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

后端 未结 10 764
感情败类
感情败类 2020-11-27 11:19

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

相关标签:
10条回答
  • 2020-11-27 11:37

    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

    0 讨论(0)
  • 2020-11-27 11:38

    There is a very hacky solution to keep service running even you force stop it. I do not recommend that because it is against user willingness. You can define a broadcast receiver to receive intent with action X. onStartCommand handler of your service, broadcast X (if the service is not started yet). on broadcast receiver upon receipt of X, first start the service, then, sleep for some minutes, and finally re-broadcast X.

    0 讨论(0)
  • 2020-11-27 11:42

    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"));
    
    0 讨论(0)
  • 2020-11-27 11:45

    I think the only foolproof solution here is to have 2 services in separate processes (android:process="somecustomprocessname" in manifest, in the service entry) that both listen to broadcasts and restart each other, because currently the UI doesn't let users kill multiple processes in one action. You can then set up a pinger thread in each service that checks if the other service is running every 100 milliseconds or so, and if not, attempts to restart it. But this is starting to look more and more like malware...

    0 讨论(0)
  • 2020-11-27 11:46

    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?

    0 讨论(0)
  • 2020-11-27 11:52

    The only real solution for keeping services alive ist to call Service.startForeground(...) with a provided Notification. This will be the only valid solution, every other one will be very dependent on how Google will change the behaviour of it's system. With every API update, Google could prevent every other hack.

    This also keeps the user aware, that your app is performing some background task which will keep the app alive and the user has to stop this. If you provide the user the ability to stop it is part of your application, though.

    See the Documentation:

    void startForeground (int id, Notification notification)
    

    Make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state. By default services are background, meaning that if the system needs to kill them to reclaim more memory (such as to display a large page in a web browser), they can be killed without too much harm. You can set this flag if killing your service would be disruptive to the user, such as if your service is performing background music playback, so the user would notice if their music stopped playing.

    0 讨论(0)
提交回复
热议问题