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

Автор: IT Sectr Опубликовано: 2026-03-28 Время чтения: 8 мин

AlarmManager — это системный сервис Android, который позволяет приложениям выполнять задачи в заданное время, даже если приложение не запущено или устройство находится в режиме сна. В отличие от JobScheduler или WorkManager, AlarmManager гарантирует точность срабатывания, что делает его незаменимым для будильников, календарных напоминаний и задач, критичных ко времени исполнения. По данным Android Developers, 2026, начиная с Android 4.4 setRepeating ведёт себя как неточный повтор, а для точных будильников требуется setExact или setAlarmClock.

Главное

  • AlarmManager — это системный сервис Android для выполнения задач в точное время, работающий даже в спящем режиме.
  • Типы будильников включают ELAPSED_REALTIME, RTC, ELAPSED_REALTIME_WAKEUP и RTC_WAKEUP — с пробуждением и без.
  • setExact гарантирует точное срабатывание на Android 4.4+, но расходует больше заряда батареи.
  • setAlarmClock — единственный метод, который система гарантированно выполняет вовремя на Android 6+.
  • Начиная с Android 12 для точных будильников требуется разрежение SCHEDULE_EXACT_ALARM.

Что такое AlarmManager?

AlarmManager — это системный сервис Android, предоставляющий API для планирования задач с точным или приблизительным временем выполнения. Он существует с первой версии Android и остаётся единственным надёжным способом выполнить код в заданный момент, независимо от состояния приложения и устройства.

Принцип работы прост: приложение отправляет системе PendingIntent с указанием времени срабатывания. Когда наступает нужный момент, система отправляет Intent зарегистрированному BroadcastReceiver или запускает Service. Даже если устройство находилось в спящем режиме, WakeLock позволяет процессору пробудиться и обработать событие.

Основная область применения AlarmManager — задачи, требующие точного времени: будильники, календарные напоминания, запуск длительных операций в определённый час. Для задач, где точность не критична (синхронизация раз в сутки), Google рекомендует WorkManager или JobScheduler, так как они более энергоэффективны.

Как работает AlarmManager?

AlarmManager получает от приложения PendingIntent и время срабатывания. Система сохраняет этот запрос в своём внутреннем планировщике и пробуждает процессор в указанное время для доставки Intent. Разработчик должен заранее зарегистрировать BroadcastReceiver, который обработает этот Intent.

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

AlarmManager поддерживает 4 типа будильников: ELAPSED_REALTIME (время с момента загрузки, не будит), RTC (реальное время, не будит), ELAPSED_REALTIME_WAKEUP (время с загрузки, будит устройство) и RTC_WAKEUP (реальное время, будит). WAKEUP-версии необходимы, если задача должна выполниться, даже когда устройство спит.

ТипВремяБудитПример
ELAPSED_REALTIMEс момента загрузкинеттаймер работы
RTCUnix timestampнетлогирование
ELAPSED_REALTIME_WAKEUPс момента загрузкидапериодическая задача
RTC_WAKEUPUnix timestampдабудильник

Разрешения и права

Начиная с Android 12 (API 31), для использования точных будильников (setExact) требуется разрешение SCHEDULE_EXACT_ALARM. Пользователь может отозвать его через настройки. Для приложений, которым нужен точный будильник с отображением (например, часы), используется USE_EXACT_ALARM, выдаваемое при установке.

Методы set, setRepeating и setExact

AlarmManager предоставляет три основных метода для планирования задач. Выбор метода определяет точность срабатывания и влияние на энергопотребление устройства.

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

setRepeating — метод для периодических повторений. Начиная с Android 4.4 (API 19) setRepeating стал неточным — интервалы могут варьироваться. Система больше не гарантирует постоянный период. Вместо setRepeating рекомендуется использовать setExact с повторным планированием или WorkManager с PeriodicWorkRequest.

setExact — метод для точного однократного срабатывания. Система пробуждает устройство в максимально близкое к указанному время. setAlarmClock — особый случай setExact, который также показывает значок будильника в статус-баре и имеет наивысший приоритет среди всех типов будильников.

kotlin
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

// Точный однократный будильник
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
    this, 0, intent,
    PendingIntent.FLAG_IMMUTABLE
)

alarmManager.setAlarmClock(
    AlarmManager.AlarmClockInfo(
        targetTime, pendingIntent
    ),
    pendingIntent
)

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

Типичный сценарий — создание ежедневного напоминания в определённое время. Для этого используется RTC_WAKEUP с setExact. При срабатывании BroadcastReceiver запускает уведомление или Service. После обработки необходимо перепланировать задачу на следующий день.

kotlin
class ReminderReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent?) {
        val notificationManager =
            context.getSystemService(Context.NOTIFICATION_SERVICE)
                as NotificationManager

        val notification = NotificationCompat.Builder(
            context, "reminder_channel"
        )
            .setContentTitle("Напоминание")
            .setContentText("Пора выполнить задачу")
            .setSmallIcon(R.drawable.ic_reminder)
            .build()

        notificationManager.notify(1001, notification)
    }
}

Для повторения на каждый день используется setExact с вычислением следующего срабатывания. В Intent можно передать флаги для идентификации разных типов напоминаний. Убедитесь, что BroadcastReceiver зарегистрирован в AndroidManifest.xml с обработкой действия WAKEUP.

kotlin
fun scheduleDailyReminder(context: Context, hour: Int, minute: Int) {
    val calendar = Calendar.getInstance().apply {
        set(Calendar.HOUR_OF_DAY, hour)
        set(Calendar.MINUTE, minute)
        set(Calendar.SECOND, 0)
        if (before(Calendar.getInstance())) {
            add(Calendar.DAY_OF_MONTH, 1)
        }
    }

    val alarmManager =
        context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

    alarmManager.setExactAndAllowWhileIdle(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        pendingIntent
    )
}

Оптимизация и рекомендации

AlarmManager — мощный, но энергозатратный инструмент. Каждый WAKEUP-будильник выводит устройство из спящего режима, что расходует заряд батареи. Google рекомендует минимизировать использование точных будильников и предпочитать setExactAndAllowWhileIdle на Android 6+ для снижения влияния на Doze Mode. Для периодических задач без требования к точности используйте WorkManager с PeriodicWorkRequest, который не требует пробуждения устройства и не расходует заряд батареи на каждый запуск.

Тестирование AlarmManager в Unit-тестах

Для тестирования AlarmManager используйте TestAlarmManager из Android Test Framework. Он позволяет эмулировать срабатывание будильника без ожидания реального времени. В Robolectric доступен ShadowAlarmManager, который перехватывает вызовы set, setExact и setRepeating, предоставляя методы для принудительного срабатывания и проверки количества запланированных задач. Для Unit-тестов BroadcastReceiver используйте Robolectric.getForegroundScheduler(). Также доступен Espresso-тест с IdlingResource, который ожидает срабатывания будильника в интеграционных тестах.

Миграция с AlarmManager на WorkManager

Если приложение использует AlarmManager для периодических задач, не требующих точного времени, рассмотрите миграцию на WorkManager. PeriodicWorkRequest с минимальным интервалом 15 минут заменяет setRepeating, при этом WorkManager гарантирует выполнение после перезагрузки, обрабатывает Doze Mode и не требует разрешения SCHEDULE_EXACT_ALARM. Для задач, критичных ко времени (будильник на 7 утра), AlarmManager остаётся единственным правильным выбором. Оптимальная стратегия — использовать AlarmManager только для будильников с setAlarmClock, а все остальные фоновые задачи перевести на WorkManager.

Для периодических задач без требования к точности используйте WorkManager с PeriodicWorkRequest. Для задач с точным временем, но не критичных к срабатыванию в спящем режиме — setExact без WAKEUP. И только для будильников с обязательным пробуждением — setAlarmClock или RTC_WAKEUP.

Также важно проверять наличие разрешения SCHEDULE_EXACT_ALARM на Android 12+. Если разрешение не выдано, setExact будет работать как обычный set (неточно). Используйте AlarmManager.canScheduleExactAlarms() для проверки. При отсутствии разрешения можно предложить пользователю перейти в настройки через Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).

Обработка BOOT_COMPLETED для восстановления будильников

Критически важная особенность AlarmManager — все запланированные будильники сбрасываются после перезагрузки устройства. Для их восстановления необходимо объявить BroadcastReceiver, обрабатывающий Intent.ACTION_BOOT_COMPLETED, и перепланировать все активные будильники в методе onReceive. Без этого пользователь потеряет все напоминания после выключения и включения телефона.

kotlin
class BootReceiver : BroadcastReceiver() {
    override fun onReceive(
        context: Context,
        intent: Intent
    ) {
        if (intent.action ==
            Intent.ACTION_BOOT_COMPLETED
        ) {
            val prefs =
                context.getSharedPreferences("alarms", 0)
            val savedTime =
                prefs.getLong("next_alarm", 0L)
            if (savedTime > System.currentTimeMillis()) {
                scheduleReminder(context, savedTime)
            }
        }
    }
}

На практике AlarmManager остаётся лучшим решением для приложений-будильников, календарей, напоминаний о приёме лекарств и любых задач, где время срабатывания критично для пользователя. Для всех остальных сценариев фоновой работы предпочтительны WorkManager или JobScheduler.

При выборе между AlarmManager и WorkManager руководствуйтесь правилом: если пользователь явно попросил напомнить в 14:30 — используйте AlarmManager с setAlarmClock. Если задача должна выполниться «примерно раз в час» — WorkManager с PeriodicWorkRequest будет энергоэффективнее и надёжнее.

Часто задаваемые вопросы

В чём разница между setExact и setAlarmClock?

Оба метода гарантируют точное срабатывание, но setAlarmClock дополнительно показывает значок будильника в статус-баре и информирует систему, что это будильник для пользователя. На Android 6+ setAlarmClock имеет иммунитет от Doze Mode, тогда как setExact может быть отложен.

Как AlarmManager ведёт себя после перезагрузки устройства?

После перезагрузки все запланированные будильники сбрасываются. Для восстановления необходимо зарегистрировать BroadcastReceiver на действие BOOT_COMPLETED и перепланировать все задачи в onReceive. Без этого ни один будильник не сработает после включения устройства.

Почему setRepeating не рекомендуется на Android 4.4+?

Начиная с API 19 setRepeating стал неточным — система может сдвигать интервалы для энергосбережения. Вместо этого используйте setExact с ручным перепланированием или WorkManager с PeriodicWorkRequest, который предоставляет более предсказуемое поведение.

Какое разрешение нужно для точных будильников на Android 12+?

Для setExact требуется разрешение SCHEDULE_EXACT_ALARM, которое пользователь может предоставить или отозвать в настройках. Для setAlarmClock с отображением в интерфейсе часов используется USE_EXACT_ALARM, выдаваемое автоматически при установке из магазина.

Можно ли использовать AlarmManager без PendingIntent?

Нет, AlarmManager всегда работает через PendingIntent. Это может быть PendingIntent.getBroadcast для BroadcastReceiver, PendingIntent.getService для Service или PendingIntent.getActivity для Activity. Без PendingIntent система не сможет доставить событие приложению.

Итоги

  • AlarmManager — системный сервис Android для выполнения задач в точное время с возможностью пробуждения устройства.
  • Четыре типа будильников — ELAPSED_REALTIME, RTC, ELAPSED_REALTIME_WAKEUP и RTC_WAKEUP — покрывают разные сценарии.
  • setExact и setAlarmClock — единственные методы для точного срабатывания на современных версиях Android.
  • setRepeating устарел на Android 4.4+ — используйте setExact с ручным перепланированием.
  • Разрешение SCHEDULE_EXACT_ALARM обязательно на Android 12+ для точных будильников.
  • WorkManager или JobScheduler предпочтительнее для неточных фоновых задач без требования ко времени.
  • Не забывайте обрабатывать BOOT_COMPLETED для восстановления будильников после перезагрузки устройства.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также