Home » Android » How can I allow Android to Doze while my app is open and the screen is on?

How can I allow Android to Doze while my app is open and the screen is on?

Posted by: admin June 15, 2020 Leave a comment

Questions:

I am making an app that will run when the device is locked, via Activity#setShowWhenLocked(true). I do not want to prevent the device from entering a low-power state. I know that the system does this with Always-On Display, and the display has an associated power mode for that:

/frameworks/base/core/java/android/view/Display.java

286    /**
287     * Display state: The display is dozing in a low power state; it is still
288     * on but is optimized for showing system-provided content while the
289     * device is non-interactive.
290     *
291     * @see #getState
292     * @see android.os.PowerManager#isInteractive
293     */
294    public static final int STATE_DOZE = ViewProtoEnums.DISPLAY_STATE_DOZE; // 3
295
296    /**
297     * Display state: The display is dozing in a suspended low power state; it is still
298     * on but the CPU is not updating it. This may be used in one of two ways: to show
299     * static system-provided content while the device is non-interactive, or to allow
300     * a "Sidekick" compute resource to update the display. For this reason, the
301     * CPU must not control the display in this mode.
302     *
303     * @see #getState
304     * @see android.os.PowerManager#isInteractive
305     */
306    public static final int STATE_DOZE_SUSPEND = ViewProtoEnums.DISPLAY_STATE_DOZE_SUSPEND; // 4

There is also this section in /frameworks/base/core/java/android/os/PowerManagerInternal.java:

51     * Wakefulness: The device is dozing.  It is almost asleep but is allowing a special
52     * low-power "doze" dream to run which keeps the display on but lets the application
53     * processor be suspended.  It can be awoken by a call to wakeUp() which ends the dream.
54     * The device fully goes to sleep if the dream cannot be started or ends on its own.
55     */
56    public static final int WAKEFULNESS_DOZING = 3;

If possible, I would like to avoid using root to do this, but if all else fails I could manually control doze with root using these commands, but that sounds messy and I don’t want to mess up any other app’s dozing interactions.

Also, I’m only particularly concerned with Android Pie (9.0) and later.

Update:

I have also tried acquiring a DOZE_WAKE_LOCK, but it requires the system permission DEVICE_POWER. I tried to adb shell pm grant the permission to my app, but it is not a changeable permission type.

How to&Answers:

You could do this by DreamService which is a Screen Saver. You cannot do this by Activity. Activity prevent the device enter sleep mode.

Dreams are interactive screensavers launched when a charging device is
idle, or docked in a desk dock. Dreams provide another modality for
apps to express themselves, tailored for an exhibition/lean-back
experience.

Answer:

What you want is the ambient mode in android wear, which let an activity can show a drawable(usually some white lines with a black background) when device is slept. As far as I know, the code for phone device do not has this feature, because your activity must extends a class called WearableActivity and managed by an system app called Ambient. The wake lock DOZE_WAKE_LOCK you found is used in this Ambient app.

Answer:

Providing your not running a background task, or downloading something, if you app is playing video for example you can use Keep the screen on. This will allow the screen to remain on and retain brightness for the duration required for you app. You can clear it with a flag or leave it. It’s the equivalent of doze with the screen on, as it will allow the CPU to rest and stop running background tasks.

It doesn’t use the same power as wake locks, which utilise the CPU.

From the docs, you can use the flag FLAG_KEEP_SCREEN_ON in your java code:

public class MainActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  }
}

or use the attribute android:keepScreenOn in the xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true">
    ...
</RelativeLayout>

This doesn’t interfere with the Doze restrictions

which are in summary:

  • suspended network access
  • ignores wake locks.
  • limitation on alarms
  • not perform Wi-Fi scans
  • no sync adapters
  • no JobSchedulers