Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCM high priority messages not received in deep idle mode

After entering Deep Idle Mode using:

adb shell dumpsys deviceidle force-idle

I'm trying to send the device a high priority message, as suggested by the documentation, using:

{ "to" : "feoLl37Ses4:A.......hDQU1OZKd", "priority" : "high", "notification" : { "body" : "This is the body.", "title" : "this is the title", "icon" : "new" } }

The message is not received. Only after I change the state of the device to IDLE_MAINTENANCE the message is received.

How can I get the device to receive the message even if it's in deep idle mode?

like image 633
Udi Idan Avatar asked Feb 23 '17 01:02

Udi Idan


2 Answers

I know is late answer but just in case anyone runs into this same issue. I was experiencing the same issue and spent a few hours trying several solutions until I came to the conclusion that you shouldn't use adb shell dumpsys deviceidle force-idle to enter deep idle mode to test your push notifications, because they will simply not be received (your device is forced into deep idle mode whatever happens unless you execute the unforce command).

If you want to test your high priority push notifications in deep idle mode use instead adb shell dumpsys deviceidle step to go through all steps until you reach deep idle mode. Here is an example.

adb shell dumpsys deviceidle get light
ACTIVE
adb shell dumpsys deviceidle step
Stepped to deep: IDLE_PENDING
adb shell dumpsys deviceidle get light
INACTIVE
adb shell dumpsys deviceidle step
Stepped to deep: SENSING
adb shell dumpsys deviceidle step
Stepped to deep: LOCATING
adb shell dumpsys deviceidle step
Stepped to deep: IDLE
adb shell dumpsys deviceidle get light
OVERRIDE
adb shell dumpsys deviceidle get deep
IDLE

This way you will enter deep doze mode as in a real case scenario and your pushes will be received as expected. Notice that before calling the step command you should execute adb shell dumpsys battery unplug and turn the device screen off.

My guess adb shell dumpsys deviceidle force-idle is stronger since it forces idle mode even if the device screen is on. It is totally misleading from the official android doc when they say "You can test Doze mode by following these steps:" and tell you to use the force-idle command. Because this force-idle does not work as the real one and there isn't any disclaimer regarding that.

like image 153
JorgeMuci Avatar answered Oct 13 '22 21:10

JorgeMuci


If you want to wake app from Doze state(so you can receive messages) use, setAndAllowWhileIdle() and setExactAndAllowWhileIdle().

Your app went to Doze mode when you executed the command

adb shell dumpsys deviceidle force-idle

Doze restrictions

The following restrictions apply to your apps while in Doze:

  1. Network access is suspended.
  2. The system ignores wake locks.
  3. Standard AlarmManager alarms (including setExact() and setWindow()) are deferred to the next maintenance window.
  4. If you need to set alarms that fire while in Doze, use setAndAllowWhileIdle() or setExactAndAllowWhileIdle().
  5. Alarms set with setAlarmClock() continue to fire normally — the system exits Doze shortly before those alarms fire.
  6. The system does not perform Wi-Fi scans.
  7. The system does not allow sync adapters to run.
  8. The system does not allow JobScheduler to run

The Doze restriction on network access is also likely to affect your app, especially if the app relies on real-time messages such as tickles or notifications. If your app requires a persistent connection to the network to receive messages, you should use Firebase Cloud Messaging (FCM) if possible.

To help with scheduling alarms, Android 6.0 (API level 23) introduces two new AlarmManager methods: setAndAllowWhileIdle() and setExactAndAllowWhileIdle(). With these methods, you can set alarms that will fire even if the device is in Doze.

like image 34
noogui Avatar answered Oct 13 '22 22:10

noogui