David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 1 | page.title=Optimizing for Doze and App Standby |
| 2 | page.metaDescription=Test and optimize your app for the power-saving features in Android 6.0. |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 3 | page.tags=doze, app standby, marshmallow, alarms |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 4 | meta.tags="battery", "marshmallow", "alarms" |
Quddus Chong | 1c7be2e | 2015-09-28 11:22:53 -0700 | [diff] [blame] | 5 | page.image=images/cards/card-doze_16-9_2x.png |
David Friedman | 1b75a36 | 2015-09-29 09:43:46 -0700 | [diff] [blame] | 6 | |
| 7 | |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 8 | parent.link=index.html |
| 9 | |
| 10 | trainingnavtop=true |
| 11 | next.title=Monitoring the Battery Level and Charging State |
| 12 | next.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> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 21 | <li><a href="#restrictions">Doze restrictions</a></li> |
| 22 | <li><a href="#assessing_your_app">Adapting your app to Doze</a></li> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 23 | </ol> |
| 24 | </li> |
| 25 | <li><a href="#understand_app_standby">Understanding App Standby</a></li> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 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 |
| 29 | Standby</a> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 30 | <ol> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 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> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 33 | </ol> |
| 34 | </li> |
Dirk Dougherty | 6a38543 | 2016-01-07 18:18:05 -0800 | [diff] [blame] | 35 | <li><a href="#whitelisting-cases">Acceptable Use Cases for Whitelisting</a></li> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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 |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 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 |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 45 | of time. <em>App Standby</em> defers background network activity for apps |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 46 | with which the user has not recently interacted. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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 |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 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 |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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 |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 70 | system runs all pending syncs, jobs, and alarms, and lets apps access the |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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;"> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 77 | <strong>Figure 1.</strong> Doze provides a recurring maintenance window for apps to use the |
| 78 | network and handle pending activities. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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 |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 86 | reduce battery consumption in cases of longer-term inactivity when the device is not |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 105 | <li>Network access is suspended. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 106 | </li> |
| 107 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 108 | <li>The system ignores <a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html"> |
| 109 | wake locks</a>. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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, |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 115 | android.app.PendingIntent) setWindow()}) are deferred to the next maintenance window. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 116 | </li> |
| 117 | |
| 118 | <li style="list-style: none; display: inline"> |
| 119 | <ul> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 120 | <li>If you need to set alarms that fire while in Doze, use {@link |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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 — 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 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 138 | <li>The system does not allow |
| 139 | <a href="{@docRoot}reference/android/content/AbstractThreadedSyncAdapter.html">sync adapters</a> |
| 140 | to run. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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 |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 155 | messaging</a>. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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 | |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 163 | <li>Provide sufficient information within the initial <a href= |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 164 | "https://developers.google.com/cloud-messaging/concept-options#payload">message |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 165 | payload</a>, so subsequent network access is unnecessary. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 176 | <a href="#testing_doze">Test your app in Doze.</a> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 177 | </li> |
| 178 | </ul> |
| 179 | </ol> |
| 180 | </div> |
| 181 | </div> |
| 182 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 183 | <h3 id="assessing_your_app">Adapting your app to Doze</h3> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 184 | |
| 185 | <p> |
| 186 | Doze can affect apps differently, depending on the capabilities they offer |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 187 | and the services they use. Many apps function normally across Doze |
| 188 | cycles without modification. In some cases, you must optimize the way |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 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. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 196 | </p> |
| 197 | |
| 198 | <p> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 199 | To help with scheduling alarms, Android 6.0 (API level 23) introduces two new |
| 200 | {@link android.app.AlarmManager} methods: {@link |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 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, |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 205 | you can set alarms that will fire even if the device is in Doze. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 206 | </p> |
| 207 | |
Adarsh Fernando | 9140e0d | 2016-04-06 10:36:53 -0700 | [diff] [blame] | 208 | <p class="note"> |
| 209 | <strong>Note:</strong> Neither {@link |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 210 | android.app.AlarmManager#setAndAllowWhileIdle(int, long, |
David Friedman | 1b75a36 | 2015-09-29 09:43:46 -0700 | [diff] [blame] | 211 | android.app.PendingIntent) setAndAllowWhileIdle()} nor {@link |
| 212 | android.app.AlarmManager#setExactAndAllowWhileIdle(int, long, |
Adarsh Fernando | 9140e0d | 2016-04-06 10:36:53 -0700 | [diff] [blame] | 213 | android.app.PendingIntent) setExactAndAllowWhileIdle()} can fire alarms more |
| 214 | than once per 9 minutes, per app. |
| 215 | </p> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 216 | |
| 217 | <p> |
| 218 | The Doze restriction on network access is also likely to affect your app, |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 219 | especially if the app relies on real-time messages such as tickles or |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 220 | notifications. If your app requires a persistent connection to the network to |
David Friedman | 8e69aaf | 2015-09-30 12:26:12 -0700 | [diff] [blame] | 221 | receive messages, you should use <a href="#using_gcm">Google Cloud Messaging (GCM)</a> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 222 | if possible. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 223 | </p> |
| 224 | |
| 225 | <p> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 226 | To confirm that your app behaves as expected with Doze, you can use adb commands to force the |
| 227 | system to enter and exit Doze and observe your app’s behavior. For details, see |
| 228 | <a href="#testing_doze_and_app_standby">Testing with Doze and App Standby</a>. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 229 | </p> |
| 230 | |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 231 | <h2 id="understand_app_standby">Understanding App Standby</h2> |
| 232 | |
| 233 | <p> |
| 234 | App Standby allows the system to determine that an app is idle when the user |
| 235 | is not actively using it. The system makes this determination when the user |
| 236 | does not touch the app for a certain period of time and none of the following |
| 237 | conditions applies: |
| 238 | </p> |
| 239 | |
| 240 | <ul> |
| 241 | <li>The user explicitly launches the app. |
| 242 | </li> |
| 243 | |
| 244 | <li>The app has a process currently in the foreground (either as an activity |
| 245 | or foreground service, or in use by another activity or foreground service). |
| 246 | </li> |
| 247 | |
| 248 | <li>The app generates a notification that users see on the lock screen or in |
| 249 | the notification tray. |
| 250 | </li> |
| 251 | </ul> |
| 252 | |
| 253 | <p> |
| 254 | When the user plugs the device into a power supply, the system releases apps |
| 255 | from the standby state, allowing them to freely access the network and to |
| 256 | execute any pending jobs and syncs. If the device is idle for long periods of |
| 257 | time, the system allows idle apps network access around once a day. |
| 258 | </p> |
| 259 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 260 | <h2 id="using_gcm">Using GCM to Interact with Your App While the Device is Idle</h2> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 261 | |
| 262 | <p> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 263 | <a href="https://developers.google.com/cloud-messaging/">Google Cloud |
| 264 | Messaging (GCM)</a> is a cloud-to-device service that lets you support |
| 265 | real-time downstream messaging between backend services and apps on |
| 266 | Android devices. GCM provides a single, persistent connection to the cloud; all apps needing |
| 267 | real-time messaging can share this connection. This shared |
| 268 | connection significantly optimizes battery consumption by making it unnecessary for |
| 269 | multiple apps to maintain their own, separate persistent connections, which can |
| 270 | deplete the battery rapidly. For this reason, if your app requires messaging integration with a |
| 271 | backend service, we strongly recommend that you <strong>use GCM if possible</strong>, rather than |
| 272 | maintaining your own persistent network connection. |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 273 | </p> |
| 274 | |
| 275 | <p> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 276 | GCM is optimized to work with Doze and App Standby idle modes by means of |
| 277 | <a href="https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message"> |
| 278 | high-priority GCM messages</a>. GCM high-priority messages let you reliably wake your app to |
| 279 | access the network, even if the user’s device is in Doze or the app is in App Standby mode. |
| 280 | In Doze or App Standby mode, the system delivers the message and gives the |
| 281 | app temporary access to network services and partial wakelocks, then returns the device or app |
| 282 | to idle state. |
| 283 | </p> |
| 284 | |
| 285 | <p> |
| 286 | High-priority GCM messages do not otherwise affect Doze mode, and they don’t |
David Friedman | 8e69aaf | 2015-09-30 12:26:12 -0700 | [diff] [blame] | 287 | affect the state of any other app. This means that your app can use them to communicate |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 288 | efficiently while minimizing battery impacts across the system and device. |
| 289 | </p> |
| 290 | |
| 291 | <p> |
| 292 | As a general best practice, if your app requires downstream messaging, it |
| 293 | should use GCM. If your server and client already uses GCM, make sure that your service uses |
| 294 | high-priority messages for critical messages, since this will reliably |
| 295 | wake apps even when the device is in Doze. |
| 296 | </p> |
| 297 | |
| 298 | <h2 id="support_for_other_use_cases">Support for Other Use Cases</h2> |
| 299 | |
| 300 | <p> |
| 301 | Almost all apps should be able to support Doze by managing network connectivity, alarms, |
| 302 | jobs, and syncs properly, and using GCM high-priority messages. For a narrow |
| 303 | set of use cases, this might not be sufficient. For such cases, the system |
| 304 | provides a configurable whitelist of apps that are <strong>partially |
| 305 | exempt</strong> from Doze and App Standby optimizations. |
| 306 | </p> |
| 307 | |
| 308 | <p> |
| 309 | An app that is whitelisted can use the network and hold |
| 310 | |
| 311 | <a href="{@docRoot}reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK"> |
| 312 | partial wake locks</a> during Doze and |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 313 | App Standby. However, <strong>other restrictions still apply</strong> to the |
| 314 | whitelisted app, just as they do to other apps. For example, the whitelisted |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 315 | app’s jobs and syncs are deferred, and its regular {@link android.app.AlarmManager} alarms do not |
| 316 | fire. An app can check whether it is currently on the exemption whitelist by |
| 317 | calling {@link |
| 318 | android.os.PowerManager#isIgnoringBatteryOptimizations(java.lang.String) |
| 319 | isIgnoringBatteryOptimizations()}. |
| 320 | </li> |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 321 | </p> |
| 322 | |
| 323 | <p> |
| 324 | Users can manually configure the whitelist in <strong>Settings > Battery |
| 325 | > Battery Optimization.</strong> Alternatively, the system provides |
| 326 | ways for apps to ask users to whitelist them. |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 327 | |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 328 | </p> |
| 329 | |
| 330 | <ul> |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 331 | <li>An app can fire the {@link |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 332 | android.provider.Settings#ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS} intent |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 333 | to take the user directly to the <strong>Battery Optimization</strong>, where they can |
| 334 | add the app. |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 335 | </li> |
| 336 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 337 | <li>An app holding the {@link |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 338 | android.Manifest.permission#REQUEST_IGNORE_BATTERY_OPTIMIZATIONS} permission |
| 339 | can trigger a system dialog to let the user add the app to the whitelist |
| 340 | directly, without going to settings. The app fires a {@link |
| 341 | android.provider.Settings#ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS} Intent |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 342 | to trigger the dialog. |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 343 | </li> |
| 344 | |
| 345 | <li>The user can manually remove apps from the whitelist as needed. |
| 346 | </li> |
| 347 | </ul> |
| 348 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 349 | <p>Before asking the user to add your app to the whitelist, make sure the app |
| 350 | |
| 351 | matches the <a href="#whitelisting-cases">acceptable use cases</a> for whitelisting.</p> |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 352 | |
| 353 | |
| 354 | <p class="caution"> |
| 355 | <strong>Note:</strong> Google Play policies prohibit apps from requesting |
| 356 | direct exemption from Power Management features in Android 6.0+ (Doze and App |
| 357 | Standby) unless the core function of the app is adversely affected. |
| 358 | </p> |
| 359 | |
| 360 | <h2 id="testing_doze_and_app_standby">Testing with Doze and App Standby</h2> |
| 361 | |
| 362 | <p> |
| 363 | To ensure a great experience for your users, you should test your app fully |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 364 | in Doze and App Standby. |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 365 | </p> |
| 366 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 367 | <h3 id="testing_doze">Testing your app with Doze</h4> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 368 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 369 | <p>You can test Doze mode by following these steps:</p> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 370 | <ol> |
| 371 | <li>Configure a hardware device or virtual device with an Android 6.0 (API |
| 372 | level 23) or higher system image. |
| 373 | </li> |
| 374 | |
| 375 | <li>Connect the device to your development machine and install your app. |
| 376 | </li> |
| 377 | |
| 378 | <li>Run your app and leave it active. |
| 379 | </li> |
| 380 | |
David Friedman | 8e69aaf | 2015-09-30 12:26:12 -0700 | [diff] [blame] | 381 | <li>Shut off the device screen. (The app remains active.) |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 382 | </li> |
| 383 | |
David Friedman | 8e69aaf | 2015-09-30 12:26:12 -0700 | [diff] [blame] | 384 | <li>Force the system to cycle through Doze modes by running the following |
| 385 | commands: |
| 386 | |
| 387 | <pre class="no-pretty-print"> |
| 388 | $ adb shell dumpsys battery unplug |
| 389 | $ adb shell dumpsys deviceidle step</pre> |
| 390 | |
| 391 | <p>You may need to run the second command more than once. Repeat it until |
| 392 | the device state changes to idle.</p> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 393 | </li> |
| 394 | |
| 395 | <li> Observe the behavior of your app after you reactivate the device. Make |
| 396 | sure the app recovers gracefully when the device exits Doze. |
| 397 | </li> |
| 398 | </ol> |
| 399 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 400 | <h3 id="testing_your_app_with_app_standby">Testing your app with App Standby</h4> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 401 | |
| 402 | <p>To test the App Standby mode with your app:</p> |
| 403 | |
| 404 | <ol> |
| 405 | <li> Configure a hardware device or virtual device with an Android 6.0 (API level |
| 406 | 23) or higher system image. |
| 407 | </li> |
| 408 | <li> Connect the device to your development machine and install your app.</li> |
| 409 | <li> Run your app and leave it active.</li> |
| 410 | <li> Force the app into App Standby mode by running the following commands: |
| 411 | |
| 412 | <pre class="no-pretty-print">$ adb shell dumpsys battery unplug |
| 413 | $ adb shell am set-inactive <packageName> true</pre> |
| 414 | <li>Simulate waking your app using the following commands: |
| 415 | |
| 416 | <pre class="no-pretty-print">$ adb shell am set-inactive <packageName> false |
| 417 | $ adb shell am get-inactive <packageName></pre> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 418 | </li> |
| 419 | <li>Observe the behavior of your app after waking it. Make sure the app recovers gracefully |
| 420 | from standby mode. In particular, you should check if your app's Notifications and background |
| 421 | jobs continue to function as expected. |
| 422 | </li> |
| 423 | </ol> |
| 424 | |
| 425 | |
Dirk Dougherty | 6a38543 | 2016-01-07 18:18:05 -0800 | [diff] [blame] | 426 | <h2 id="whitelisting-cases">Acceptable Use Cases for Whitelisting</h2> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 427 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 428 | <p>The table below highlights the acceptable use cases for requesting or being on |
| 429 | the Battery Optimizations exceptions whitelist. In general, your app should not be on the |
Dirk Dougherty | caa32fa | 2015-10-16 10:08:55 -0700 | [diff] [blame] | 430 | whitelist unless Doze or App Standby break the core function of the app or there is a |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 431 | technical reason why your app cannot use GCM high-priority messages.</p> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 432 | |
David Friedman | 76b6a19 | 2015-09-28 12:29:41 -0700 | [diff] [blame] | 433 | <p>For more information, see <a href="#support_for_other_use_cases">Support for Other Use Cases |
| 434 | </a>.</p> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 435 | |
| 436 | <table> |
| 437 | <tr> |
| 438 | <th>Type</td> |
| 439 | <th>Use-case</td> |
| 440 | <th>Can use GCM?</td> |
| 441 | <th>Whitelisting acceptable?</td> |
| 442 | <th>Notes</td> |
| 443 | </tr> |
| 444 | |
| 445 | <tr> |
| 446 | <td rowspan="2">Instant messaging, chat, or calling app. </td> |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 447 | <td rowspan="3">Requires delivery of real-time messages to users while device is in Doze or app |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 448 | is in App Standby.</td> |
| 449 | <td>Yes, using GCM</td> |
| 450 | <td rowspan="2" style="color:red">Not Acceptable</td> |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 451 | <td rowspan="2">Should use GCM high-priority messages to wake the app and access the network.</td> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 452 | </tr> |
| 453 | |
| 454 | <tr> |
Dirk Dougherty | 1a5ac2d | 2015-09-28 10:52:18 -0700 | [diff] [blame] | 455 | <td>Yes, but is not using GCM high-priority messages.</td> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 456 | </tr> |
| 457 | |
| 458 | <tr> |
| 459 | <td rowspan="1">Instant messaging, chat, or calling app; |
Dirk Dougherty | 6a38543 | 2016-01-07 18:18:05 -0800 | [diff] [blame] | 460 | enterprise VOIP apps.</td> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 461 | <td>No, can not use GCM because of technical dependency on another messaging |
Dirk Dougherty | caa32fa | 2015-10-16 10:08:55 -0700 | [diff] [blame] | 462 | service or Doze and App Standby break the core function of the app.</td> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 463 | <td style="color:green">Acceptable</td> |
| 464 | <td></td> |
| 465 | </tr> |
| 466 | |
Dirk Dougherty | 6a38543 | 2016-01-07 18:18:05 -0800 | [diff] [blame] | 467 | <tr> |
| 468 | <td rowspan="1">Task automation app</td> |
| 469 | <td>App's core function is scheduling automated actions, such as for instant |
| 470 | messaging, voice calling, new photo management, or location actions.</td> |
| 471 | <td>If applicable.</td> |
| 472 | <td style="color:green">Acceptable</td> |
| 473 | <td></td> |
| 474 | </tr> |
| 475 | |
Dirk Dougherty | 9a30832 | 2016-02-29 19:09:00 -0800 | [diff] [blame] | 476 | <tr> |
| 477 | <td rowspan="2">Peripheral device companion app</td> |
| 478 | <td>App's core function is maintaining a persistent connection with the peripheral |
| 479 | device for the purpose of providing the peripheral device internet access.</td> |
| 480 | <td >If applicable.</td> |
| 481 | <td style="color:green">Acceptable</td> |
| 482 | <td rowspan="2"></td> |
| 483 | </tr> |
| 484 | |
| 485 | <tr> |
| 486 | <td>App only needs to connect to a peripheral device periodically to sync, or only |
| 487 | needs to connect to devices, such as wireless headphones, connected via standard |
| 488 | Bluetooth profiles.</td> |
| 489 | <td >If applicable.</td> |
| 490 | <td style="color:red">Not Acceptable</td> |
| 491 | </tr> |
David Friedman | fb546b0 | 2015-09-11 19:00:08 -0700 | [diff] [blame] | 492 | </table> |
| 493 | |
| 494 | |