AlarmManager — је системски сервис Android-а који омогућава апликацијама да извршавају задатке у одређено време, чак и ако апликација није покренута или је уређај у режиму спавања. За разлику од JobScheduler-а или WorkManager-а, AlarmManager гарантује прецизно окидање, што га чини незаменљивим за аларме, календарске подсетнике и задатке критичне за време извршења. Према Android Developers, 2026, од Android 4.4 setRepeating понаша се као нетачно понављање, а за прецизне аларме потребан је setExact или setAlarmClock.
Главно
AlarmManager — је системски сервис Android-а који пружа API за планирање задатака са тачним или приближним временом извршења. Постоји од прве верзије Android-а и остаје једини поуздан начин да се код изврши у одређеном тренутку, независно од стања апликације и уређаја.
Принцип рада је једноставан: апликација шаље систему PendingIntent са навођењем времена окидања. Када дође тражени тренутак, систем шаље Intent регистрованом BroadcastReceiver-у или покреће Service. Чак и ако је уређај био у режиму спавања, WakeLock омогућава процессору да се пробуди и обради догађај.
Главна област примене AlarmManager-а — задаци који захтевају тачно време: аларми, календарски подсетници, покретање дуготрајних операција у одређено време. За задатке где прецизност није критична (синхронизација једном дневно), Google препоручује WorkManager или JobScheduler, јер су енергетски ефикаснији.
AlarmManager прима од апликације PendingIntent и време окидања. Систем чува овај захтев у свом унутрашњем планеру и буди процессор у одређено време да би испоручио Intent. Програмер мора унапред да региструје BroadcastReceiver који ће обрадити овај Intent.
AlarmManager подржава 4 врсте аларма: ELAPSED_REALTIME (време од покретања, не буди), RTC (реално време, не буди), ELAPSED_REALTIME_WAKEUP (време од покретања, буди уређај) и RTC_WAKEUP (реално време, буди). WAKEUP верзије су неопходне ако задатак мора да се изврши чак и када уређај спава.
| Врста | Време | Буди | Пример |
|---|---|---|---|
| ELAPSED_REALTIME | од покретања | не | тајмер рада |
| RTC | Unix timestamp | не | логовање |
| ELAPSED_REALTIME_WAKEUP | од покретања | да | периодични задатак |
| RTC_WAKEUP | Unix timestamp | да | аларм |
Од Android 12 (API 31), за коришћење прецизних аларма (setExact) потребна је дозвола SCHEDULE_EXACT_ALARM. Корисник може да је опозове у подешавањима. За апликације којима је потребан прецизан аларм са приказом (нпр. сат), користи се USE_EXACT_ALARM, која се додељује при инсталацији.
AlarmManager пружа три главне методе за планирање задатака. Избор методе одређује прецизност окидања и утицај на потрошњу енергије уређаја.
set — основна метода за једнократно нетачно окидање. Систем може да помери време до неколико минута ради груписања са другим догађајима. Погодна за задатке где прецизност није критична: подсетник да уђете у апликацију.
setRepeating — метода за периодична понављања. Од Android 4.4 (API 19) setRepeating је постао нетачан — интервали могу да варирају. Систем више не гарантује константан период. Уместо setRepeating препоручује се коришћење setExact са ручним препланирањем или WorkManager са PeriodicWorkRequest.
setExact — метода за прецизно једнократно окидање. Систем буди уређај у време што ближе наведеном. setAlarmClock — посебан случај setExact-а, који додатно приказује икону аларма у статусној траци и има највиши приоритет међу свим врстама аларма.
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
)
Типичан сценарио — креирање дневног подсетника у одређено време. За то се користи RTC_WAKEUP са setExact. При окидању, BroadcastReceiver покреће обавештење или Service. Након обраде, потребно је препланирати задатак за следећи дан.
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.
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-а користите TestAlarmManager из Android Test Framework-а. Он омогућава емулацију окидања аларма без чекања на реално време. У Robolectric-у је доступан ShadowAlarmManager, који пресреће позиве set, setExact и setRepeating, пружајући методе за принудно окидање и проверу броја планираних задатака. За јединичне тестове BroadcastReceiver-а користите Robolectric.getForegroundScheduler(). Такође је доступан Espresso тест са IdlingResource-ом који чека окидање аларма у интеграционим тестовима.
Ако апликација користи 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).
Критично важна карактеристика AlarmManager-а — сви планирани аларми се ресетују након поновног покретања уређаја. За њихово обнављање потребно је декларисати BroadcastReceiver који обрађује Intent.ACTION_BOOT_COMPLETED и препланирати све активне аларме у методи onReceive. Без тога, корисник ће изгубити све подсетнике након гашења и укључивања телефона.
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 биће енергетски ефикаснији и поузданији.
Често постављана питања
Обе методе гарантују прецизно окидање, али setAlarmClock додатно приказује икону аларма у статусној траци и информише систем да је ово аларм за корисника. На Android 6+ setAlarmClock има имунитет од Doze Mode-а, док setExact може бити одложен.
Након поновног покретања, сви планирани аларми се ресетују. За обнављање је потребно регистровати BroadcastReceiver за акцију BOOT_COMPLETED и препланирати све задатке у onReceive. Без тога, ниједан аларм неће радити након укључивања уређаја.
Од API 19 setRepeating је постао нетачан — систем може да помера интервале ради уштеде енергије. Уместо тога користите setExact са ручним препланирањем или WorkManager са PeriodicWorkRequest, који пружа предвидљивије понашање.
За setExact потребна је дозвола SCHEDULE_EXACT_ALARM, коју корисник може да одобри или опозове у подешавањима. За setAlarmClock са приказом у интерфејсу сата користи се USE_EXACT_ALARM, која се аутоматски додељује при инсталацији из продавнице.
Не, AlarmManager увек ради преко PendingIntent-а. То може бити PendingIntent.getBroadcast за BroadcastReceiver, PendingIntent.getService за Service или PendingIntent.getActivity за Activity. Без PendingIntent-а систем неће моћи да испоручи догађај апликацији.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође