18

I already using startforeground() at my Service, but Android keeps killing my Service when I clear all the recent apps.

Here's the code of my Service:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    Notification notification = new NotificationCompat.Builder(this)
            .setContentTitle("Text")
            .setTicker("Text")
            .setContentText("Text")
            .setSmallIcon(R.drawable.icon)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon))
            .build();

    startForeground(100, notification);

    return START_STICKY;
}

Is there something wrong I did with this code?

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
zamroni hamim
  • 545
  • 1
  • 6
  • 21

5 Answers5

23

A long running service needs the following to make it less likely to be terminated:

  1. Return START_STICKY from onStartCommand(). With this, system will re-start the service even if it has to be stopped for resources limitations.

  2. When the service is not bound to any UI component (e.g an Activity), The service must go in foreground mode by showing a foreground notification. Foreground services are less likely to be terminated by system.

  3. Set the attribute "stopWithTask"=false in corresponding <service> tag of manifest file.

Also, note that devices from some manufacturers will terminate services even with above properties due to customization:

  1. Custom task managers.
  2. Battery saving features that can prohibit non-system services.

Some application services do need to stay in background and have to be aggressively kept alive. Though this method is not recommended, but following steps can be done:

  1. Add triggers for service start : Such as Boot Complete, and Network Connected broadcasts.

  2. If service receives intents/broadcasts FLAG_RECEIVER_FOREGROUND in the intent.

  3. An extreme resort is to manually schedule a pending intent for service restart, with AlarmManager, when onTaskRemoved() is called.

Also, see:

  1. START_STICKY does not work on Android KitKat
Community
  • 1
  • 1
S.D.
  • 29,290
  • 3
  • 79
  • 130
  • I used two devices which one of it is customized I think, and it turns out that the the other one that I think isn't customized didn't kill my service. I marked this "accepted" as this is more complete that Jack's answer. Thank you. – zamroni hamim Mar 31 '16 at 06:06
  • I got it worked after seeing link from your last update using "onTaskRemoved()". Precisely, from this link inside that answer: http://stackoverflow.com/a/20681898/624109 . Can you put answer from above link to your update, so we all can immediately see it? Thank you. – zamroni hamim Apr 01 '16 at 04:52
6

Android system can stop your service anytime when they want to stop to maintain the device performance or power consumption. There are many situation where android system can stop your service like low battery, app is not in active state for a long time, device is in sleeping mode, power saving mode etc.

I developed a trick or hack(you can say that) by using that no one can stop your service (Android System, Third Party apps, User).

Note: By using this your service will never stop and may drain your battery also.

Follow the steps below :-

1) Return START_STICKY in onStartCommand.

2) Then modify the onDestroy() and onTaskRemoved() method in your service as below:

@Override
public void onDestroy() {
    super.onDestroy();
    Toast.makeText(getApplicationContext(), "Service Task destroyed", Toast.LENGTH_LONG).show();


    Intent myIntent = new Intent(getApplicationContext(), YourService.class);

    PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, myIntent, 0);

    AlarmManager alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);

    Calendar calendar = Calendar.getInstance();

    calendar.setTimeInMillis(System.currentTimeMillis());

    calendar.add(Calendar.SECOND, 10);

    alarmManager1.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

  Toast.makeText(getApplicationContext(), "Start Alarm", Toast.LENGTH_SHORT).show();

}




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


        Intent myIntent = new Intent(getApplicationContext(), YourService.class);

        PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, myIntent, 0);

        AlarmManager alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);

        Calendar calendar = Calendar.getInstance();

        calendar.setTimeInMillis(System.currentTimeMillis());

        calendar.add(Calendar.SECOND, 10);

        alarmManager1.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

        Toast.makeText(getApplicationContext(), "Start Alarm", Toast.LENGTH_SHORT).show();


    }




@Override

    public int onStartCommand(Intent intent, int flags, int startId) {
     Toast.makeText(getApplicationContext(), "Service Starts", Toast.LENGTH_SHORT).show();
        return START_STICKY;
    }

Here i am setting an alarm every time whenever the service is stop (by android system or by user mannually) and using PendindIntent restart the service within 10 seconds every time.

Ameer Faisal
  • 355
  • 1
  • 9
  • 1
    Not working in Oppo devices because these override functions are not triggered in oppo devices – Ahmad Jan 15 '20 at 07:11
4

you can use START_REDELIVER_INTENT instead of START_STICKY

The simplest explanation of these could be,

START_STICKY- tells the system to create a fresh copy of the service, when sufficient memory is available, after it recovers from low memory. Here you will lose the results that might have computed before.

START_NOT_STICKY- tells the system not to bother to restart the service, even when it has sufficient memory.

START_REDELIVER_INTENT- tells the system to restart the service after the crash and also redeliver the intents that were present at the time of crash.

I hope this will help you. thanks

rockstar
  • 587
  • 4
  • 22
1

Huawei, Vivo, Oppo and Xiaomi restrict background services. Please also take a look at here

edit: In these brands, because of lots of customization, all services are restricted by default. either you must disable background restrictions for your app via settings or you can prompt to the user by firing an intent. Unfortunately, the path to the Background Restriction settings is different in each Operating System.

private static final Intent[] POWERMANAGER_INTENTS = {
new Intent().setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")),
new Intent().setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity")),
new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity")),
new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")),
new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")),
new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity")),
new Intent().setComponent(new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity")),
new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")),
new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager")),
new Intent().setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")),
new Intent().setComponent(new ComponentName("com.samsung.android.lool", "com.samsung.android.sm.ui.battery.BatteryActivity")),
new Intent().setComponent(new ComponentName("com.htc.pitroad", "com.htc.pitroad.landingpage.activity.LandingPageActivity")),
new Intent().setComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.MainActivity"))
};


for (Intent intent : POWERMANAGER_INTENTS)
    if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
            // show dialog to ask user action
        break;
}
Behrad Ranjbar
  • 261
  • 2
  • 13
  • How do you know that the user's issue is related to the phone brands? I suggest you reword the answer to indicate a possibility instead of giving a statement. – Simas Joneliunas Dec 31 '19 at 05:49
0

Please Read this Click Here

Some of device which have custom android , not real test of android will kill your service when you clear recent application

J.D.
  • 1,401
  • 1
  • 12
  • 21
  • That's right, I used two devices, and the other device that I use to run app didn't kill my service. thank you for your answer. – zamroni hamim Mar 31 '16 at 06:08
  • 1
    @zamronihamim yes that's true that some of company make change in core structure of android and this issue is happen. so if you want to over come this issue send broad cast in onDestroy method of service and register broadcast receiver in your app when you receive broadcast recreate your service pragmatically. If you are satisfied with and please accept it. – J.D. Mar 31 '16 at 06:17