我的应用程序使用后台服务来收听GPS位置变化。它适用于Android 7.1.1(即使我的活动已关闭或屏幕关闭)。当我在android 9(使用AVD)上尝试它时,它仅在活动位于前台时才起作用,否则不起作用。应用程序关闭时,服务似乎已停止。 minSdkVersion设置为23.为什么app在不同的API上有不同的行为? Android不保证较新操作系统版本的应用程序兼容性?
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**code to request permission*/
startService(new Intent(this, EventControllerService.class));
}
}
public final class EventControllerService extends Service {
private final static int MIN_TIME_FOR_GPS_UPDATES = 1;
private final static float MIN_METER_FOR_GPS_UPDATES = 10.0f;
private static NotificationManager mNotificationManager;
private final BroadcastReceiver receiverDNDChange = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//work on receive
}
};
private final EventControllerService self = this;
private final LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Toast.makeText(self, "DENTRO", Toast.LENGTH_LONG).show();
try {
//work to do on position change
} catch (SecurityException ignored) {
stopSelf();
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
@Override
public void onCreate() {
super.onCreate();
try {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
IntentFilter filter = new IntentFilter();
filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
registerReceiver(receiverDNDChange, filter);
LocationManager mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_FOR_GPS_UPDATES, MIN_METER_FOR_GPS_UPDATES, locationListener);
} catch (SecurityException ignored) {
stopSelf();
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="marcomantovani.pcd.silentmap">
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<service android:name=".EventControllerService"/>
<receiver android:name="marcomantovani.pcd.silentmap.AutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
如何更改代码以避免此问题?
我明白你读到这个:https://developer.android.com/about/versions/oreo/background
有很多与后台服务有关的变化,特别是Android 9中的GPS。请注意这一点(因此针对API23不是解决方案):
默认情况下,这些更改仅会影响针对Android 8.0(API级别26)或更高级别的应用。但是,用户可以从“设置”屏幕为任何应用启用这些限制,即使应用的目标是低于26的API级别。您可能需要更新应用以符合新的限制。
您现在可以做些什么,以及我们如何在我们的应用程序中使用它。将您的服务迁移到与Android 9兼容。我建议使用:
startForegroundService()
使您的服务在前台运行。这是一个小小的改变。只需更改一个标志就可以通过这种方式启动服务。
显示您的应用正在运行的通知(这将使您的应用即使在用户离开应用时仍然有效 - Android操作系统将限制您的服务)
定位API23也是一个坏主意,因为:
从2019年8月1日开始,Google Play要求新应用至少定位到Android 9.0(API级别28),并且该应用从2019年11月1日起更新目标Android 9.0。在这些日期之前,新应用和应用更新必须至少定位到Android 8.0(API级别26)。
TL; DR 1.将服务迁移到前台2.创建简单通知,告诉用户应用程序正在运行3.使用startForeground()启动服务
Android一直在稳步地限制在后台访问应用程序。 Android 8限制了位置服务。
参考:https://developer.android.com/about/versions/oreo/android-8.0-changes#abll