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-а у јединичним тестовима

За тестирање AlarmManager-а користите TestAlarmManager из Android Test Framework-а. Он омогућава емулацију окидања аларма без чекања на реално време. У Robolectric-у је доступан ShadowAlarmManager, који пресреће позиве set, setExact и setRepeating, пружајући методе за принудно окидање и проверу броја планираних задатака. За јединичне тестове 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. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође