According to Android Marshmallow documentation when the system is in doze mode, any wakelock is ignored. However it\'s not clear to me if a wakelock prevent doze mode or not
As far as I have explored, all wake locks (except the ones held by apps with a current foreground service) are dropped when the deeper doze starts. The whole point of doze is to let the system sleep when the 'relevant conditions' set in. So yes locks is not something they would care too much about I guess.
The way I see it JobScheduler is the way to go about scheduling, background tasks etc in future. Takes some control away from developers though but that's the call I guess framework guys took for battery life. It's more like 'trigger and hope things will happen more or less on time'.
Coming to your use case, JobScheduler has an onStopJob callback to know when the execution of your job has stopped [for any reason - say wifi was toggled] you need to take appropriate action such as rescheduling your job for the next maintenance window. From the docs:
One immediate repercussion is that the system will cease holding a wakelock for you.
In response to the comment discussion above, this is not an answer to the question. It's meant to clarify app behaviour in Doze mode in general. In my testing app, I tried to get a GPS position every 2 minutes, GPS signal strength was sufficient at all times.
Testing conditions:
GPS test log for Doze mode:
1 2015-09-04 - 12:14 GPS ok (device left stationary unplugged)
2 2015-09-04 - 12:16 GPS ok
3 2015-09-04 - 12:18 GPS ok
4 2015-09-04 - 12:20 GPS ok
5 2015-09-04 - 12:22 GPS ok
6 2015-09-04 - 12:24 GPS ok
7 2015-09-04 - 12:26 GPS ok
8 2015-09-04 - 12:28 GPS ok
9 2015-09-04 - 12:30 GPS ok
10 2015-09-04 - 12:32 GPS ok
11 2015-09-04 - 12:34 GPS ok
...
31 2015-09-04 - 13:14 GPS ok
32 2015-09-04 - 13:16 GPS ok
33 2015-09-04 - 13:18 GPS ok
34 2015-09-04 - 13:20 GPS ok
35 2015-09-04 - 13:22 GPS ok
36 2015-09-04 - 13:24 GPS ok
37 2015-09-04 - 13:26 GPS ok (entering Doze mode some time after)
38 2015-09-04 - 13:42 GPS failed, active millis: 60174 (idle)
39 2015-09-04 - 13:57 GPS failed, active millis: 60128 (idle)
40 2015-09-04 - 14:12 GPS failed, active millis: 60122 (idle)
41 2015-09-04 - 14:16 GPS ok (idle maintenance)
42 2015-09-04 - 14:18 GPS ok (idle maintenance)
43 2015-09-04 - 14:20 GPS ok (idle maintenance)
44 2015-09-04 - 14:22 GPS ok (idle maintenance)
45 2015-09-04 - 14:38 GPS failed, active millis: 60143 (idle)
46 2015-09-04 - 14:53 GPS failed, active millis: 60122 (idle)
47 2015-09-04 - 15:08 GPS failed, active millis: 60068 (idle)
48 2015-09-04 - 15:23 GPS failed, active millis: 60138 (idle)
49 2015-09-04 - 15:38 GPS failed, active millis: 60140 (idle)
50 2015-09-04 - 15:53 GPS failed, active millis: 60131 (idle)
51 2015-09-04 - 16:08 GPS failed, active millis: 60185 (idle)
52 2015-09-04 - 16:12 GPS ok (ending Doze mode - power button on)
Now that I looked at my logs again, I noticed a very strange behavior: The same test with "ignore optimizations" OFF showed basically identical results (like it should), BUT most of the times the timeout did not work as expected, I got 'active millis' in the range of either ~330000 (~5 times timeout time) or even ~580000 (~10 times timeout time) while idle. This weird behavior I can not explain, but it seems to show that there actually IS some effect of the setting of "ignore optimizations" on Doze mode.
Edit: The 'strange' behavior described above is just now documented: Only with "ignore optimizations" ON, you may hold a partial wakelock in Doze idle mode.
Based on some testing, using a Nexus 5 with the the final(?) preview of Android 6.0 installed:
Holding a PARTIAL_WAKE_LOCK
is insufficient to block Doze mode — the device will still doze, even though you have the WakeLock
and are trying to do regular work (e.g., setExactAndAllowWhileIdle()
to get control every minute)
Keeping the screen on using android:keepScreenOn
(or the Java equivalent), with the screen on, is sufficient to block Doze mode
Keeping the screen on using android:keepScreenOn
(or the Java equivalent), with the screen off (user presses POWER button), is insufficient to block Doze mode
IOW, video players and the like should not be affected while the user is watching the video, even though the player may not be moving or charging. However, if the user presses the POWER button, you're back into having Doze risk.
I have not tried using FULL_WAKE_LOCK
(I would expect behavior identical to android:keepScreenOn
, but I am far from certain).
Interesting
Google's own clock app in Android 6.0 is able to block Doze mode altogether:
The state remains as 'Stepped to: ACTIVE'
If you set an alarm with a time > 60 minutes from now, it works normally (device may go into idle states). BUT once the alarm is < 60 min away it seems that the device quietly awakes from Doze idle, as the state returns 'ACTIVE' again (instead of 'IDLE_MAINTENANCE').
I really wonder how they are doing this!
- EDIT -
It seems to be setAlarmClock()
that is having this behavior by default.
This might be helpful for some use cases.