Continually Running Background Service

24,200

Solution 1

In oreo release Android defined limits to background services.

To improve the user experience, Android 8.0 (API level 26) imposes limitations on what apps can do while running in the background.

Still if app need to run its service always, then we can create foreground service.

Background Service Limitations: While an app is idle, there are limits to its use of background services. This does not apply to foreground services, which are more noticeable to the user.

So create a foreground service. In which you will put a notification for user while your service is running. See this answer (There are many others)

Now what if you don't want a notification for your service. A solution is for that.

You can create some periodic task that will start your service, service will do its work and stops itself. By this your app will not be considered battery draining.

You can create periodic task with Alarm Manager, Job Scheduler, Evernote-Jobs or Work Manager.

  • Instead of telling pros & cons of each one. I just tell you best. Work manager is best solution for periodic tasks. Which was introduced with Android Architecture Component.
  • Unlike Job-Scheduler(only >21 API) it will work for all versions.
  • Also it starts work after a Doze-Standby mode.
  • Make a Android Boot Receiver for scheduling service after device boot.

I created forever running service with Work-Manager, that is working perfectly.

Solution 2

Since Android 8.0 many background service limitations have been introduced.

Two solutions:

  1. if you need to get total control of task and execution timing, you have to choose Foreground Service. Pros: your app will be considered to be alive, then is more unlikely that the os will kill it to free resources. Cons: your user will always see the Foreground Notification.

  2. if you need to schedule periodically task, then Work Manager (introduced in Google I/O 18) is the best solution. This component choose the best possible scheduler (Jobscheduler, JobDispatcher, AlarmManager..). Keep in mind that work manager APIs are useful only for the tasks that require guaranteed execution and they are deferrable. Ref: Android Dev Documentation

Solution 3

The only solution I would suggest is using Firebase Cloud Messages. Or foreground services.

Solution 4

Using BroadcastReciever we can run backgrouund service continuously, but if it will get killed , destroy automatically re-instance the old service instance When service stops forcefully it will call onDestroy() method, in this case use one receiver and send one broadcast when ever service destroy and restart service again. in thee following method com.android.app is custom action of reciever class which extends BroadcastReciever

public void onDestroy() {
    try {
        myTimer.cancel();
        timerTask.cancel();
    } catch (Exception e) {
        e.printStackTrace();
    }
    Intent intent = new Intent("com.android.app");
    intent.putExtra("valueone", "tostoreagain");
    sendBroadcast(intent);
}

and in onReceive Method

 @Override
public void onReceive(Context context, Intent intent) {
    Log.i("Service Stoped", "call service again");
    context.startService(new Intent(context, ServiceCheckWork.class));
}

In case device is restarted then we have onBootCompleted action for receiver to catch

When you are targeting SdkVersion "O"

In MainActivity.java define getPendingIntent()

private PendingIntent getPendingIntent() {
  Intent intent = new Intent(this, YourBroadcastReceiver.class);
 intent.setAction(YourBroadcastReceiver.ACTION_PROCESS_UPDATES);
 return PendingIntent.getBroadcast(this, 0, intent, 
  PendingIntent.FLAG_UPDATE_CURRENT);
 }

here we use PendingIntent with BroadcastReceiver and This BroadcastReceiver has already been defined in AndroidManifest.xml. Now in YourBroadcastReceiver.java class which contains an onReceive() method:

 Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
   final String action = intent.getAction();
   if (ACTION_PROCESS_UPDATES.equals(action)) {
       NotificationResult result = NotificationResult.extractResult(intent);
       if (result != null) {
           List<Notification> notifications = result.getNotification();
           NotificationResultHelper notificationResultHelper = new 
   NotificationResultHelper(
                   context, notifications);
           // Save the notification data to SharedPreferences.
           notificationResultHelper.saveResults();
           // Show notification with the notification data.
           notificationResultHelper.showNotification();
           Log.i(TAG, 
NotificationResultHelper.getSavedNotificationResult(context));
       }
   }
 }
}
Share:
24,200

Related videos on Youtube

CaseyB
Author by

CaseyB

I am an Android and iOS Developer both professionally and as a hobby. I also have a good deal of experience with C++, C# with a special interest in graphics and game programming.

Updated on July 09, 2022

Comments

  • CaseyB
    CaseyB almost 2 years

    I'm targeting sdk version 27 with a minimum version of 19 and trying to get a service that runs continuously in the background. I tried different service start options but it still got killed with the app. I tried using a BroadcastReceiver to start the service when it got killed but that gave me an error saying that the app was in the background and couldn't start a service so I tried using the JobScheduler and that gave me the same error. How is this supposed to be done? For example, if I were making a pedometer app, how could I keep that running in the background?

  • CaseyB
    CaseyB almost 6 years
    This is what I tried but it fails on anything Oreo and above.
  • Admin
    Admin almost 6 years
    @CaseyB i have updated my answer hope it will help you
  • Jerin A Mathews
    Jerin A Mathews over 5 years
    The work manager is not working with Chinese roms oreo versions like oxygen os, miui etc which is used in one plus, redmi etc.
  • Khemraj Sharma
    Khemraj Sharma over 5 years
    @JerinAMathews Thanks for sharing info, I will check this, will post issue in google dev if needed.
  • Jerin A Mathews
    Jerin A Mathews over 5 years
    Let me know if somehting changes
  • Joe
    Joe over 5 years
    Google also says: By default, these restrictions only apply to apps that target Android 8.0 (API level 26) or higher. However, users can enable most of these restrictions for any app from the Settings screen, even if the app targets an API level lower than 26.
  • Houssem Chlegou
    Houssem Chlegou over 5 years
    @Khemraj could you please post an example code for this use case? i'm searching for ages for a solution like that, i tried everything, but the app keeps killing the background services. please anyone has a solution may post it.
  • varun
    varun about 5 years
    @JerinAMathews Ahhh, these rebellious companies and their super-customized Android CDD-violating OS flavours are becoming quite a pain... Google must seriously advocate manufacturers who conform to the standards!!!
  • Shivam Bhusri
    Shivam Bhusri about 5 years
    its not working in pie.It says: Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.bhusridevelopers.myapplication/.PermanentService }: app is in background uid Ui
  • Ch4t4r
    Ch4t4r about 5 years
    Where does it crash exactly? Haven't tested on Pie yet. And again, this is a hack and not something you'd want to do in the first place (normally).
  • Shivam Bhusri
    Shivam Bhusri about 5 years
    when temporaryservice tries to start permanentservice(in oncreate method of temporaryservice:startService(new Intent(this, PermanentBackgroundService.class));)
  • Ch4t4r
    Ch4t4r about 5 years
    Tested on emulator, still works for me. Did you declare the FOREGROUND_SERVICE permission in the manifest?
  • Shivam Bhusri
    Shivam Bhusri about 5 years
    yeah not it works but In pie permanent service gets destroyed every 30seconds
  • Hilal
    Hilal about 5 years
    I guess work manager shows the notification. Can I avoid it and make it look like it works in background?
  • Khemraj Sharma
    Khemraj Sharma about 5 years
    Work manager does not show notification. There must be some code implemented for showing notification. See this answer. stackoverflow.com/a/15775964/6891563
  • j3ko
    j3ko over 4 years
    What is the best solution to schedule a reliable periodic task that will work on all ROMs (including chinese)?
  • DS009
    DS009 almost 4 years
    @Khemraj : can you post a sample code for this please, I tried different options and couldn't get it working.
  • JohnyTex
    JohnyTex over 2 years
    WorkManager can only run ten minute jobs though.
  • JohnyTex
    JohnyTex over 2 years
    WorkManager can only run ten minute jobs though.