Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Push message cannot start service at once

Context

We are developing an android app that is supposed to do the following:

  1. the user installs the app, registers and closes the app
  2. once or twice a year an admin sends a Firebase data message with priority high to the user containing a geo fence
  3. the FCM message starts a JobService that locates where the phone is
  4. if the phone is inside the given area an Activity is started and user interaction starts
  5. if the phone is outside the area the service is stopped and the user is never disturbed

I developed the app based on the Firebase push example found here

The problem

The application works fine on my older phones but on my new test phone (android 8.1.0, LineageOS 15.1) we have a problem when the phone is in sleep mode. In this case the FCM message arrives instantly but the service is first started once the phone is unlocked. So the message is stuck between 2. and 3.

We need the app to respond at once - not when the user decides to use his phone 2 hours later.

I assume the problem is due to the Doze mode introduced with android 6. I tried to solve it by adding the app to the whitelist in settings->battery->battery optimization but this did not solve the problem.

Questions

  1. Is it Doze mode that delays my app between 2. and 3.? If so why is it not solved when the app is in the whitelist?

  2. Is there any other way to start the location service at once? This post suggests that a foreground service can do it but this requires that a notification is shown which breaks with 5.

  3. Is there another way to start my service at once besides whitelist and foreground service?

like image 497
Theis Borg Avatar asked Jan 26 '18 13:01

Theis Borg


2 Answers

Yes! you are right this may be due to the Doze and App Standby features introduced in API 23 Marshmallow.

As mentioned in the documentation, the system do ignore wakelocks and system doesn't allow JobScheduler to run, which effectively prevents your app from running the Job.

An easy and effective workaround would be to run Location detecting routine inside a normal background service and start it using startService() when you receive FCM push.

Note that you might still need to white-list your app because as mentioned in another post here, only a whitelisted app can use the network and hold partial wake locks.

like image 186
riyaz-ali Avatar answered Oct 19 '22 11:10

riyaz-ali


Is it Doze mode that delays my app between 2. and 3.?

From the documentation Doze mode affect Network access and blocks JobScheduler.

If so why is it not solved when the app is in the whitelist?

Also from the documentation: An app that is whitelisted can use the network and hold partial wake locks during Doze and App Standby. However, other restrictions still apply to the whitelisted app, just as they do to other apps.

So the blocking of JobScheduler still applies.

Is there any other way to start the location service at once? This post suggests that a foreground service can do it but this requires that a notification is shown which breaks with 5.

Ignore Battery Optimizations (for Internet access) in combination with an AlarmManager with setAndAllowWhileIdle() or setExactAndAllowWhileIdle() should work.

Be careful with Ignore Battery Optimizations

Google Play policies prohibit apps from requesting direct exemption from Power Management features in Android 6.0+ (Doze and App Standby) unless the core function of the app is adversely affected.

I think an important question here is: Do you really need to execute the JobScheduler immediately.

If a user leaves a device unplugged and stationary for a period of time, with the screen off, the device enters Doze mode.

If the device is in Doze mode, it means the user is not using it.

if the phone is inside the given area an Activity is started and user interaction starts

This is the step Doze blocks

We need the app to respond at once - not when the user decides to use his phone 2 hours later.

If the device is in Doze it means the user is not interacting with it. Even if you show the Activity the user is not using the phone, he will see it when he starts using it 2 hours later :)

like image 31
LordRaydenMK Avatar answered Oct 19 '22 10:10

LordRaydenMK