Cormoran Smith Cormoran Smith - 1 month ago 21
Android Question

Foreground Service is getting killed immediately in Android 4.1 ~ 5.1.1 when app is killed

I have a service which is downloading a file in foreground

@Override
public int onStartCommand(Intent intent, int flags, int sid){
this.sid = sid;
PendingIntent mainIntent = PendingIntent.getActivity(this, 0, MyApplication.mainIntent, 0);
Notification notification = new NotificationCompat.Builder(VuclipPrime.getInstance())
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Downloading Video")
.setContentText("Initiating...")
.setContentIntent(mainIntent)
.setAutoCancel(false)
.setOngoing(true)
.build();
startForeground(mNotificationId, notification);
if (VideoDownloadManager.currentVideoDownloadTask != null) {
VideoDownloadManager.currentVideoDownloadTask.start();
} else {
stopSelf();
}
return START_NOT_STICKY;
}


When I swipe to kill the app, the service is being stopped as well.
I tried all the existing solutions on StackOverflow, but none are working.
I tried the YouTube app and it does not kill its service. How do I achieve that ? Thanks.

Answer

The solution is to launch a dummy activity in the onTaskRemoved() method of the service which prevents the service from getting killed.

Check the following code :-

package com.your.application.services;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;


public class DownloadService extends Service {
    int mNotificationId = 001;
    Notification notification;
    private int sid;

    public DownloadService() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int sid) {
        this.sid = sid;
        PendingIntent mainIntent = PendingIntent.getActivity(this, 0, YourApplication.getInstance().downloadService.mainIntent, 0);
        notification = new NotificationCompat.Builder(YourApplication.getInstance())
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("Starting Service")
                .setContentText("Initiating...")
                .setContentIntent(mainIntent)
                .setAutoCancel(true)
                .setOngoing(true)
                .build();
        startForeground(mNotificationId, notification);
        if (YourApplication.getInstance().downloadService.videoDownloader != null) {
            YourApplication.getInstance().downloadService.startDonwloadThread(YourApplication.getInstance().downloadService.videoDownloader);
        } else {
            stopSelf();
        }
        return START_NOT_STICKY;
    }

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

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

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 && Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
            Intent intent = new Intent(this, DummyActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }
    }
}

The AndroidManifest entry for DummyActivity :-

            <activity
            android:name=".downloader.DummyActivity"
            android:allowTaskReparenting="true"
            android:alwaysRetainTaskState="false"
            android:clearTaskOnLaunch="true"
            android:enabled="true"
            android:excludeFromRecents="true"
            android:finishOnTaskLaunch="true"
            android:noHistory="true"
            android:stateNotNeeded="true"
            android:theme="@android:style/Theme.NoDisplay" />
Comments