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

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

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

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

Таблица 1. Влияние режима гибернации на ваше приложение
Целевая версия SDK Характеристики устройства Эффекты гибернации
Android 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 Защита > Разрешения для неиспользуемых приложений Удалите разрешения, если приложение не используется

Пример кода 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 и более поздних версий; он не поддерживает функции гибернации, портированные на более ранние версии Android. Поэтому мы не рекомендуем использовать этот API.

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

  • Чтобы проверить, отключен ли режим гибернации для вашего приложения: isAutoRevokeWhitelisted()
  • Чтобы отправить пользователя на страницу настроек режима гибернации: создайте Intent с помощью 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