Android - Foreground is not working in Oreo. OS killed service after some interval

  • Thread starter Android Central Question
  • Start date
A

Android Central Question

I have an application which is using location service in background at every 5 minute of interval. We are using Fusedlocationproviderclient in foreground service. It is working fine when app is in open.

When I put application in background or swipe to kill from background , Foreground service is automatically killed by OS on android 8.0 and higher version.

We are facing problem in samsung note 8 , one plus 5t and red mi devices.

Please let me know How can I implement service which is compatible for all devices.

This is my location service class

public class TrackingForgroundService extends Service {

private final long UPDATE_INTERVAL = (long) 2000;
private static final long FASTEST_INTERVAL = 2000;

public BookingTrackingForgroundService() {

}

@nUllaBle
@override
public IBinder onBind(Intent intent) {
return null;
}

@override
public void onCreate() {
super.onCreate();
}

@override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
String action = intent.getAction();

switch (action) {
case ACTION_START_FOREGROUND_SERVICE:
startForegroundService();

break;
case ACTION_STOP_FOREGROUND_SERVICE:
stopForegroundService();

break;
}
}
return START_STICKY;
}

private class TimerTaskToGetLocation extends TimerTask {
@override
public void run() {

mHandler.post(new Runnable() {
@override
public void run() {
// Call webservice evry 5 minute
}
});

}
}

private void startForegroundService() {

Log.d(TAG_FOREGROUND_SERVICE, "Start foreground service.");

context = this;
startLocationUpdates();
notify_interval1 = Prefs.with(this).readLong("notify_interval1", 5000);
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTaskToGetLocation(), 15000, notify_interval1);
mTimer.scheduleAtFixedRate(new TimerTaskToSendCsvFile(), 60000, 1200000);
prefsPrivate = getSharedPreferences(Constants.prefsKeys.PREFS_PRIVATE, Context.MODE_PRIVATE);
internet = new NetConnectionService(context);

Intent notificationIntent = new Intent(this, ActTherapistDashboard.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(getString(R.string.app_name))
.setContentText("Geolocation is running")
.setTicker("Geolocation").setSmallIcon(R.drawable.app_small_icon_white)
.setContentIntent(pendingIntent);
Notification notification = builder.build();
if (Build.VERSION.SDK_INT >= 26) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(CHANNEL_DESCRIPTION);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
startForeground(SERVICE_ID, notification);
}

private void stopForegroundService() {
stopLocationUpdates();
Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");
if (mTimer != null) {
mTimer.cancel();
} else {
mTimer = null;
}
// Stop foreground service and remove the notification.
stopForeground(true);

// Stop the foreground service.
stopSelf();
}

public static boolean isServiceRunningInForeground(Context context, Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
if (service.foreground) {
return true;
}

}
}
return false;
}

private void startLocationUpdates() {
// create location request object
mLocationRequest = LocationRequest.create();

mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);

// initialize location setting request builder object
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
LocationSettingsRequest locationSettingsRequest = builder.build();

// initialize location service object
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = settingsClient.checkLocationSettings(locationSettingsRequest);
task.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
registerLocationListner();
}
});

}

private void registerLocationListner() {
locationCallback = new LocationCallback() {
@override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
onLocationChanged(locationResult.getLastLocation());
}
};

//location permission
LocationServices.getFusedLocationProviderClient(this).requestLocationUpdates(mLocationRequest, locationCallback, null);

}

private void onLocationChanged(Location location) {

if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
latitudeTemp = latitude;
longitudeTemp = longitude;
}

}

}
 

josh_l

New member
Mar 14, 2019
1
0
0
Visit site
You have to change some settings in the devices in order to protect the foreground service from getting killed. For One Plus you have Battery Optimizer which you should change to "don't optimize" for your app. And for Redmi you have to enable autostart and change battery settings to "no restrictions.". Samsung should have something simillar to these settings.
 

Forum statistics

Threads
943,150
Messages
6,917,531
Members
3,158,850
Latest member
kerokekerol