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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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