2

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.

3 Answers3

0

You are startinf Service with NOT_STICKY param. You should return START_STICKY inside onStartCommand()

@Override
    public int onStartCommand(Intent intent, int flags, int sid){
        this.sid = sid;
        PendingIntent mainIntent = PendingIntent.getActivity(this, 0, VuclipPrime.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_STICKY;
    }

From documentation:

https://developer.android.com/reference/android/app/Service.html#START_STICKY

  • START_STICKY: the system will try to start the service again when it's killed.
  • START_NO_STICKY: the system wont care about if the service is killed.
adalpari
  • 3,052
  • 20
  • 39
0

The solution is to launch a dummy activity in the onTaskRemoved() method of the service which prevents the service from getting killed. Also finish the DummyActivity immediately after launching.

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 DummyActivity:-

public class DummyActivity extends Activity {
    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        finish();
    }
}

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" />
0

Android discontinues process if it's not listed as protected app when process is in sleep mode. Go to Settings->Protected Apps->Select your app and enable as protected app.

Sabid Habib
  • 419
  • 1
  • 4
  • 16