How to Automatically Restart a Service Even If User Force Close It

Restart the service even if app is force-stopped and Keep running service in background even after closing the app How?

I am not sure which 'Task Manager' you are referring to as different ones would act differently, so I am basing my answer on the action when the user goes to Settings-->manage Applications and--> force stops the app the way android has given him.


Assuming that your service is running as part of the process and if the user force-stops your process, you are prevented from ever running the service again until the user manually launches you.This is especially valid from 3.0 and above version ( check for yours). It also seems logical when you think that there is an app which keeps a service started all the time and is annoying the user in some way. So when the user orders a hit ( :) force-stops) on the app, it should not restart the service to continue bugging the user.

For instance, Imagine what would happen if you could create apps which just ate at your processor time by holding a wake lock, and you couldn't kill them. This would be horrible and a huge security disaster.

So, you will not be able to restart your service by any means until the user launches one of your activities.

Also you cannot disable the force-stop button AFAIK. You should take the viewpoint that nothing on the device is yours to control besides your app and (to a limited extent) the resources to which you're granted access.

Finnally, even the gtalk app will bend to your will if you desire to force stop. It will start only when you use Gtalk or other apps which use the gtalk service such as PUSH Gmail ( for phones where gtalk isnt a part of firmware). Also take a look at Android C2DM here:

https://stackoverflow.com/a/11238779/1218762

Android: How to auto-restart an application after it has been force closed?

To accomplish this you have to do two things:

  1. Avoid the "Force close" - standard way of application crash.
  2. Setup a restart mechanism when the crash happens anyway.

See below how to do these:

  1. Call Thread.setDefaultUncaughtExceptionHandler() in order to catch all uncaught exception, in which case uncaughtException() method will be called. "Force close" will not appear and the application will be unresponsive, which is not a quite good thing.
    In order to restart your application when it crashed you should do the following :

  2. In the onCreate method, in your main activity initialize a PendingIntent member:

    Intent intent = PendingIntent.getActivity(
    YourApplication.getInstance().getBaseContext(),
    0,
    new Intent(getIntent()),
    getIntent().getFlags());

Then put the following in your uncaughtException() method:

AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent);
System.exit(2);

You also must call System.exit(), otherwise will not work.
In this way your application will restart after 2 seconds.

Eventually you can set some flag in your intent that the application crashed and in your onCreate() method you can show a dialog "I'm sorry, the application crashed, hope never again :)".

How to restart service after the app is killed from recent tasks

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:

@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);

Log.d(TAG, "TASK REMOVED");

PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);

AlarmManager alarmManager = (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.UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {

@Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.d(TAG, "Uncaught exception start!");
ex.printStackTrace();

//Same as done in onTaskRemoved()
PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);

AlarmManager alarmManager = (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.

How can a windows service programmatically restart itself?

Set the service to restart after failure (double click the service in the control panel and have a look around on those tabs - I forget the name of it). Then, anytime you want the service to restart, just call Environment.Exit(1) (or any non-zero return) and the OS will restart it for you.



Related Topics



Leave a reply



Submit