Перевод приложений в спящий режим

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

Что происходит при гибернации

Как показано в таблице 1, последствия перехода в режим гибернации зависят от целевой версии SDK приложения, а также от устройства, на котором оно запущено.

Таблица 1. Что происходит с приложением в режиме гибернации
Целевая версия SDK Характеристики устройства Что происходит при заморозке
Android 12 или более поздней версии; ОС Android 12 или более поздней версии.

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

Приложение не может выполнять задачи или отправлять оповещения в фоновом режиме.

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

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

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

Динамические разрешения приложения будут сброшены.

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

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

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

Однако система не выполняет следующие действия:

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

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

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

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

Приложения

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

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

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

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

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

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

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

Что не является примером

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

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

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

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

Исключения для пользователей из режима гибернации

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

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

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

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

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

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

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

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

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

    При отправке этого намерения важно вызывать startActivityForResult(), а не startActivity().

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

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

Пример кода API

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

Kotlin

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 или более поздней версии и не поддерживает функции гибернации, которые были перенесены в более ранние версии 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