В Android 10 (уровень API 29) и более поздних версиях накладываются ограничения на запуск приложений , работающих в фоновом режиме. Эти ограничения помогают минимизировать помехи для пользователя и позволяют ему лучше контролировать то, что отображается на экране.
В этом руководстве рассматриваются уведомления как альтернатива запуску действий в фоновом режиме. Также перечислены конкретные случаи, когда это ограничение не применяется.
Вместо этого отображать уведомления
Практически во всех случаях приложениям в фоновом режиме приходится отображать уведомления, срочные для предоставления пользователю срочной информации, а не для непосредственного запуска какого-либо действия. К таким уведомлениям относятся уведомления о входящем телефонном звонке или срабатывании будильника.
Эта система оповещений и напоминаний на основе уведомлений обеспечивает пользователям ряд преимуществ:
- При использовании устройства пользователь видит всплывающее уведомление, на которое можно ответить. Пользователь сохраняет текущий контекст и контролирует содержимое экрана.
- Уведомления, привязанные ко времени, учитывают правила режима «Не беспокоить», установленные пользователем. Например, пользователи могут разрешать звонки только от определённых контактов или от повторяющихся абонентов при включённом режиме «Не беспокоить».
- Когда экран устройства выключен, полноэкранное намерение запускается немедленно.
- На экране настроек устройства пользователь может увидеть, какие приложения недавно отправляли уведомления, в том числе из определённых каналов. На этом экране пользователь может управлять своими настройками уведомлений.
Когда приложения могут начинать действия
Приложения, работающие на Android 10 или выше, могут запускать действия при выполнении одного или нескольких из следующих условий:
- Приложение имеет видимое окно, например, активность на переднем плане.
- Приложение имеет активность в заднем стеке приоритетной задачи.
Приложение имеет активность в стеке текущих задач на экране «Недавние» .
В приложении есть активность, которая началась совсем недавно.
Приложение недавно вызвало
finish()
для какой-либо задачи. Это применимо только в том случае, если на момент вызоваfinish()
приложение либо выполняло какую-либо задачу на переднем плане, либо находилось в стеке задач переднего плана.Приложение использует одну из следующих служб, привязанных к системе. Этим службам может потребоваться запуск пользовательского интерфейса.
-
AccessibilityService
-
AutofillService
-
CallRedirectionService
-
HostApduService
-
InCallService
-
TileService
(Не применимо в Android 14 (уровень API 34) и выше) -
VoiceInteractionService
-
VrListenerService
.
-
Приложение содержит службу, связанную с другим видимым приложением. Для успешного запуска фонового приложения приложение, связанное со службой, должно оставаться видимым.
Приложение получает уведомление
PendingIntent
от системы. В случае ожидающих намерений для служб и приёмников широковещательной рассылки приложение может начать выполнение действий в течение нескольких секунд после отправки ожидающего намерения.Приложение получает
PendingIntent
, отправленный из другого видимого приложения.Приложение получает системное оповещение, при котором ожидается запуск пользовательского интерфейса. Примеры включают
ACTION_NEW_OUTGOING_CALL
иSECRET_CODE_ACTION
. Приложение может начать выполнять действия в течение нескольких секунд после отправки оповещения.Приложение связывается с сопутствующим устройством через API
CompanionDeviceManager
. Этот API позволяет приложению запускать действия в ответ на действия пользователя на сопряженном устройстве.The app is a device policy controller running in device owner mode . Example use cases include fully managed enterprise devices as well as dedicated devices like digital signage and kiosks.
Пользователь предоставил приложению разрешение
SYSTEM_ALERT_WINDOW
.
При запуске действий из PendingIntents требуется согласие.
Чтобы избежать случайного запуска Activity на основе перечисленных условий , начиная с Android 14 существуют явные API, которые позволяют вам включить или отключить предоставление разрешений приложению на запуск Activity.
Приложения для Android 15 и более поздних версий по умолчанию больше не будут неявно предоставлять права на запуск фоновой активности (BAL) создаваемым ими PendingIntents
. Для этого требуется явное согласие. Ниже приведены варианты, зависящие от того, отправляет ли приложение PendingIntents
или создаёт их.
Отправителем PendingIntent
Приложения, ориентированные на Android 14 или выше, которые хотят запустить PendingIntent
должны
- fulfill the listed conditions and
- разрешить запуск фоновой активности на основе этих исключений
Такое согласие должно иметь место только в том случае, если разработчик приложения знает, что приложение собирается начать действие.
Чтобы согласиться, приложение должно передать пакет ActivityOptions
с setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
методу PendingIntent.send()
или аналогичным методам.
Создатель PendingIntent
Apps targeting Android 15 or higher that create a PendingIntent
must now explicitly opt in to allow background activity launch if they want those PendingIntents
to be startable under the listed conditions .
В большинстве случаев приложение, запускающее PendingIntent
, должно само дать согласие. Однако, если создающему приложению необходимо предоставить следующие привилегии:
-
PendingIntent
может быть запущен в любой момент, когда приложение, создающее его, становится видимым. -
PendingIntent
может быть запущен в любое время, если создающее его приложение имеет особые привилегии.
Чтобы согласиться, приложение должно передать пакет ActivityOptions
с setPendingIntentCreatorBackgroundActivityStartMode (ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
методу PendingIntent.getActivity()
или аналогичным методам.
Более подробную информацию можно найти в соответствующей справочной документации:
-
ActivityOptions.setPendingIntentBackgroundActivityStartMode
-
ActivityOptions.setPendingIntentCreatorBackgroundActivityStartMode
Строгий режим
Начиная с Android 16, разработчик приложения может включить строгий режим , чтобы получать уведомления, когда запуск активности заблокирован (или существует риск блокировки при повышении целевого SDK приложения).
Пример кода для включения с самого начала метода Application.onCreate()
вашего приложения, Activity или другого компонента приложения:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectBlockedBackgroundActivityLaunch()
.penaltyLog()
.build());
)
}
Более подробную информацию читайте в документации по строгому режиму .