AlarmManager — este un serviciu de sistem Android care permite aplicațiilor să execute sarcini la un moment dat, chiar dacă aplicația nu rulează sau dispozitivul este în modul de repaus. Spre deosebire de JobScheduler sau WorkManager, AlarmManager garantează precizia declanșării, ceea ce îl face indispensabil pentru alarme, mementouri calendaristice și sarcini critice din punct de vedere temporal. Conform Android Developers, 2026, începând cu Android 4.4, setRepeating se comportă ca o repetare imprecisă, iar pentru alarme precise este necesar setExact sau setAlarmClock.
Principalele puncte
AlarmManager — este un serviciu de sistem Android care oferă API pentru planificarea sarcinilor cu timp de execuție precis sau aproximativ. Există de la prima versiune de Android și rămâne singura modalitate fiabilă de a executa cod la un moment dat, indiferent de starea aplicației și a dispozitivului.
Principiul de funcționare este simplu: aplicația trimite sistemului un PendingIntent cu specificarea timpului de declanșare. Când momentul dorit sosește, sistemul trimite Intent către BroadcastReceiver înregistrat sau pornește un Service. Chiar dacă dispozitivul era în modul de repaus, WakeLock permite procesorului să se trezească și să proceseze evenimentul.
Principalul domeniu de aplicare al AlarmManager — sarcini care necesită timp precis: alarme, mementouri calendaristice, pornirea operațiunilor lungi la o anumită oră. Pentru sarcini unde precizia nu este critică (sincronizare o dată pe zi), Google recomandă WorkManager sau JobScheduler, deoarece sunt mai eficiente energetic.
AlarmManager primește de la aplicație un PendingIntent și timpul de declanșare. Sistemul salvează această cerere în planificatorul său intern și trezește procesorul la momentul specificat pentru a livra Intent-ul. Dezvoltatorul trebuie să înregistreze în prealabil un BroadcastReceiver care va procesa acest Intent.
AlarmManager suportă 4 tipuri de alarme: ELAPSED_REALTIME (timp de la pornire, nu trezește), RTC (timp real, nu trezește), ELAPSED_REALTIME_WAKEUP (timp de la pornire, trezește dispozitivul) și RTC_WAKEUP (timp real, trezește). Versiunile WAKEUP sunt necesare dacă sarcina trebuie executată chiar și când dispozitivul doarme.
| Tip | Timp | Trezește | Exemplu |
|---|---|---|---|
| ELAPSED_REALTIME | de la pornire | nu | timer de funcționare |
| RTC | Unix timestamp | nu | jurnalizare |
| ELAPSED_REALTIME_WAKEUP | de la pornire | da | sarcină periodică |
| RTC_WAKEUP | Unix timestamp | da | alarmă |
Începând cu Android 12 (API 31), pentru utilizarea alarmelor precise (setExact) este necesară permisiunea SCHEDULE_EXACT_ALARM. Utilizatorul o poate retrage din setări. Pentru aplicațiile care necesită o alarmă precisă cu afișare (de exemplu, ceas), se utilizează USE_EXACT_ALARM, acordată la instalare.
AlarmManager oferă trei metode principale pentru planificarea sarcinilor. Alegerea metodei determină precizia declanșării și impactul asupra consumului de energie al dispozitivului.
set — metoda de bază pentru declanșarea unică imprecisă. Sistemul poate deplasa timpul cu câteva minute pentru grupare cu alte evenimente. Potrivită pentru sarcini unde precizia nu este critică: un memento de a intra în aplicație.
setRepeating — metoda pentru repetări periodice. Începând cu Android 4.4 (API 19), setRepeating a devenit imprecis — intervalele pot varia. Sistemul nu mai garantează o perioadă constantă. În loc de setRepeating, se recomandă utilizarea setExact cu replanificare manuală sau WorkManager cu PeriodicWorkRequest.
setExact — metoda pentru declanșarea unică precisă. Sistemul trezește dispozitivul la momentul cât mai apropiat de cel specificat. setAlarmClock — un caz special al setExact, care afișează suplimentar o pictogramă de alarmă în bara de stare și are cea mai mare prioritate dintre toate tipurile de alarme.
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// Alarmă precisă unică
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(
targetTime, pendingIntent
),
pendingIntent
)
Scenariul tipic — crearea unui memento zilnic la o anumită oră. Pentru aceasta se utilizează RTC_WAKEUP cu setExact. La declanșare, BroadcastReceiver pornește o notificare sau un Service. După procesare, sarcina trebuie replanificată pentru ziua următoare.
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("Memento")
.setContentText("Este timpul să executați sarcina")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
Pentru repetarea zilnică se utilizează setExact cu calcularea următoarei declanșări. În Intent pot fi transmise flaguri pentru identificarea diferitelor tipuri de mementouri. Asigurați-vă că BroadcastReceiver este înregistrat în AndroidManifest.xml cu procesarea acțiunii 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 — un instrument puternic, dar consumator de energie. Fiecare alarmă WAKEUP scoate dispozitivul din modul de repaus, ceea ce consumă bateria. Google recomandă minimizarea utilizării alarmelor precise și preferarea setExactAndAllowWhileIdle pe Android 6+ pentru a reduce impactul asupra Doze Mode. Pentru sarcini periodice fără cerință de precizie, utilizați WorkManager cu PeriodicWorkRequest, care nu necesită trezirea dispozitivului și nu consumă baterie la fiecare execuție.
Pentru testarea AlarmManager utilizați TestAlarmManager din Android Test Framework. Acesta permite simularea declanșării alarmei fără a aștepta timpul real. În Robolectric este disponibil ShadowAlarmManager, care interceptează apelurile set, setExact și setRepeating, oferind metode pentru declanșarea forțată și verificarea numărului de sarcini planificate. Pentru testele unitare ale BroadcastReceiver, utilizați Robolectric.getForegroundScheduler(). De asemenea, este disponibil un test Espresso cu IdlingResource care așteaptă declanșarea alarmei în testele de integrare.
Dacă aplicația utilizează AlarmManager pentru sarcini periodice care nu necesită timp precis, luați în considerare migrarea la WorkManager. PeriodicWorkRequest cu un interval minim de 15 minute înlocuiește setRepeating, iar WorkManager garantează execuția după repornire, gestionează Doze Mode și nu necesită permisiunea SCHEDULE_EXACT_ALARM. Pentru sarcini critice temporal (alarma la 7 dimineața), AlarmManager rămâne singura alegere corectă. Strategia optimă — utilizați AlarmManager doar pentru alarme cu setAlarmClock, iar toate celelalte sarcini de fundal transferați-le pe WorkManager.
Pentru sarcini periodice fără cerință de precizie utilizați WorkManager cu PeriodicWorkRequest. Pentru sarcini cu timp precis, dar necritice la declanșarea în modul de repaus — setExact fără WAKEUP. Și doar pentru alarme cu trezire obligatorie — setAlarmClock sau RTC_WAKEUP.
De asemenea, este important să verificați prezența permisiunii SCHEDULE_EXACT_ALARM pe Android 12+. Dacă permisiunea nu a fost acordată, setExact va funcționa ca un set obișnuit (imprecis). Utilizați AlarmManager.canScheduleExactAlarms() pentru verificare. În lipsa permisiunii, puteți sugera utilizatorului să navigheze la setări prin Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).
O caracteristică critic importantă a AlarmManager — toate alarmele planificate sunt resetate după repornirea dispozitivului. Pentru restaurarea lor, trebuie să declarați un BroadcastReceiver care procesează Intent.ACTION_BOOT_COMPLETED și să replanificați toate alarmele active în metoda onReceive. Fără aceasta, utilizatorul va pierde toate mementourile după oprirea și pornirea telefonului.
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)
}
}
}
}
În practică, AlarmManager rămâne cea mai bună soluție pentru aplicațiile de alarmă, calendare, mementouri pentru administrarea medicamentelor și orice sarcini unde momentul declanșării este critic pentru utilizator. Pentru toate celelalte scenarii de lucru în fundal, sunt preferați WorkManager sau JobScheduler.
Atunci când alegeți între AlarmManager și WorkManager, ghidați-vă după regula: dacă utilizatorul a cerut explicit un memento la 14:30 — utilizați AlarmManager cu setAlarmClock. Dacă sarcina trebuie executată „aproximativ o dată pe oră" — WorkManager cu PeriodicWorkRequest va fi mai eficient energetic și mai fiabil.
Întrebări frecvente
Ambele metode garantează declanșarea precisă, dar setAlarmClock afișează suplimentar o pictogramă de alarmă în bara de stare și informează sistemul că aceasta este o alarmă pentru utilizator. Pe Android 6+, setAlarmClock are imunitate față de Doze Mode, în timp ce setExact poate fi întârziat.
După repornire, toate alarmele planificate sunt resetate. Pentru restaurare, este necesar să înregistrați un BroadcastReceiver pentru acțiunea BOOT_COMPLETED și să replanificați toate sarcinile în onReceive. Fără aceasta, nicio alarmă nu va funcționa după pornirea dispozitivului.
Începând cu API 19, setRepeating a devenit imprecis — sistemul poate deplasa intervalele pentru economisirea energiei. În locul acestuia, utilizați setExact cu replanificare manuală sau WorkManager cu PeriodicWorkRequest, care oferă un comportament mai previzibil.
Pentru setExact este necesară permisiunea SCHEDULE_EXACT_ALARM, pe care utilizatorul o poate acorda sau retrage în setări. Pentru setAlarmClock cu afișare în interfața ceasului, se utilizează USE_EXACT_ALARM, acordată automat la instalarea din magazin.
Nu, AlarmManager funcționează întotdeauna prin PendingIntent. Acesta poate fi PendingIntent.getBroadcast pentru BroadcastReceiver, PendingIntent.getService pentru Service sau PendingIntent.getActivity pentru Activity. Fără PendingIntent, sistemul nu va putea livra evenimentul aplicației.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și