In this codelab, you’ll learn how to test apps for Doze Mode & App Standby compatibility and how they might affect features in your app .

What you’ll learn

What you’ll need

First, let’s see what the sample app looks like. With the app downloaded, the following instructions describe how to install the app onto your device.

  1. Download the sample app to your computer.

Download APK

  1. Enable USB debugging on your Android device.
  2. Plug in your Android device
  3. Open a command line terminal on your computer and go to the directory containing the sample app. Then install the app via the Android Debug Bridge (ADB):
$ cd my-downloads
$ adb install DozeStandbySample.apk
  1. Open the app on the device.

Frequently Asked Questions

In Doze mode, the system attempts to conserve battery by restricting apps' access to network and CPU-intensive services. Doze mode becomes active, if a user leaves a device unplugged and stationary for a period of time, with the screen off.

In order to test doze mode, we first have to simulate an unplugged device. We can do this via ADB:

$ adb shell dumpsys battery unplug

The other precondition for Doze mode is that the screen is switched off. Put your device into sleep mode by pressing the power button or entering:

$ adb shell input keyevent KEYCODE_POWER

Now we can trigger Doze mode via:

$ adb shell dumpsys deviceidle step

This command cycles through the different doze state. You might have to repeat the command a few times until the device enters the Doze IDLE state:

$ adb shell dumpsys deviceidle step
Stepped to: ACTIVE
$ adb shell dumpsys deviceidle step
Stepped to: IDLE_PENDING
$ adb shell dumpsys deviceidle step
Stepped to: SENSING
$ adb shell dumpsys deviceidle step
Stepped to: LOCATING
$ adb shell dumpsys deviceidle step
Stepped to: IDLE_MAINTENANCE
$ adb shell dumpsys deviceidle step
Stepped to: IDLE

Periodically, the system exits Doze for a brief time to let apps complete their deferred activities. During this maintenance window, the system runs all pending syncs, jobs, and alarms, and lets apps access the network. You can trigger the maintenance mode by executing the step command one more time:

$ adb shell dumpsys deviceidle step
Stepped to: IDLE_MAINTENANCE

Another step command brings the device back to IDLE:

$ adb shell dumpsys deviceidle step
Stepped to: IDLE

To leave doze mode, active the display of your device.

Takeaway

In this step you’ve learned how to trigger the different Doze modes via ADB. Use this to test if your app behaves correctly when entering and leaving Doze idle mode.

Doze idle mode does not allow JobScheduler to run. The following steps show you how to background jobs behave in Doze mode.

First we have to start background job. Open the Jobs tab in the sample app and press the START JOB button.

Open a command line terminal and monitor the background job via logcat:

$ adb logcat -s "DozeSample"

DozeSample: Starting Job
DozeSample: Running Job 0
DozeSample: Running Job 1
DozeSample: Running Job 2
DozeSample: Running Job 3

The first thing to test if the job behaves correctly suspends when entering Doze mode. Open a second terminal window and activate the Doze idle mode via:

$ adb shell dumpsys deviceidle step

This results in the background job being suspended. Check in the logcat output in first command line terminal if if the job has been suspended.

If the job is correctly suspended, we now have to test if it resumes work during the maintenance windows. Enter the IDLE_MAINTENANCE state via:

$ adb shell dumpsys deviceidle step

Check in the logcat output if the background job is being resumed.

Finally we have to check if jobs correctly resume their work when leaving doze mode. Let’s go back to the to the IDLE state by executing once more:

$ adb shell dumpsys deviceidle step

This should suspend the job again. Leave Doze mode by activating the device display. At this point everything should work normally again. Check in the logcat output if the job resumes.

Takeaway

In this step you’ve learned how to check if background activity is correctly suspended during doze mode. Make sure not to test only backgrounds jobs triggered via the JobScheduler, but also make sure that no other services are running during Doze idle mode.

During Doze idle mode, network access is suspended. This means apps cannot poll backend servers in the background. If your app requires messaging integration with a backend service, we strongly recommend that you use GCM if possible. This step demonstrates how GCM messaging interacts with Doze mode.

Visit the GCM tab in the sample app. The tab displays an URL:

To send test GCM messages to your device, open this URL in a browser on a different device than the one you use for testing:

Let’s see if notifications still work in Doze mode. Monitor your app via ADB in a command line terminal:

$ adb logcat -s "DozeSample"

Put the device into IDLE state again:

$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step

Send a GCM message via the website and observe the logcat output:

Now, repeat the same steps with a high priority GCM message. Enable this via the toggle in the web UI. How does it behave differently?

Takeaway

In this step you have seen that high priority GCM messages still work in Doze idle mode. All other GCM messages are postponed to the next maintenance window. If your app uses GCM, think about which messages should be high-priority.

Frequently Asked Questions

Standard AlarmManager alarms can be affected by Doze mode. In the next step we will test how alarms behave in doze mode. First, go to a command line terminal and start logcat:

$ adb logcat -s "DozeSample"

Now open the sample app on your device and go to the Alarm tab. Set an alarm. You should give yourself enough time to active the Doze idle mode.

Activate the Doze IDLE state on your device in a second command line window:

$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step

Wait for the alarm and check the logcat:

$ adb shell dumpsys deviceidle step

Now, repeat the same steps, but select enable alarm during idle mode via checkbox. How does the app behave differently?

Takeaway

Standard AlarmManager alarms (including setExact() and setWindow()) are deferred to the next maintenance window. If you need to set alarms that fire while in Doze, use setAndAllowWhileIdle() or setExactAndAllowWhileIdle().

Frequently Asked Questions

App Standby defers background network activity for apps with which the user has not recently interacted. The following steps explain how to check if background jobs work correctly with App Standby.

First we have to start a background job in the sample app. Open the Jobs tab in the sample app and press the START JOB button.

Open a command line terminal and monitor the same app via logcat:

$ adb logcat -s "DozeSample"

App Standby is only active if the device is unplugged. To simulate an unplugged device, open a second command line terminal and enter:

$ adb shell dumpsys battery unplug

Put the sample app into standby mode (the second command queries the standby state):

$ adb shell am set-inactive com.example.android.dozestandby true
$ adb shell am get-inactive com.example.android.dozestandby
Idle=true

See in the logcat output in the first command line if the job suspended.

Let’s put the sample app out of standby mode:

$ adb shell am set-inactive com.example.android.dozestandby false
$ adb shell am get-inactive com.example.android.dozestandby
Idle=false

The logcat output should show that the background job resumes its work.

Takeaway

App Standby affects apps only while the device is unplugged. Make sure the app recovers gracefully from standby mode. In particular, you should check if your app's background jobs continue to function as expected.

A common question is whether notifications still work in App Standby. Let’s test this with the sample app. Open a command line terminal and monitor the sample app via logcat:

$ adb logcat -s "DozeSample"

Visit the GCM tab in the sample app and open the displayed URL on a different device:

Now activate Standby mode for the sample app in new command line terminal:

$ adb shell am set-inactive com.example.android.dozestandby true
$ adb shell am get-inactive com.example.android.dozestandby
Idle=true

Send a GCM message with a normal priority to your device via the website and observe the logcat output in the first terminal window:

Now, repeat the same steps with a high priority GCM message (enable via the toggle in the web UI). Does it behave differently?

Takeaway

GCM messages work even if your app is in standby. Make sure to put important data into the message payload as your app might not have network access when the message arrives.

You know everything to successfully test your apps for Doze mode and App Standby compatibility.

What we've covered

Next Steps

Learn More