In Android O (8.0.0+) (API 26+), How to get a location services update when the app is in the background or kill. In "Strava" Android App (Available on Play Store), location services run properly when the app is in the background or kill. I need to build same functionality in my app. Whenever I start service using
startService(new Intent(this, GpsServices.class));
Then the onDestroy method is called after 10 sec when an app is an idle mode (the app is in the background or kill). Below is my code.
public class GpsServices extends Service implements LocationListener, Listener {
@Override
public void onCreate() {
mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mLocationManager != null) {
mLocationManager.addGpsStatusListener(this);
}
if (mLocationManager != null) {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
500,
0,
this);
}
}
public void onLocationChanged(Location location) {
System.out.println("location = [" + location + "]");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
/* Remove the locationlistener updates when Services is stopped */
@Override
public void onDestroy() {
try {
mLocationManager.removeUpdates(this);
mLocationManager.removeGpsStatusListener(this);
stopForeground(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Any help would be appreciated.
You can try one of below two options or a combination of both, which have solved my problems when I have faced them.
For location update to continue running in the background, you must use LocationServices
API with FusedLocationProviderClient
as described here and here in docs or here in CODEPATH.
If you would have read the Android Oreo 8.0 Documentation properly somewhere in here, you would have landed on this solution.
Step 1: Make sure you start a service as a foreground service as given in below code
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
mainActivity.startService(new Intent(getContext(), GpsServices.class));
mainActivity.startService(new Intent(getContext(), BluetoothService.class));
mainActivity.startService(new Intent(getContext(), BackgroundApiService.class));
}
else {
mainActivity.startForegroundService(new Intent(getContext(), GpsServices.class));
mainActivity.startForegroundService(new Intent(getContext(), BluetoothService.class));
mainActivity.startForegroundService(new Intent(getContext(), BackgroundApiService.class));
}
Step 2: Use notification to show that your service is running. Add below line of code in
onCreate
method of service.
@Override
public void onCreate() {
...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(NOTIFICATION_ID, notification);
}
...
}
Step 3: Remove the
notification
when the service is stopped or destroyed.
@Override
public void onDestroy() {
...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
stopForeground(true); //true will remove notification
}
...
}
One problem with Option 2 is that it will keep showing the notification
until your GpsService
is running on all devices running on Android Oreo 8.0.
I'm sure that both these options will work even when the app is in the background or in kill state.
I hope this solution might solve your problem.