Открыть сервис

AlarmManager

AlarmManager — это системный сервис операционной системы Android, предназначенный для выполнения определённого кода приложения в заданное время или через заданные промежутки времени, даже если приложение в данный момент не активно или устройство находится в спящем режиме. AlarmManager относится к классу системных служб планирования задач и предоставляет разработчикам механизм для запуска широковещательных приёмников (BroadcastReceiver) в указанные моменты.

История

Механизм AlarmManager был введён в Android API начиная с самой первой версии операционной системы (Android 1.0, 2008 год). Изначально он использовался для простых задач, таких как будильники, напоминания и периодические обновления данных. В более поздних версиях Android, особенно начиная с Android 6.0 (Marshmallow, 2015), в механизм работы AlarmManager были внесены существенные изменения, связанные с оптимизацией энергопотребления. В частности, был введён режим Doze, который ограничивает доступ к сетевым операциям и откладывает выполнение будильников в период бездействия устройства. В Android 8.0 (Oreo, 2017) были добавлены ограничения на фоновые службы, что также повлияло на работу AlarmManager. В Android 12 (2021) и более поздних версиях были введены дополнительные ограничения на точное планирование будильников, требующие специального разрешения от пользователя.

Принцип работы

AlarmManager работает на уровне ядра Android и взаимодействует с системным планировщиком, который управляет временем пробуждения устройства. Когда приложение регистрирует будильник, оно передаёт в AlarmManager следующие параметры:

  • Тип будильника — определяет, будет ли устройство пробуждаться из спящего режима.
  • Время срабатывания — момент времени (в миллисекундах с начала эпохи Unix) или интервал.
  • PendingIntentобъект, который будет выполнен при срабатывании будильника (обычно это Intent для BroadcastReceiver).

После регистрации AlarmManager сохраняет задачу во внутренней очереди. При наступлении указанного времени система отправляет указанный PendingIntent. Если устройство находилось в спящем режиме, оно может быть временно пробуждено (в зависимости от типа будильника). После обработки Intent устройство может снова перейти в спящий режим.

Типы будильников

AlarmManager поддерживает несколько типов будильников, которые различаются по поведению относительно спящего режима и времени:

ТипКонстантаПоведение
Точное время, пробуждаетRTC_WAKEUPПробуждает устройство из спящего режима в указанное время.
Точное время, не пробуждаетRTCСрабатывает в указанное время, но не пробуждает устройство (Intent будет доставлен после выхода из спящего режима).
Прошедшее время, пробуждаетELAPSED_REALTIME_WAKEUPПробуждает устройство через заданное количество миллисекунд с момента загрузки системы.
Прошедшее время, не пробуждаетELAPSED_REALTIMEСрабатывает через заданное количество миллисекунд с момента загрузки, но не пробуждает устройство.

Точные и неточные будильники

Начиная с Android 12, Google ввёл различие между точными и неточными будильниками. Точные будильники (setExact() и setAlarmClock()) гарантируют срабатывание в указанный момент времени с минимальной задержкой. Неточные будильники (set()) могут быть сгруппированы системой для экономии энергии. Для использования точных будильников приложение должно запросить разрешение SCHEDULE_EXACT_ALARM, которое пользователь может отозвать в настройках.

Применение

AlarmManager широко используется в Android-приложениях для следующих целей:

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

Ограничения и особенности

Режим Doze

Начиная с Android 6.0, в системе реализован режим энергосбережения Doze. Если устройство находится в состоянии покоя (неподвижно, экран выключен) в течение определённого времени, Doze ограничивает доступ к сетевым операциям и откладывает выполнение неточных будильников. Точные будильники, зарегистрированные через setAlarmClock(), выполняются в любом случае, так как они считаются приоритетными для пользователя. Обычные точные будильники (setExact()) могут быть отложены на несколько минут.

Фоновые ограничения в Android 8.0+

В Android 8.0 были введены ограничения на фоновые службы. Приложение, находящееся в фоне, не может запускать службы через startService(). Для выполнения фоновых задач рекомендуется использовать JobScheduler или WorkManager. AlarmManager остаётся актуальным для задач, требующих точного времени срабатывания, но его использование для длительных фоновых операций не рекомендуется.

Разрешения

Для использования точных будильников в Android 12+ приложение должно объявить разрешение SCHEDULE_EXACT_ALARM в манифесте и запросить его у пользователя. Пользователь может отозвать это разрешение в настройках. Приложения, не имеющие этого разрешения, могут использовать только неточные будильники.

Альтернативы

В современных версиях Android для фоновых задач рекомендуется использовать:

  • WorkManager — библиотека из Android Jetpack, которая обеспечивает выполнение фоновых задач с учётом состояния устройства и ограничений (например, наличие сети, заряд батареи). WorkManager использует AlarmManager как один из возможных механизмов выполнения, но предоставляет более высокоуровневый API.
  • JobScheduler — системный сервис, появившийся в Android 5.0 (Lollipop), который планирует задачи с учётом состояния устройства и позволяет группировать их для экономии энергии.
  • Handler — для простых задержек в рамках одного процесса, не требующих пробуждения устройства.

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

Типичный пример регистрации будильника в коде Android:

```java AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(this, MyReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

// Установка будильника на 10:00 утра Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 10); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0);

alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); ```

Интересные факты

  • AlarmManager является частью Android Open Source Project (AOSP) и доступен для всех производителей устройств.
  • В ранних версиях Android (до 4.4) setRepeating() позволял создавать периодические будильники с точным интервалом, но начиная с Android 4.4 (KitKat) все повторяющиеся будильники стали неточными — система группирует их для экономии энергии.
  • AlarmManager может быть использован злоумышленниками для пробуждения устройства и разрядки батареи, поэтому Google ввёл ограничения на его использование в фоновых приложениях.

Источники

  • Android Developers Documentation: AlarmManager
  • Android Developers Documentation: Scheduling repeating alarms
  • Android Developers Documentation: Optimize for Doze and App Standby
  • Android Developers Blog: Android 12 changes to exact alarm permission
  • Android Open Source Project (AOSP) — исходный код AlarmManager

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →