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

Если ваше приложение ориентировано на 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 и более поздних версиях следующие действия также считаются взаимодействием с пользователем:

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

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

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

Непримеры

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

Системные исключения из режима гибернации

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

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

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

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

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

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

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

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

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

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

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

  1. Отобразите пользовательский интерфейс, который объяснит пользователю, почему ему необходимо отключить режим гибернации для вашего приложения.
  2. Вызовите API-функцию createManageUnusedAppRestrictionsIntent() , как показано в примере кода 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()
  • Чтобы перенаправить пользователя на страницу настроек режима гибернации: создайте 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