How To Restart Service After The App Is Killed From Recent Tasks
Solution 1:
Override onTaskRemoved() in your service and use alarm manager to start the service again. Below is code from our app that does the same and works fine:
@OverridepublicvoidonTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.d(TAG, "TASK REMOVED");
PendingIntentservice= PendingIntent.getService(
getApplicationContext(),
1001,
newIntent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);
AlarmManageralarmManager= (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
}
As you may want to send location periodically even in the case if the service gets killed on low memory (or for any reason), I suggest you to handle the uncaughtException to restart it after N seconds. This is how we have done in our app that works perfectly:
private Thread.UncaughtExceptionHandler defaultUEH;
private Thread.UncaughtExceptionHandleruncaughtExceptionHandler=newThread.UncaughtExceptionHandler() {
@OverridepublicvoiduncaughtException(Thread thread, Throwable ex) {
Log.d(TAG, "Uncaught exception start!");
ex.printStackTrace();
//Same as done in onTaskRemoved()PendingIntentservice= PendingIntent.getService(
getApplicationContext(),
1001,
newIntent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);
AlarmManageralarmManager= (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
System.exit(2);
}
};
Note: I THINK and I remember I verified it on Kitkat that START_STICKY does not work on Kitkat and higher API levels. Please verify this for yourself.
MORE: As you do loc sending periodically, you may have to consider the deep sleep mode. To get things work in deep sleep, use WakefulBroadcastReceiver combined with AlarmManager. Take a look at my other post How to use http in deep sleep mode.
UPDATE: This solution does not work (in fact need not to work) if user "FORCE STOP" the application from Settings. This is good in fact as restarting the service is not a good way if user himself wants to stop application. So, it is fine.
Solution 2:
replace return Service.START_NOT_STICKY;
with return START_STICKY;
Solution 3:
If you ONLY want to restart service after it kill from Recent Task, simple use
@OverridepublicintonStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
If you use START_STICKY
, when you kill app from recent task, your service will be killed (onTaskRemoved
fired, onDestroy
NOT fired) THEN it will auto start again (onCreate
fired, onStartComand
fired)
Solution 4:
I use android 9 and the solution works partially for me.
I had a case with foreground service (working 24/7), which I wanted to restart after the application was crashed.
When the event uncaughtExceptionHandler
was caught, the application got frozen besides public void onTaskRemoved(Intent rootIntent) {
event doesn't work anymore in latest Android versions (I suppose O+).
My application has only one activity with fragments if you need solution for more activities just use this link.
To solve that problem I've added a function which checks if the activity is working (to kill it) and some instructions to kill the process:
classMyApplication : Application() {
privatevar currentActivity: Activity? = nulloverridefunonCreate() {
super.onCreate()
StorageManager.init()
this.registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
overridefunonActivityPaused(activity: Activity) {
}
overridefunonActivityStarted(activity: Activity) {
currentActivity = activity
}
overridefunonActivityDestroyed(activity: Activity) {
}
overridefunonActivitySaveInstanceState(activity: Activity, outState: Bundle) {
}
overridefunonActivityStopped(activity: Activity) {
currentActivity = null
}
overridefunonActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
}
overridefunonActivityResumed(activity: Activity) {
}
})
Thread.setDefaultUncaughtExceptionHandler { _, e ->
// Close current activity
currentActivity?.finish()
val service : PendingIntent? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Start service in Oreo and latest
PendingIntent.getForegroundService(
applicationContext,
8888,
Intent(applicationContext, SensorService::class.java),
PendingIntent.FLAG_ONE_SHOT)
} else {
// Start service in Nougat and older
PendingIntent.getService(
applicationContext,
8888,
Intent(applicationContext, MyService::class.java),
PendingIntent.FLAG_ONE_SHOT)
}
// The great solution introduced by @cgrval alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service)
// Kill the current application process to avoid freezing activity
android.os.Process.killProcess(android.os.Process.myPid())
exitProcess(10)
}
}
}
Add to manifest:
<application
android:name="com.example.MyApplication"
...
Post a Comment for "How To Restart Service After The App Is Killed From Recent Tasks"