blob: 11e81c1f1c60d7fb85da0e3f020e6e84ccd15b8b [file] [log] [blame]
Trevor Johns682c24e2016-04-12 10:13:47 -07001page.title=Optimizing for Doze and App Standby
2page.metaDescription=Test and optimize your app for the power-saving features in Android 6.0.
3page.tags=doze, app standby, marshmallow, alarms
4meta.tags="battery", "marshmallow", "alarms"
5page.image=images/cards/card-doze_16-9_2x.png
6
7
8parent.link=index.html
9
10trainingnavtop=true
11next.title=Monitoring the Battery Level and Charging State
12next.link=battery-monitoring.html
13@jd:body
14
15<div id="tb-wrapper">
16<div id="tb">
17 <h2>In this document</h2>
18 <ol>
19 <li><a href="#understand_doze">Understanding Doze</a>
20 <ol>
21 <li><a href="#restrictions">Doze restrictions</a></li>
22 <li><a href="#assessing_your_app">Adapting your app to Doze</a></li>
23 </ol>
24 </li>
25 <li><a href="#understand_app_standby">Understanding App Standby</a></li>
26 <li><a href="#using_gcm">Using GCM to Interact with Your App</a></li>
27 <li><a href="#support_for_other_use_cases">Support for Other Use Cases</a></li>
28 <li><a href="#testing_doze_and_app_standby">Testing with Doze and App
29Standby</a>
30 <ol>
31 <li><a href="#testing_doze">Testing your app with Doze</a></li>
32 <li><a href="#testing_your_app_with_app_standby">Testing your app with App Standby</a></li>
33 </ol>
34 </li>
35 <li><a href="#whitelisting-cases">Acceptable Use Cases for Whitelisting</a></li>
36 </ol>
37 </div>
38</div>
39
40<p>
41 Starting from Android 6.0 (API level 23), Android introduces two
42 power-saving features that extend battery life for users by managing how apps behave when a
43 device is not connected to a power source. <em>Doze</em> reduces battery consumption by deferring
44 background CPU and network activity for apps when the device is unused for long periods
45 of time. <em>App Standby</em> defers background network activity for apps
46 with which the user has not recently interacted.
47</p>
48
49<p>
50 Doze and App Standby manage the behavior of all apps running on Android 6.0
51 or higher, regardless whether they are specifically targeting API level 23.
52 To ensure the best experience for users, test your app in Doze and App
53 Standby modes and make any necessary adjustments to your code. The sections
54 below provide details.
55</p>
56
57
58<h2 id="understand_doze">Understanding Doze</h2>
59<p>
60 If a user leaves a device unplugged and stationary for a period of time, with
61 the screen off, the device enters Doze mode. In Doze mode, the system
62 attempts to conserve battery by restricting apps' access to network and
63 CPU-intensive services. It also prevents apps from accessing the network and
64 defers their jobs, syncs, and standard alarms.
65</p>
66
67<p>
68 Periodically, the system exits Doze for a brief time to let apps complete
69 their deferred activities. During this <em>maintenance window</em>, the
70 system runs all pending syncs, jobs, and alarms, and lets apps access the
71 network.
72</p>
73
74<div style="margin:1em 0em;">
75 <img src="{@docRoot}images/training/doze.png">
76 <p class="img-caption" style="text-align:center;">
77 <strong>Figure 1.</strong> Doze provides a recurring maintenance window for apps to use the
78 network and handle pending activities.
79 </p>
80</div>
81
82<p>
83 At the conclusion of each maintenance window, the system again enters Doze,
84 suspending network access and deferring jobs, syncs, and alarms. Over time,
85 the system schedules maintenance windows less and less frequently, helping to
86 reduce battery consumption in cases of longer-term inactivity when the device is not
87 connected to a charger.
88</p>
89
90
91<p>
92 As soon as the user wakes the device by moving it, turning on the screen, or
93 connecting a charger, the system exits Doze and all apps return to normal
94 activity.
95</p>
96
97
98<h3 id="restrictions">Doze restrictions</h3>
99
100<p>
101 The following restrictions apply to your apps while in Doze:
102</p>
103
104<ul>
105 <li>Network access is suspended.
106 </li>
107
108 <li>The system ignores <a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">
109 wake locks</a>.
110 </li>
111
112 <li>Standard {@link android.app.AlarmManager} alarms (including {@link
113 android.app.AlarmManager#setExact(int, long, android.app.PendingIntent) setExact()} and
114 {@link android.app.AlarmManager#setWindow(int, long, long,
115 android.app.PendingIntent) setWindow()}) are deferred to the next maintenance window.
116 </li>
117
118 <li style="list-style: none; display: inline">
119 <ul>
120 <li>If you need to set alarms that fire while in Doze, use {@link
121 android.app.AlarmManager#setAndAllowWhileIdle(int,long,android.app.PendingIntent)
122 setAndAllowWhileIdle()}
123 or {@link android.app.AlarmManager#setExactAndAllowWhileIdle(int, long,
124 android.app.PendingIntent) setExactAndAllowWhileIdle()}.
125 </li>
126
127 <li>Alarms set with {@link
128 android.app.AlarmManager#setAlarmClock(android.app.AlarmManager.AlarmClockInfo,
129 android.app.PendingIntent) setAlarmClock()} continue to fire normally &mdash; the system
130 exits Doze shortly before those alarms fire.
131 </li>
132 </ul>
133 </li>
134
135 <li>The system does not perform Wi-Fi scans.
136 </li>
137
138 <li>The system does not allow
139 <a href="{@docRoot}reference/android/content/AbstractThreadedSyncAdapter.html">sync adapters</a>
140 to run.
141 </li>
142
143 <li>The system does not allow {@link android.app.job.JobScheduler} to run.
144 </li>
145</ul>
146
147
148<div id="qv-wrapper">
149<div id="qv" style="width:300px">
150<h2>Doze checklist</h2>
151<ol>
152<ul>
153 <li>If possible, use GCM for <a href=
154 "https://developers.google.com/cloud-messaging/downstream">downstream
155 messaging</a>.
156 </li>
157
158 <li>If your users must see a notification right away, make sure to use a <a href=
159 "https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message">GCM
160 high priority message</a>.
161 </li>
162
163 <li>Provide sufficient information within the initial <a href=
164 "https://developers.google.com/cloud-messaging/concept-options#payload">message
165 payload</a>, so subsequent network access is unnecessary.
166 </li>
167
168 <li>Set critical alarms with {@link
169 android.app.AlarmManager#setAndAllowWhileIdle(int, long,
170 android.app.PendingIntent) setAndAllowWhileIdle()} and {@link
171 android.app.AlarmManager#setExactAndAllowWhileIdle(int, long,
172 android.app.PendingIntent) setExactAndAllowWhileIdle()}.
173 </li>
174
175 <li>
176 <a href="#testing_doze">Test your app in Doze.</a>
177 </li>
178</ul>
179</ol>
180</div>
181</div>
182
183<h3 id="assessing_your_app">Adapting your app to Doze</h3>
184
185<p>
186 Doze can affect apps differently, depending on the capabilities they offer
187 and the services they use. Many apps function normally across Doze
188 cycles without modification. In some cases, you must optimize the way
189 that your app manages network, alarms, jobs, and syncs. Apps should be able
190 to efficiently manage activities during each maintenance window.
191</p>
192<p>
193 Doze is particularly likely to affect activities that {@link android.app.AlarmManager} alarms and
194 timers manage, because alarms in Android 5.1 (API level 22) or lower do not fire when the system
195 is in Doze.
196</p>
197
198<p>
199 To help with scheduling alarms, Android 6.0 (API level 23) introduces two new
200 {@link android.app.AlarmManager} methods: {@link
201 android.app.AlarmManager#setAndAllowWhileIdle(int, long,
202 android.app.PendingIntent) setAndAllowWhileIdle()} and {@link
203 android.app.AlarmManager#setExactAndAllowWhileIdle(int, long,
204 android.app.PendingIntent) setExactAndAllowWhileIdle()}. With these methods,
205 you can set alarms that will fire even if the device is in Doze.
206</p>
207
208<p class="note"><strong>Note:</strong> Neither
209{@link
210 android.app.AlarmManager#setAndAllowWhileIdle(int, long,
211 android.app.PendingIntent) setAndAllowWhileIdle()} nor {@link
212 android.app.AlarmManager#setExactAndAllowWhileIdle(int, long,
213 android.app.PendingIntent) setExactAndAllowWhileIdle()} can fire alarms more than once per 15
214minutes per app.</p>
215
216<p>
217 The Doze restriction on network access is also likely to affect your app,
218 especially if the app relies on real-time messages such as tickles or
219 notifications. If your app requires a persistent connection to the network to
220 receive messages, you should use <a href="#using_gcm">Google Cloud Messaging (GCM)</a>
221 if possible.
222</p>
223
224<p>
225 To confirm that your app behaves as expected with Doze, you can use adb commands to force the
226 system to enter and exit Doze and observe your app’s behavior. For details, see
227 <a href="#testing_doze_and_app_standby">Testing with Doze and App Standby</a>.
228</p>
229
230<h2 id="understand_app_standby">Understanding App Standby</h2>
231
232<p>
233 App Standby allows the system to determine that an app is idle when the user
234 is not actively using it. The system makes this determination when the user
235 does not touch the app for a certain period of time and none of the following
236 conditions applies:
237</p>
238
239<ul>
240 <li>The user explicitly launches the app.
241 </li>
242
243 <li>The app has a process currently in the foreground (either as an activity
244 or foreground service, or in use by another activity or foreground service).
245 </li>
246
247 <li>The app generates a notification that users see on the lock screen or in
248 the notification tray.
249 </li>
250</ul>
251
252<p>
253 When the user plugs the device into a power supply, the system releases apps
254 from the standby state, allowing them to freely access the network and to
255 execute any pending jobs and syncs. If the device is idle for long periods of
256 time, the system allows idle apps network access around once a day.
257</p>
258
259<h2 id="using_gcm">Using GCM to Interact with Your App While the Device is Idle</h2>
260
261<p>
262 <a href="https://developers.google.com/cloud-messaging/">Google Cloud
263 Messaging (GCM)</a> is a cloud-to-device service that lets you support
264 real-time downstream messaging between backend services and apps on
265 Android devices. GCM provides a single, persistent connection to the cloud; all apps needing
266 real-time messaging can share this connection. This shared
267 connection significantly optimizes battery consumption by making it unnecessary for
268 multiple apps to maintain their own, separate persistent connections, which can
269 deplete the battery rapidly. For this reason, if your app requires messaging integration with a
270 backend service, we strongly recommend that you <strong>use GCM if possible</strong>, rather than
271 maintaining your own persistent network connection.
272</p>
273
274<p>
275 GCM is optimized to work with Doze and App Standby idle modes by means of
276 <a href="https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message">
277 high-priority GCM messages</a>. GCM high-priority messages let you reliably wake your app to
278 access the network, even if the user’s device is in Doze or the app is in App Standby mode.
279 In Doze or App Standby mode, the system delivers the message and gives the
280 app temporary access to network services and partial wakelocks, then returns the device or app
281 to idle state.
282</p>
283
284<p>
285 High-priority GCM messages do not otherwise affect Doze mode, and they don’t
286 affect the state of any other app. This means that your app can use them to communicate
287 efficiently while minimizing battery impacts across the system and device.
288</p>
289
290<p>
291 As a general best practice, if your app requires downstream messaging, it
292 should use GCM. If your server and client already uses GCM, make sure that your service uses
293 high-priority messages for critical messages, since this will reliably
294 wake apps even when the device is in Doze.
295</p>
296
297<h2 id="support_for_other_use_cases">Support for Other Use Cases</h2>
298
299<p>
300 Almost all apps should be able to support Doze by managing network connectivity, alarms,
301 jobs, and syncs properly, and using GCM high-priority messages. For a narrow
302 set of use cases, this might not be sufficient. For such cases, the system
303 provides a configurable whitelist of apps that are <strong>partially
304 exempt</strong> from Doze and App Standby optimizations.
305</p>
306
307<p>
308 An app that is whitelisted can use the network and hold
309
310 <a href="{@docRoot}reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK">
311 partial wake locks</a> during Doze and
312 App Standby. However, <strong>other restrictions still apply</strong> to the
313 whitelisted app, just as they do to other apps. For example, the whitelisted
314 app’s jobs and syncs are deferred, and its regular {@link android.app.AlarmManager} alarms do not
315 fire. An app can check whether it is currently on the exemption whitelist by
316 calling {@link
317 android.os.PowerManager#isIgnoringBatteryOptimizations(java.lang.String)
318 isIgnoringBatteryOptimizations()}.
319 </li>
320</p>
321
322<p>
323 Users can manually configure the whitelist in <strong>Settings &gt; Battery
324 &gt; Battery Optimization.</strong> Alternatively, the system provides
325 ways for apps to ask users to whitelist them.
326
327</p>
328
329<ul>
330 <li>An app can fire the {@link
331 android.provider.Settings#ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS} intent
332 to take the user directly to the <strong>Battery Optimization</strong>, where they can
333 add the app.
334 </li>
335
336 <li>An app holding the {@link
337 android.Manifest.permission#REQUEST_IGNORE_BATTERY_OPTIMIZATIONS} permission
338 can trigger a system dialog to let the user add the app to the whitelist
339 directly, without going to settings. The app fires a {@link
340 android.provider.Settings#ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS} Intent
341 to trigger the dialog.
342 </li>
343
344 <li>The user can manually remove apps from the whitelist as needed.
345 </li>
346</ul>
347
348<p>Before asking the user to add your app to the whitelist, make sure the app
349
350matches the <a href="#whitelisting-cases">acceptable use cases</a> for whitelisting.</p>
351
352
353<p class="caution">
354 <strong>Note:</strong> Google Play policies prohibit apps from requesting
355 direct exemption from Power Management features in Android 6.0+ (Doze and App
356 Standby) unless the core function of the app is adversely affected.
357</p>
358
359<h2 id="testing_doze_and_app_standby">Testing with Doze and App Standby</h2>
360
361<p>
362 To ensure a great experience for your users, you should test your app fully
363 in Doze and App Standby.
364</p>
365
366<h3 id="testing_doze">Testing your app with Doze</h4>
367
368<p>You can test Doze mode by following these steps:</p>
369<ol>
370 <li>Configure a hardware device or virtual device with an Android 6.0 (API
371 level 23) or higher system image.
372 </li>
373
374 <li>Connect the device to your development machine and install your app.
375 </li>
376
377 <li>Run your app and leave it active.
378 </li>
379
380 <li>Shut off the device screen. (The app remains active.)
381 </li>
382
383 <li>Force the system to cycle through Doze modes by running the following
384 commands:
385
386 <pre class="no-pretty-print">
387$ adb shell dumpsys battery unplug
388$ adb shell dumpsys deviceidle step</pre>
389
390 <p>You may need to run the second command more than once. Repeat it until
391 the device state changes to idle.</p>
392 </li>
393
394 <li> Observe the behavior of your app after you reactivate the device. Make
395 sure the app recovers gracefully when the device exits Doze.
396 </li>
397</ol>
398
399<h3 id="testing_your_app_with_app_standby">Testing your app with App Standby</h4>
400
401<p>To test the App Standby mode with your app:</p>
402
403<ol>
404 <li> Configure a hardware device or virtual device with an Android 6.0 (API level
405 23) or higher system image.
406 </li>
407 <li> Connect the device to your development machine and install your app.</li>
408 <li> Run your app and leave it active.</li>
409 <li> Force the app into App Standby mode by running the following commands:
410
411 <pre class="no-pretty-print">$ adb shell dumpsys battery unplug
412$ adb shell am set-inactive &lt;packageName&gt; true</pre>
413 <li>Simulate waking your app using the following commands:
414
415 <pre class="no-pretty-print">$ adb shell am set-inactive &lt;packageName&gt; false
416$ adb shell am get-inactive &lt;packageName&gt;</pre>
417 </li>
418 <li>Observe the behavior of your app after waking it. Make sure the app recovers gracefully
419 from standby mode. In particular, you should check if your app's Notifications and background
420 jobs continue to function as expected.
421 </li>
422</ol>
423
424
425<h2 id="whitelisting-cases">Acceptable Use Cases for Whitelisting</h2>
426
427<p>The table below highlights the acceptable use cases for requesting or being on
428 the Battery Optimizations exceptions whitelist. In general, your app should not be on the
429 whitelist unless Doze or App Standby break the core function of the app or there is a
430 technical reason why your app cannot use GCM high-priority messages.</p>
431
432 <p>For more information, see <a href="#support_for_other_use_cases">Support for Other Use Cases
433 </a>.</p>
434
435<table>
436 <tr>
437 <th>Type</td>
438 <th>Use-case</td>
439 <th>Can use GCM?</td>
440 <th>Whitelisting acceptable?</td>
441 <th>Notes</td>
442 </tr>
443
444 <tr>
445 <td rowspan="2">Instant messaging, chat, or calling app. </td>
446 <td rowspan="3">Requires delivery of real-time messages to users while device is in Doze or app
447 is in App Standby.</td>
448 <td>Yes, using GCM</td>
449 <td rowspan="2" style="color:red">Not Acceptable</td>
450 <td rowspan="2">Should use GCM high-priority messages to wake the app and access the network.</td>
451 </tr>
452
453 <tr>
454 <td>Yes, but is not using GCM high-priority messages.</td>
455 </tr>
456
457 <tr>
458 <td rowspan="1">Instant messaging, chat, or calling app;
459 enterprise VOIP apps.</td>
460 <td>No, can not use GCM because of technical dependency on another messaging
461 service or Doze and App Standby break the core function of the app.</td>
462 <td style="color:green">Acceptable</td>
463 <td></td>
464 </tr>
465
466 <tr>
467 <td rowspan="1">Task automation app</td>
468 <td>App's core function is scheduling automated actions, such as for instant
469 messaging, voice calling, new photo management, or location actions.</td>
470 <td>If applicable.</td>
471 <td style="color:green">Acceptable</td>
472 <td></td>
473 </tr>
474
475 <tr>
476 <td rowspan="2">Peripheral device companion app</td>
477 <td>App's core function is maintaining a persistent connection with the peripheral
478 device for the purpose of providing the peripheral device internet access.</td>
479 <td >If applicable.</td>
480 <td style="color:green">Acceptable</td>
481 <td rowspan="2"></td>
482 </tr>
483
484 <tr>
485 <td>App only needs to connect to a peripheral device periodically to sync, or only
486 needs to connect to devices, such as wireless headphones, connected via standard
487 Bluetooth profiles.</td>
488 <td >If applicable.</td>
489 <td style="color:red">Not Acceptable</td>
490 </tr>
491</table>
492
493