Спящий режим приложения

Если ваше приложение предназначено для Android 11 (уровень API 30) или выше, и пользователь не взаимодействует с вашим приложением в течение нескольких месяцев, система переводит ваше приложение в состояние гибернации . Система оптимизирует пространство для хранения, а не производительность, и система защищает пользовательские данные. Такое поведение системы похоже на то, что происходит, когда пользователь принудительно останавливает ваше приложение вручную из настроек системы.

Эффекты спячки

Как показано в таблице 1, эффект гибернации зависит от целевой версии SDK вашего приложения, а также от устройства, на котором оно работает:

Таблица 1. Влияние спящего режима на ваше приложение
Целевая версия SDK Характеристики устройства Эффекты гибернации
Андроид 12 или выше Работает под управлением Android 12 или выше

Разрешения времени выполнения вашего приложения сбрасываются. Это действие имеет тот же эффект, как если бы пользователь просмотрел разрешение в настройках системы и изменил уровень доступа вашего приложения на «Запретить» .

Ваше приложение не может запускать задания или оповещения в фоновом режиме.

Ваше приложение не может получать push-уведомления, в том числе сообщения с высоким приоритетом, отправленные через Firebase Cloud Messaging .

Все файлы в кеше вашего приложения будут удалены.

Андроид 11 Работает на Android 11 Разрешения времени выполнения вашего приложения сбрасываются.
Андроид 11 Работает под управлением Android 6.0 (уровень API 23) до Android 10 (уровень API 29) включительно и работает на базе сервисов Google Play.

Разрешения времени выполнения вашего приложения сбрасываются.

Это поведение вступит в силу в декабре 2021 года. Узнайте больше в этой записи блога о том , как сделать автоматический сброс разрешений доступным для миллиардов других устройств .

Поведение системы, когда приложение выходит из спящего режима

Когда пользователь в следующий раз взаимодействует с вашим приложением, ваше приложение выходит из спящего режима и снова может создавать задания, оповещения и уведомления.

Однако система не делает для вашего приложения следующее:

  1. Повторно предоставьте разрешения времени выполнения вашего приложения.

    Пользователь должен повторно предоставить эти разрешения для вашего приложения.

  2. Перенесите все задания, оповещения и уведомления, которые были запланированы до того, как ваше приложение перешло в спящий режим.

    Чтобы упростить поддержку этого рабочего процесса, используйте WorkManager . Вы также можете добавить логику перепланирования в широковещательный приемник ACTION_BOOT_COMPLETED , который вызывается, когда ваше приложение выходит из спящего режима и после загрузки устройства.

Использование приложения

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

Примеры использования приложения

Когда активность в вашем приложении возобновляется, система рассматривает это событие как взаимодействие с пользователем. Таким образом, система продлевает время, прежде чем ваше приложение перейдет в спящий режим.

В Android 11 и более поздних версиях взаимодействием с пользователем также считаются следующие действия:

  • Пользователь взаимодействует с виджетом .
  • Пользователь взаимодействует с уведомлением, за исключением отклонения уведомления .

Следует отметить, что использование приложения в спящем режиме не требует явного взаимодействия с пользователем. Пока вызывается компонент пакета, это по-прежнему считается использованием приложения. Вот некоторые примеры этого:

  • Приложения, поставщик услуг или контента которых привязан к другому приложению на устройстве или в ОС. Например, редакторы методов ввода (IME) или менеджеры паролей.
  • Получатели широковещательной рассылки в пакете получают явную трансляцию из внешнего пакета.

Непримеры

Если ваше приложение демонстрирует только поведение, описанное в следующем списке, ваше приложение переходит в спящий режим через несколько месяцев:

Исключение системы из спящего режима

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

Приложения не отображаются в лаунчере
Любое приложение, у которого нет активного ярлыка на панели запуска.
Приложения рабочего профиля
Любое приложение, которое пользователь устанавливает в рабочий профиль . Обратите внимание: если то же приложение также находится в личном профиле, освобождением от налога освобождается только приложение рабочего профиля.
Контроллеры политик устройств
Приложения, которые контролируют локальные политики устройств и системные приложения на устройствах.
Привилегированные приложения оператора связи
Любое приложение, которое операторы мобильной связи предварительно загружают на устройства и считают необходимым для выполнения договорных обязательств по обслуживанию, например приложения голосовой почты или обслуживания клиентов.
3p-установщики приложений
Сторонние магазины приложений для автоматического обновления установленных приложений при необходимости.

Освобождение пользователя от режима гибернации

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

  • Обеспечьте семейную безопасность, периодически сообщая о местонахождении членов семьи.
  • Синхронизируйте данные между устройством и сервером вашего приложения.
  • Общайтесь с интеллектуальными устройствами, такими как телевизор.
  • Выполните сопряжение с сопутствующими устройствами, например с часами.

Чтобы запросить освобождение, выполните действия, описанные в следующих разделах.

Проверьте, отключил ли пользователь уже спящий режим для вашего приложения.

Чтобы проверить, отключил ли пользователь уже спящий режим для вашего приложения, используйте API getUnusedAppRestrictionsStatus() .

Дополнительные сведения о том, как использовать этот API в вашем приложении, см. в примере кода API на этой странице.

Попросите пользователя отключить спящий режим для вашего приложения.

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

  1. Отобразите пользовательский интерфейс, который объясняет пользователю, почему ему необходимо отключить спящий режим для вашего приложения.
  2. Вызовите API createManageUnusedAppRestrictionsIntent() , как показано в примере кода API . Этот API создает намерение, которое загружает экран информации о приложении в настройках. Отсюда пользователь может отключить спящий режим для вашего приложения.

    Важно, чтобы при отправке этого намерения вы вызывали startActivityForResult() , а не startActivity() .

    Как показано в таблице 2, расположение и название опции зависит от характеристик устройства, на котором установлено ваше приложение:

    Табл. 2. Параметр, отключающий спящий режим для вашего приложения
    Характеристики устройства Страница, на которой отображается опция Название опции, которую нужно отключить
    Работает под управлением Android 13 или выше Информация о приложении Приостановить активность приложения, если оно не используется
    Работает на Android 12 Информация о приложении Удалить разрешения и освободить место
    Работает на Android 11 Информация о приложении > Разрешения Удалить разрешения, если приложение не используется
    Работает под управлением Android 6.0–Android 10 включительно и работает на базе сервисов Google Play. Приложение Play > Меню > Play Protect > Разрешения для неиспользуемых приложений. Удалить разрешения, если приложение не используется

Пример кода API

В этом примере кода показано, как проверить, включен ли спящий режим для вашего приложения, и как правильно попросить пользователей отключить спящий режим для вашего приложения.

Котлин

val future: ListenableFuture<Int> =
    PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener({ onResult(future.get()) }, ContextCompat.getMainExecutor(context))

fun onResult(appRestrictionsStatus: Int) {
  when (appRestrictionsStatus) {
    // Couldn't fetch status. Check logs for details.
    ERROR -> { }

    // Restrictions don't apply to your app on this device.
    FEATURE_NOT_AVAILABLE -> { }

    // The user has disabled restrictions for your app.
    DISABLED -> { }

    // If the user doesn't start your app for a few months, the system will
    // place restrictions on it. See the API_* constants for details.
    API_30_BACKPORT, API_30, API_31 -> handleRestrictions(appRestrictionsStatus)
  }
}

fun handleRestrictions(appRestrictionsStatus: Int) {
  // If your app works primarily in the background, you can ask the user
  // to disable these restrictions. Check if you have already asked the
  // user to disable these restrictions. If not, you can show a message to
  // the user explaining why permission auto-reset or app hibernation should be
  // disabled. Then, redirect the user to the page in system settings where they
  // can disable the feature.
  val intent = IntentCompat.createManageUnusedAppRestrictionsIntent(context, packageName)

  // You must use startActivityForResult(), not startActivity(), even if
  // you don't use the result code returned in onActivityResult().
  startActivityForResult(intent, REQUEST_CODE)
}

API устаревшей платформы

Операционная система также включает API для взаимодействия с функцией гибернации. Однако API работает только на устройствах под управлением Android 11 или выше; API не поддерживает функции спящего режима, которые были перенесены в более ранние версии Android. Поэтому мы не рекомендуем использовать API.

Если вам необходимо временно продолжить использование API в целях совместимости, в следующем списке показано, как его использовать:

  • Чтобы проверить, отключен ли спящий режим для вашего приложения: isAutoRevokeWhitelisted()
  • Чтобы отправить пользователя на страницу настроек гибернации: создайте намерение, используя ACTION_APPLICATION_DETAILS_SETTINGS

Вручную вызвать режим гибернации

Чтобы проверить, как ваше приложение ведет себя после того, как система переводит его в состояние гибернации, выполните следующие действия:

  1. (Только для Android 12 и более поздних версий) Включите режим гибернации на вашем устройстве:

    adb shell device_config put app_hibernation app_hibernation_enabled true
    
  2. Установите время по умолчанию, в течение которого система ожидает перехода в спящий режим. Таким образом, вы можете восстановить его после тестирования:

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  3. Сократите время ожидания системы. В следующем примере система изменена таким образом, что ваше приложение переходит в спящий режим всего через одну секунду после прекращения взаимодействия с приложением:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  4. Дождитесь завершения всех трансляций во время загрузки на вашем тестовом устройстве, выполнив следующую команду:

    adb shell am wait-for-broadcast-idle
    

    Когда широковещательная рассылка завершена, эта команда возвращает сообщение: All broadcast queues are idle!

  5. Вызовите процесс гибернации приложения вручную:

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  6. (Только для Android 12 и более поздних версий) Подтвердите, что приложение находится в спящем режиме, одним из следующих способов:

    • Обратите внимание, что на тестовом устройстве теперь отображается уведомление, указывающее, что неиспользуемые приложения находятся в спящем режиме.
    • Выполните следующую команду:

      adb shell cmd app_hibernation get-state PACKAGE-NAME
      
  7. Восстановите время ожидания по умолчанию, прежде чем система переведет ваше приложение в спящий режим:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold