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

2

9

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.

Kasten answered 25/10, 2018 at 13:5 Comment(6)
What do you need your app to be doing? Playing content? Is there any background service going on or is it all about the user interface?Archambault
@YvetteColomb I want to display mostly static information (but maybe with a change or animation often enough to avoid burn-in)Kasten
@Kasten did you find any solution?Calandracalandria
@user3405331 No, unfortunately. Though, I did my initial research on Android 9, so it is possible that Android 10 has some way to accomplish this.Kasten
@Kasten If we grant WRITE_SECURE_SETTINGS permission through adb then we can edit device_idle_constants there must be some way out there but there is no proper documentationCalandracalandria
@KhalidLakhani Interesting idea! I had not seen that settings key before. I just found this: github.com/easz/doze-tweak which does help shed some light on how to use the setting, including a diagram of the state transitions.Kasten
M
1

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.

Malines answered 31/10, 2018 at 9:37 Comment(1)
This will only work when the phone is plugged in or docked, unfortunately. I have looked at this strategy already, but could not find a reasonable way for the Dream to run while the phone was not charging or docked. I played around with using adb shell dumpsys battery to mock the battery state as charging, but this is not a realistic solution. Also, Doze mode does not engage when the device is plugged into a power charger.Kasten
T
0

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.

Traditionalism answered 29/11, 2018 at 15:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.