My app uses a background service to listen to GPS position changes. It works on android 7.1.1 (even if my activity is closed or the screen is turn off). When I tried it on android 9 (with the AVD) it only works when the activity is in the foreground, otherwise not. It looks like the service is stopped when the app is closed. minSdkVersion is set to 23. Why app have different behavior on different API? Android does not guarantee the compatibility of apps on newer OS versions?
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>
How can I change code to avoid this problem?
I understand you read this: https://developer.android.com/about/versions/oreo/background
There are many changes related to background services and especially GPS in Android 9. Note this also (so targeting API23 is not a solution):
What you can do right now and how we make it work in our apps. Migrate your service to compatible with Android 9. I suggest using:
startForegroundService()Make your service to run on foreground. It's a small change. Just change one flag nad start your service this way.
Show notification that your app is working (this will keep your app working even when user is leaving the app otherwise - Android OS will limit your service)
Targeting API23 is a bad idea also because of this:
TL;DR 1. Migrate service to foreground 2. Create simple notification that will tell your user that app is working 3. Start service with startForeground()