Как я могу разрешить Android дремать, пока мое приложение открыто и экран включен?

Я делаю приложение, которое будет работать, когда устройство заблокировано, через Activity#setShowWhenLocked(true), Я не хочу, чтобы устройство не переходило в режим низкого энергопотребления. Я знаю, что система делает это с Always-On Displayи дисплей имеет связанный режим питания для этого:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/view/Display.java#294

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

Этот раздел также находится в http://androidxref.com/9.0.0_r3/xref/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;

Если возможно, я бы хотел избежать использования root для этого, но если все остальное не удалось, я мог бы вручную управлять дозой с помощью root с помощью этих команд, но это звучит беспорядочно, и я не хочу испортить дремлющие взаимодействия других приложений.

Кроме того, я особенно обеспокоен Android Pie (9.0)

Обновить:

Я также пытался приобрести DOZE_WAKE_LOCK, но это требует разрешения системы DEVICE_POWER, Я пытался adb shell pm grant разрешение на мое приложение, но это не изменяемый тип разрешения.

3 ответа

Вы можете сделать это с помощью DreamService, который является хранителем экрана. Вы не можете сделать это по Деятельности. Активность мешает устройству переходить в спящий режим.

Dreams - это интерактивные заставки, которые запускаются, когда зарядное устройство находится в режиме ожидания, или закреплены в настольной док-станции. Dreams - это еще один способ, позволяющий приложениям самовыражаться, адаптированный для проведения выставок и отдыха.

То, что вы хотите, это режим окружающей среды при износе андроида, который позволяет деятельности отображать рисование (обычно несколько белых линий на черном фоне), когда устройство спит. Насколько я знаю, код для устройства телефона не имеет этой функции, потому что ваша деятельность должна расширять класс WearableActivity и управляться системным приложением Ambient. Замок DOZE_WAKE_LOCK Вы нашли, используется в этом приложении Ambient.

Если вы не запускаете фоновую задачу или не загружаете что-то, например, если ваше приложение воспроизводит видео, вы можете использовать функцию "Сохранить экран". Это позволит экрану оставаться включенным и сохранять яркость в течение времени, необходимого для вашего приложения. Вы можете очистить его с флагом или оставить его. Это эквивалент дремоты с включенным экраном, поскольку он позволяет процессору отдыхать и останавливать выполнение фоновых задач.

Он не использует ту же мощность, что и пробужденные блокировки, которые используют процессор.

Из документов вы можете использовать флаг FLAG_KEEP_SCREEN_ON в своем коде Java:

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);
  }
}

или используйте атрибут android:keepScreenOn в 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>

Это не мешает дозовым ограничениям

которые в итоге:

  • доступ к сети приостановлен
  • игнорирует следы
  • ограничение по сигналам тревоги
  • не выполнять сканирование Wi-Fi
  • нет адаптеров синхронизации
  • нет JobSchedulers
Другие вопросы по тегам