15

My app has a background service running that gets users current location and update it to a server every five minutes. To run this location update process continuously, I use alarm manager to set its next execution time from the service itself. However, when I install the app in my Nokia 6 running Android 8.1 it works for some time and if I keep the phone idle for some time, my service will get killed with the next alarms by the application also being cleared from system alarm manager. My guess was that the idle time makes the phone enter doze mode. However, I don't understand why the alarm managers got cleared. To my understanding, the doze mode should open up maintenance windows periodically to execute any pending tasks.

To mitigate this issue, I tried to apply a Job Scheduler service on top of Alarm Manager, which runs every 15 minutes. Purpose of this job scheduler was to re-start the service which has the alarm manager in it, so even if it gets killed and the alarm is cleared, job scheduler would re-up the service.

After I tested this patch and keeping it for some time to go into idle mode, it resulted in getting both Job Scheduler Service and Service which has the alarm in it killed with the scheduled jobs and alarms getting cleared from the system.

It is said in the Android documentation that we can use JobScheduler to mitigate its background execution limitations. And to test this out I forced killed the two services when I tested the app, but the already scheduled job did not get cleared, and it made the service with the alarm run again successfully. I don't understand the reason for this behavior, although the Evernote guys give an explanation that could match this scenario in here Android Job by Evernote

Any ideas for this abnormal behavior?

Test Environment Details

  • Device : Nokia 6 (TA-1021)
  • OS : Android 8.1.0
Ryan M
  • 18,333
  • 31
  • 67
  • 74
k9yosh
  • 858
  • 1
  • 11
  • 31
  • are you running foreground service or background service? Are you de-registering AlarmManager in onDestory() of service? – Sagar Jun 01 '18 at 03:52
  • @Sagar I tried running on both background and foreground. Yes, I am de-registering the Alarm from the Job Scheduler service. That is only if it is already set. Purpose of running the job scheduler was to clean up the alarm manager and reset the alarms every 15 minutes – k9yosh Jun 02 '18 at 15:43
  • @k9yosh did you find any solution or workaround to make this work in Android Oreo and Oreo+ devices.? I am getting this too. – Qadir Hussain Nov 29 '19 at 07:39
  • @QadirHussain No I did not. Porting your code to a FCM based notification system is the best option. And it works flawlessly. – k9yosh Nov 29 '19 at 07:46
  • @k9yosh thank you for your response. can you please tell this.? Can I register a broadcastReciver (with action ACTION_SCREEN_ON) when a push notification is received. – Qadir Hussain Nov 29 '19 at 08:44
  • @QadirHussain Yeah this should be possible. – k9yosh Dec 03 '19 at 06:30

4 Answers4

4

You would not be able to run background services long running in Oreo as there are behaviour changes, now Oreo to optimise system memory, battery etc, it kills background service, to solve your issue you should use foreground service.

Have a look at Background execution limits https://developer.android.com/about/versions/oreo/android-8.0-changes

A suggestion from me, if you can use FCM then go for it, becasue apps like WeChat, Facebook uses it, to deliver notifications and they don't face any problem...

Hope this helps in understanding the issue....

Abdul Aziz
  • 442
  • 5
  • 12
  • I have tried using foreground but still, it's getting killed. I didn't try FCM because there are some limitations. But that seems to be the only choice to try out. – k9yosh Jun 02 '18 at 12:50
  • @k9yosh look at this link specifically for your task: https://developer.android.com/about/versions/oreo/background-location-limits – Abdul Aziz Jun 04 '18 at 05:41
  • Even if google photos app is killed it uploads photos once i click in camera. How this is done. Any ideas. – Durgaprasad Jul 31 '19 at 07:02
  • @Durgaprasad when you click in the camera it sends intent to the google photos which is then caught by it and hence it starts working...this can be done with any app if you pass correct intent and catch it with intent filters. – Abdul Aziz Nov 14 '19 at 09:06
  • This is ridiculous that you need an FCM server just to make sure app alarms work reliably! It's an unnecessary overkill... Why does Android make the lives of its developers so miserable?! I know there are bad players, but still you cannot just kill alarms randomly. – doctorram Apr 30 '21 at 20:44
1

In Doze more, the alarms do not get reset, but get deferred to a later time. You have two mainstream options here:

  1. Use either setAndAllowWhileIdle() or setExactAndAllowWhileIdle(). However, these too can fire at the maximum frequency of 1 time per 9 minutes. So you'll have to decrease the frequency at which you get location in your app.

  2. Use a foreground service by way of showing a foreground notification. Everyone does that (apps like Uber, Google Maps etc). That way, your service won't get killed, and be treated as though you have an app open.

Abdul Wasae
  • 3,614
  • 4
  • 34
  • 56
  • 3
    I have used both these options, but still, it gets killed. Even the foreground service gets killed after some time in doze mode – k9yosh May 28 '18 at 09:23
0

I'm currently facing the same issue and doing the same workaraound like you do. That is, setting the Jobscheduler to a periodic job to launch my Foreground Service every 15 min in case it is getting killed for whatever reasons like a killed task. This works like a charm on pre Oreo Versions.

For Oreo the only solution I am awared of at the moment is, to allow the app to autostart in the settings. Under installed apps that is. Then it should work like pre Oreo again. What Ive heard but not tested yet, is to set the setPersisted(true) option in the Job Scheduler. Let me know if that helps

Al Cabone
  • 413
  • 6
  • 17
  • Yes, your first workaround works for pre oreo versions. I tried the same thing but the other way around. Works fine in other versions other than oreo. I will try your second workaround and get back to you. Any explanation for such behavior? – k9yosh May 28 '18 at 09:27
  • Ive tried setPersisted(true) and it did not work for me on a Xiaomi Mi Mix2 with Miui. But since they have there own way to handle apps in the background, that does not neccessarily mean much. The only explanation I have so far is that Oreo does not allow apps to start which are neither classified as foreground or background except you allow specifically for it with autostart setting. Unfortunately Im not awared of a workaround as for now. – Al Cabone May 28 '18 at 11:11
  • same problem for me did any work around worked to manage doze mode?? – Vivek Mar 16 '20 at 11:19
0

I assumed currently DOZE mode not allowed to background service so you need to find a way that DOZE mode will not affect on your app.To solve your issue you should use foreground service. or make some battery setting. Any way my better option is you should go with Firebase Cloud Messaging

MK Vimalan
  • 1,213
  • 14
  • 28