AlarmManager — je systémová služba Androidu, která umožňuje aplikacím provádět úkoly v určený čas, i když aplikace není spuštěna nebo je zařízení v režimu spánku. Na rozdíl od JobScheduler nebo WorkManager, AlarmManager zaručuje přesnost spuštění, což ho činí nepostradatelným pro budíky, kalendářové připomínky a časově kritické úkoly. Podle Android Developers, 2026, od Androidu 4.4 se setRepeating chová jako nepřesné opakování a pro přesné budíky je vyžadován setExact nebo setAlarmClock.
Hlavní body
AlarmManager — je systémová služba Androidu poskytující API pro plánování úkolů s přesným nebo přibližným časem provedení. Existuje od první verze Androidu a zůstává jediným spolehlivým způsobem, jak spustit kód v určený okamžik, nezávisle na stavu aplikace a zařízení.
Princip fungování je jednoduchý: aplikace odešle systému PendingIntent s uvedením času spuštění. Když nastane požadovaný okamžik, systém odešle Intent registrovanému BroadcastReceiver nebo spustí Service. I když bylo zařízení v režimu spánku, WakeLock umožní procesoru probudit se a zpracovat událost.
Hlavní oblast použití AlarmManager — úkoly vyžadující přesný čas: budíky, kalendářové připomínky, spouštění dlouhodobých operací v určitou hodinu. Pro úkoly, kde přesnost není kritická (synchronizace jednou denně), Google doporučuje WorkManager nebo JobScheduler, protože jsou energeticky účinnější.
AlarmManager obdrží od aplikace PendingIntent a čas spuštění. Systém uloží tento požadavek do svého interního plánovače a v určený čas probudí procesor pro doručení Intent. Vývojář musí předem zaregistrovat BroadcastReceiver, který tento Intent zpracuje.
AlarmManager podporuje 4 typy budíků: ELAPSED_REALTIME (čas od spuštění, neprobouzí), RTC (reálný čas, neprobouzí), ELAPSED_REALTIME_WAKEUP (čas od spuštění, probouzí zařízení) a RTC_WAKEUP (reálný čas, probouzí). Verze WAKEUP jsou nezbytné, pokud má být úkol proveden, i když zařízení spí.
| Typ | Čas | Probouzí | Příklad |
|---|---|---|---|
| ELAPSED_REALTIME | od spuštění | ne | časovač provozu |
| RTC | Unix timestamp | ne | logování |
| ELAPSED_REALTIME_WAKEUP | od spuštění | ano | periodický úkol |
| RTC_WAKEUP | Unix timestamp | ano | budík |
Od Androidu 12 (API 31) je pro použití přesných budíků (setExact) vyžadováno oprávnění SCHEDULE_EXACT_ALARM. Uživatel jej může odvolat v nastavení. Pro aplikace, které potřebují přesný budík se zobrazením (např. hodiny), se používá USE_EXACT_ALARM, udělované při instalaci.
AlarmManager poskytuje tři hlavní metody pro plánování úkolů. Výběr metody určuje přesnost spuštění a dopad na spotřebu energie zařízení.
set — základní metoda pro jednorázové nepřesné spuštění. Systém může posunout čas o několik minut pro seskupení s jinými událostmi. Vhodná pro úkoly, kde přesnost není kritická: připomínka nutnosti vstoupit do aplikace.
setRepeating — metoda pro periodická opakování. Od Androidu 4.4 (API 19) se setRepeating stal nepřesným — intervaly se mohou lišit. Systém již nezaručuje konstantní periodu. Místo setRepeating se doporučuje používat setExact s ručním přeplánováním nebo WorkManager s PeriodicWorkRequest.
setExact — metoda pro přesné jednorázové spuštění. Systém probudí zařízení v čase co nejbližším uvedenému. setAlarmClock — zvláštní případ setExact, který také zobrazuje ikonu budíku ve stavovém řádku a má nejvyšší prioritu mezi všemi typy budíků.
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// Přesný jednorázový budík
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(
targetTime, pendingIntent
),
pendingIntent
)
Typický scénář — vytvoření denní připomínky v určitý čas. K tomu se používá RTC_WAKEUP s setExact. Při spuštění BroadcastReceiver spustí oznámení nebo Service. Po zpracování je nutné úkol přeplánovat na následující den.
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("Připomínka")
.setContentText("Je čas splnit úkol")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
Pro denní opakování se používá setExact s výpočtem dalšího spuštění. V Intent lze předat příznaky pro identifikaci různých typů připomínek. Ujistěte se, že BroadcastReceiver je zaregistrován v AndroidManifest.xml se zpracováním akce 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 — výkonný, ale energeticky náročný nástroj. Každý budík WAKEUP vyvede zařízení z režimu spánku, což spotřebovává baterii. Google doporučuje minimalizovat používání přesných budíků a upřednostňovat setExactAndAllowWhileIdle na Androidu 6+ pro snížení dopadu na Doze Mode. Pro periodické úkoly bez požadavku na přesnost používejte WorkManager s PeriodicWorkRequest, který nevyžaduje probuzení zařízení a nespotřebovává baterii při každém spuštění.
Pro testování AlarmManager používejte TestAlarmManager z Android Test Framework. Umožňuje simulovat spuštění budíku bez čekání na reálný čas. V Robolectric je k dispozici ShadowAlarmManager, který zachycuje volání set, setExact a setRepeating a poskytuje metody pro vynucené spuštění a kontrolu počtu naplánovaných úkolů. Pro jednotkové testy BroadcastReceiver používejte Robolectric.getForegroundScheduler(). K dispozici je také Espresso test s IdlingResource, který čeká na spuštění budíku v integračních testech.
Pokud aplikace používá AlarmManager pro periodické úkoly, které nevyžadují přesný čas, zvažte migraci na WorkManager. PeriodicWorkRequest s minimálním intervalem 15 minut nahrazuje setRepeating, přičemž WorkManager zaručuje provedení po restartu, zpracovává Doze Mode a nevyžaduje oprávnění SCHEDULE_EXACT_ALARM. Pro časově kritické úkoly (budík v 7 ráno) zůstává AlarmManager jedinou správnou volbou. Optimální strategie — používejte AlarmManager pouze pro budíky s setAlarmClock a všechny ostatní úkoly na pozadí převeďte na WorkManager.
Pro periodické úkoly bez požadavku na přesnost používejte WorkManager s PeriodicWorkRequest. Pro úkoly s přesným časem, ale nekritické pro spuštění v režimu spánku — setExact bez WAKEUP. A pouze pro budíky s povinným probuzením — setAlarmClock nebo RTC_WAKEUP.
Také je důležité kontrolovat přítomnost oprávnění SCHEDULE_EXACT_ALARM na Androidu 12+. Pokud oprávnění nebylo uděleno, setExact bude fungovat jako běžný set (nepřesně). Používejte AlarmManager.canScheduleExactAlarms() pro kontrolu. Při absenci oprávnění můžete uživateli navrhnout přechod do nastavení pomocí Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).
Kriticky důležitá vlastnost AlarmManager — všechny naplánované budíky se po restartu zařízení resetují. Pro jejich obnovení je nutné deklarovat BroadcastReceiver zpracovávající Intent.ACTION_BOOT_COMPLETED a přeplánovat všechny aktivní budíky v metodě onReceive. Bez toho uživatel ztratí všechny připomínky po vypnutí a zapnutí telefonu.
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)
}
}
}
}
V praxi AlarmManager zůstává nejlepším řešením pro aplikace budíků, kalendářů, připomínek užívání léků a všech úkolů, kde je čas spuštění kritický pro uživatele. Pro všechny ostatní scénáře práce na pozadí jsou preferovány WorkManager nebo JobScheduler.
Při výběru mezi AlarmManager a WorkManager se řiďte pravidlem: pokud uživatel výslovně požádal o připomínku ve 14:30 — použijte AlarmManager s setAlarmClock. Pokud má být úkol proveden „přibližně jednou za hodinu" — WorkManager s PeriodicWorkRequest bude energeticky účinnější a spolehlivější.
Často kladené otázky
Obě metody zaručují přesné spuštění, ale setAlarmClock navíc zobrazuje ikonu budíku ve stavovém řádku a informuje systém, že se jedná o budík pro uživatele. Na Androidu 6+ má setAlarmClock imunitu vůči Doze Mode, zatímco setExact může být zpožděn.
Po restartu se všechny naplánované budíky resetují. Pro obnovení je nutné zaregistrovat BroadcastReceiver pro akci BOOT_COMPLETED a přeplánovat všechny úkoly v onReceive. Bez toho žádný budík po zapnutí zařízení nefunguje.
Od API 19 se setRepeating stal nepřesným — systém může posouvat intervaly kvůli úspoře energie. Místo toho používejte setExact s ručním přeplánováním nebo WorkManager s PeriodicWorkRequest, který poskytuje předvídatelnější chování.
Pro setExact je vyžadováno oprávnění SCHEDULE_EXACT_ALARM, které může uživatel udělit nebo odvolat v nastavení. Pro setAlarmClock se zobrazením v rozhraní hodin se používá USE_EXACT_ALARM, udělované automaticky při instalaci z obchodu.
Ne, AlarmManager vždy pracuje přes PendingIntent. Může to být PendingIntent.getBroadcast pro BroadcastReceiver, PendingIntent.getService pro Service nebo PendingIntent.getActivity pro Activity. Bez PendingIntent systém nebude schopen doručit událost aplikaci.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také