How to automatically restart a service even if user force close it?

I want a service to run all the time in my application. So I want to restart it even if it is force closed by user. There is definitely a way to do it as apps like facebook are doing it. It's not done using push notification, facebook restarts its service even if internet is off.


Solution 1:

First of all, it is really very bad pattern to run service forcefully against the user's willingness.

Anyways, you can restart it by using a BroadcastReceiver which handles the broadcast sent from onDestroy() of your service.

StickyService.java

public class StickyService extends Service
{
    private static final String TAG = "StickyService";


    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        sendBroadcast(new Intent("YouWillNeverKillMe"));
    }

}

RestartServiceReceiver.java

public class RestartServiceReceiver extends BroadcastReceiver
{

    private static final String TAG = "RestartServiceReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e(TAG, "onReceive");
    context.startService(new Intent(context.getApplicationContext(), StickyService.class));

    }

}

Declare the components in manifest file:

    <service android:name=".StickyService" >
    </service>

    <receiver android:name=".RestartServiceReceiver" >
        <intent-filter>
            <action android:name="YouWillNeverKillMe" >
            </action>
        </intent-filter>
    </receiver>

Start the StickyService in a Component (i.e. Application, Activity, Fragment):

startService(new Intent(this, StickyService.class));

OR

sendBroadcast(new Intent("YouWillNeverKillMe"));

Solution 2:

You have to create a sticky service with overriding onTaskRemoved method, where you can set an alarm service to trigger your code again.

public class BackgroundService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        //create an intent that you want to start again.
        Intent intent = new Intent(getApplicationContext(), BackgroundService.class);
        PendingIntent pendingIntent = PendingIntent.getService(this, 1, intent, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + 5000, pendingIntent);
        super.onTaskRemoved(rootIntent);
    }
}

Also in some devices like Xiaomi, Huwaei the app gets force closed once it's removed from recent apps. This is because the manufacturers have task manager features which improve ram/battery performance.

You can check this link for more information: https://stackoverflow.com/a/41360159/2798289

Solution 3:

As per the Android document

Starting from Android 3.1, the system's package manager keeps track of applications 
that are in a stopped state and provides a means of controlling their launch from 
background processes and other applications.

Note that an application's stopped state is not the same as an Activity's stopped
state. The system manages those two stopped states separately.
FLAG_INCLUDE_STOPPED_PACKAGES — Include intent filters of stopped applications in the
list of potential targets to resolve against.

FLAG_EXCLUDE_STOPPED_PACKAGES — Exclude intent filters of stopped applications from the
list of potential targets.

When neither or both of these flags is defined in an intent, the default behavior is to
include filters of stopped applications in the list of potential targets. 

Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents.
It does this to prevent broadcasts from background services from inadvertently or
unnecessarily launching components of stopped applications. A background service 
or application can override this behavior by adding the FLAG_INCLUDE_STOPPED_PACKAGES
flag to broadcast intents that should be allowed to activate stopped applications.

On Force stop of app, Android just kill the process ID. No warnings, callbacks are given to service/activities. As per the Android document, When the app is killed there are chances that it calls onPause().

When I tried in my app, even onPause() was not called. I think the only way is use to FLAG_INCLUDE_STOPPED_PACKAGES intent flag and send it from another app

Solution 4:

If I understand correctly, then actually this is not possible, Android feature to force close application was designed to allow user to get rid of unwanted applications, so it disallows any activities from it until user again starts any of its Activity.

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