4

I am trying to run my service continuously in background. I understand it will drain a lot of battery but still it is a use case for me.

Case 1: Starting BackgroundService using startService(intent) method. Case 2: Starting a BoundService using bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);

In both the case, my service onStartCommand code is like below,

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            while(count < 10000){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count++;

            }

        }
    }).start();
    // TODO: flag not start itself when stopped
    // TODO: use START_STICKY to keep running
    return START_STICKY;
}

Scenario when my service does not die means it will keep running:

case 1: If I press HOME button. case 2: If I press back and come out of the application.

Scenario when my service will definitely be killed:

case 1: If I remove my application from task stack of the phone. case 2: I go to settings and stop the service.

I want my service to get started once it will be killed in either of the scenarios mentioned above.

I have referred many questions from stackoverflow to do like this,

  @Override
    public void onDestroy() {
        super.onDestroy();

        startService(new Intent(this, BackgroundService.class));
    }

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

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

    }

But definitely onDestroy() is not that kind of method which will be called every time. I have checked it in my logs.

Custadian
  • 845
  • 1
  • 11
  • 37
  • Please accept your own answer. This will remove the question from the list of unanswered questions. Thanks! – David Wasser Aug 17 '17 at 14:41
  • Were you able to figure this out? Why did you accept my answer instead of your own? I'm curious. – David Wasser Aug 30 '17 at 07:19
  • 1
    @DavidWasser, Your answer helped me to think from different approach. I kept my app in "Auto Start" for Chinese manufacturers like for Xiaomi, Huawei etc. So you deserved it Sir. – Custadian Sep 01 '17 at 10:37

2 Answers2

4

If the user performs a "force stop" on your app, your Service will be killed and there is nothing you can do to stop it. There is also nothing you can do to restart your Service automatically because the user has told Android that it doesn't want your app to run anymore. The user must manually restart your app.

If you remove your app from the "list of recent tasks", Android will kill the OS process hosting your app. Assuming your Service is also running in this OS Process, it will also be killed. In this case, assuming that you have returned START_STICKY from onStartCommand(), Android will restart your Service in a new OS process.

There are certain devices (Xiaomi, Huawei, some other Chinese phones, some LG and Lenovo devices) where your app must be manually added to a list of "protected apps" or "apps that are allowed to run in the background" in order for Android to restart your Service automatically. On these devices, Android will not automatically restart your Service even if you have returned START_STICKY from onStartCommand().

See also Situations when a Service's onDestroy() method doesn't get called?

David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • I agree with the explanation. But in Playstore, several AppLocking apps are available which locks the apps by tracking the top app of the Android applications stack. They are running a background service and check the top most application of stack. How these applications are handling this issue. In Xiaomi, Samsung devices; I checked for Applock applications' service gets killed but after few seconds it starts again. – Custadian Aug 11 '17 at 05:04
  • Is it possible that those apps are installed as "device managers"? – David Wasser Aug 12 '17 at 09:21
  • These are the apps without Device admin permissions :| – Custadian Aug 14 '17 at 06:53
  • Sorry, I don't know. – David Wasser Aug 14 '17 at 07:03
  • Please check my answer. I tried using alarm manager which comes after a specific time period and updates the service. In case, if the service is not there then service will be started. Thanks for helping and being with me for this problem @David Wasser – Custadian Aug 14 '17 at 10:14
  • If the user "force stops" your app, I don't think that the `AlarmManager` will start your `Service` again. Also, on a phone with "protected apps", I don't think that the `AlarmManager` will start a `Service` unless it is in the list of protected apps. I'd be interested to know if this works for you, so please let me know your findings. Good luck. – David Wasser Aug 14 '17 at 12:38
0

I used repeated Alarm with RTC using the following snippet,

 Context ctx = getApplicationContext();
        Calendar cal = Calendar.getInstance();
        AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
        long interval = 100 * 5;
        Intent serviceIntent = new Intent(ctx, BackgroundService.class);
        PendingIntent servicePendingIntent =
                PendingIntent.getService(ctx,
                        BackgroundService.SERVICE_ID,
                        serviceIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT); 
        am.setRepeating(
                AlarmManager.RTC,
                cal.getTimeInMillis(),
                interval,
                servicePendingIntent
        );

With PendingIntent.FLAG_UPDATE_CURRENT, it is updating the current service itself there are other flag too which will cancel the existing service and start a fresh one.

BackgroundService.SERVICE_ID, created a static in service.

This Android Developer official doc helped me,

Alarms (based on the AlarmManager class) give you a way to perform time-based operations outside the lifetime of your application.

https://developer.android.com/training/scheduling/alarms.html#set

Custadian
  • 845
  • 1
  • 11
  • 37