3

I've created a service that its job is to clear the notifications when the app is closed by the user. Everything works perfectly well but sometimes when the application is in the background for more than 1 minute the service is killed (which means that the notifications are not cancelled). Why is this happening? I thought that the only way that you can stop a service is by using either stopSelf() or stopService().

public class OnClearFromRecentService extends Service {
    private static final String TAG = "onClearFromRecentServic";
    private NotificationManagerCompat mNotificationManagerCompat;

    @Override
    public void onCreate() {
        super.onCreate();
        mNotificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());
    }

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "Service Started");
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Service Destroyed");
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        //Put code here which will be executed when app is closed from user.
        Log.d(TAG, "onTaskRemoved was executed ");
        if (mNotificationManagerCompat != null) {
            mNotificationManagerCompat.cancelAll();
        } else {
            Log.d(TAG, "onTaskRemoved: mNotifManager is null!");
        }

        stopSelf();
    }
}

I start the service from the splash screen Activity like this: startService(new Intent(this, OnClearFromRecentService.class));

Also here are some Log messages: enter image description here

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Kwnstantinos Nikoloutsos
  • 1,832
  • 4
  • 18
  • 34
  • Which version of Android? 7.x+? – emandt Jul 21 '18 at 17:20
  • @emandt I am running this app on API 27 – Kwnstantinos Nikoloutsos Jul 21 '18 at 17:21
  • 1
    There are already many threads about this "issue". Starting from SDK 26 you have to create a Foreground Service or the System will kill it after small amount of time. Link: https://developer.android.com/about/versions/oreo/android-8.0-changes – emandt Jul 21 '18 at 17:23
  • @emandt You are right. Thank you – Kwnstantinos Nikoloutsos Jul 21 '18 at 17:28
  • @emandt Even I am planning to use a service to load Files list in a users device. For me, the service will start at the Splash Screen and will continue to work till it finishes its work. Now my question is suppose if the user minimizes my app while the service is doing its work will on Android 8.0 then will the OS kill the service after 1 minute? If yes then will using a Thread help me overcome this? Please Help. – Rahulrr2602 May 29 '19 at 12:20
  • @Rahulrr2602 YES, the Service survives Activity kill. Foreground Services are latest things killed by Android even if the system is out of memory. In my experience I never seen Android kill one of my services. I should manage the possibility of it but the probability is very-very low. – emandt May 29 '19 at 12:58
  • @emandt Thanks for the reply. I have one more doubt. Even if the service is background service will it last for more than a minute if none of my apps components is visible to the user? Which is better to load the files a Thread or a service? – Rahulrr2602 May 29 '19 at 13:26
  • @Rahulrr2602 A Background Service will continue to run while you remain/loop INSIDE its main method (for an IntentService it's the "onHandleIntent" method) or until you call "selfStop()" from inside the Service. Pay attention that a normal Service runs in the same Thread of UserInterface, so I suggest to use "IntentService". I discourage to use Threads if no-any Activity is visible.... – emandt May 29 '19 at 14:39
  • @emandt In my case, I have to do three background operations. Whereas only one Intent Service can run in the background at a time and other Intent Services are qued till the first one gets over. And in my case, the activity should be visible except in some cases where the user decided to use some other app till the loading is over or suppose the user gets a call and he attends the call then my service in Android O will be destroyed as it is running in the background for more than 1 minute without a foreground element. – Rahulrr2602 May 29 '19 at 14:52

2 Answers2

1

Try returning START_STICKY form onStartCommand.
Then system will try to recreate.
check this official doc.

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "Service Started");
        return START_NOT_STICKY;
    }

Also you can try returing START_REDELIVER_INTENT,if you also want Intent to be re-delivered.

START_REDELIVER_INTENT

Constant to return from onStartCommand(Intent, int, int): if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then it will be scheduled for a restart and the last delivered Intent re-delivered to it again via onStartCommand(Intent, int, int).

From docs.

Saheb
  • 21
  • 4
1

I found a solution with the help of @emandt.

I just added these lines of code in onStartCommand() :

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "Service Started");
    Notification notification = new NotificationCompat.Builder(this, CHANNELID)
            .setContentTitle("title")
            .setContentText("text")
            .setSmallIcon(R.drawable.baseline_pause_white_24)
            .build();
    startForeground(2001,notification);
    return START_NOT_STICKY;
}

According to docs the startForeground method :

If your service is started then also make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state...By default started services are background, meaning that their process won't be given foreground CPU scheduling (unless something else in that process is foreground)

Also,

If your app targets API level 26 or higher, the system imposes restrictions on using or creating background services unless the app itself is in the foreground. If an app needs to create a foreground service, the app should call startForegroundService(). That method creates a background service, but the method signals to the system that the service will promote itself to the foreground. Once the service has been created, the service must call its startForeground() method within five seconds.

Kwnstantinos Nikoloutsos
  • 1,832
  • 4
  • 18
  • 34