AlarmManager — egy Android rendszerszolgáltatás, amely lehetővé teszi az alkalmazások számára, hogy meghatározott időben feladatokat hajtsanak végre, még akkor is, ha az alkalmazás nem fut vagy a készülék alvó módban van. A JobScheduler-rel vagy WorkManager-rel ellentétben az AlarmManager garantálja a pontos indítást, ami nélkülözhetetlenné teszi az ébresztők, naptáremlékeztetők és időben kritikus feladatok számára. A Android Developers, 2026 szerint az Android 4.4-től kezdve a setRepeating pontatlan ismétlésként viselkedik, és a pontos ébresztőkhöz setExact vagy setAlarmClock szükséges.
Főbb pontok
AlarmManager — egy Android rendszerszolgáltatás, amely API-t biztosít feladatok ütemezéséhez pontos vagy hozzávetőleges végrehajtási idővel. Az Android első verziója óta létezik, és továbbra is az egyetlen megbízható módja a kód meghatározott pillanatban történő végrehajtásának, függetlenül az alkalmazás és a készülék állapotától.
A működési elv egyszerű: az alkalmazás elküldi a rendszernek egy PendingIntent-et az indítási idő megadásával. Amikor eljön a kívánt pillanat, a rendszer elküldi az Intent-et a regisztrált BroadcastReceiver-nek vagy elindít egy Service-t. Még ha a készülék alvó módban is volt, egy WakeLock lehetővé teszi a processzor számára, hogy felébredjen és feldolgozza az eseményt.
Az AlarmManager fő alkalmazási területe — pontos időt igénylő feladatok: ébresztők, naptáremlékeztetők, hosszú műveletek indítása meghatározott órában. Azokhoz a feladatokhoz, ahol a pontosság nem kritikus (napi egyszeri szinkronizálás), a Google a WorkManager-t vagy JobScheduler-t ajánlja, mivel ezek energiahatékonyabbak.
AlarmManager megkapja az alkalmazástól a PendingIntent-et és az indítási időt. A rendszer eltárolja ezt a kérést a belső ütemezőjében, és a megadott időpontban felébreszti a processzort az Intent kézbesítéséhez. A fejlesztőnek előre regisztrálnia kell egy BroadcastReceiver-t, amely feldolgozza ezt az Intent-et.
AlarmManager 4 ébresztőtípust támogat: ELAPSED_REALTIME (idő a rendszerindítástól, nem ébreszt), RTC (valós idő, nem ébreszt), ELAPSED_REALTIME_WAKEUP (idő a rendszerindítástól, ébreszti a készüléket) és RTC_WAKEUP (valós idő, ébreszt). A WAKEUP verziók akkor szükségesek, ha a feladatot akkor is végre kell hajtani, amikor a készülék alszik.
| Típus | Idő | Ébreszt | Példa |
|---|---|---|---|
| ELAPSED_REALTIME | rendszerindítástól | nem | munkaidő időzítő |
| RTC | Unix timestamp | nem | naplózás |
| ELAPSED_REALTIME_WAKEUP | rendszerindítástól | igen | időszakos feladat |
| RTC_WAKEUP | Unix timestamp | igen | ébresztő |
Android 12-től (API 31) kezdve a pontos ébresztők (setExact) használatához SCHEDULE_EXACT_ALARM engedély szükséges. A felhasználó visszavonhatja azt a beállításokban. Azokhoz az alkalmazásokhoz, amelyek pontos ébresztőt igényelnek kijelzéssel (pl. óra), a USE_EXACT_ALARM használatos, amelyet a telepítéskor adnak meg.
AlarmManager három fő metódust biztosít a feladatok ütemezéséhez. A metódus kiválasztása meghatározza az indítás pontosságát és a készülék energiafogyasztására gyakorolt hatást.
set — az alap metódus egyszeri pontatlan indításhoz. A rendszer néhány perccel eltolhatja az időt más eseményekkel való csoportosítás céljából. Alkalmas olyan feladatokhoz, ahol a pontosság nem kritikus: emlékeztető az alkalmazásba való belépésre.
setRepeating — a metódus időszakos ismétlésekhez. Android 4.4-től (API 19) kezdve a setRepeating pontatlanná vált — az intervallumok változhatnak. A rendszer már nem garantál állandó időszakot. A setRepeating helyett a setExact használata ajánlott kézi újraütemezéssel vagy WorkManager a PeriodicWorkRequest-tel.
setExact — a metódus pontos egyszeri indításhoz. A rendszer a lehető legközelebbi időpontban ébreszti fel a készüléket a megadotthoz. setAlarmClock — a setExact speciális esete, amely egy ébresztő ikont is megjelenít az állapotsorban, és a legmagasabb prioritással rendelkezik az összes ébresztőtípus között.
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// Pontos egyszeri ébresztő
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(
targetTime, pendingIntent
),
pendingIntent
)
Tipikus forgatókönyv — napi emlékeztető létrehozása egy meghatározott időpontban. Ehhez RTC_WAKEUP-ot használnak setExact-tal. Az indításkor a BroadcastReceiver elindít egy értesítést vagy Service-t. A feldolgozás után a feladatot át kell ütemezni a következő napra.
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("Emlékeztető")
.setContentText("Itt az ideje a feladat végrehajtásának")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
A napi ismétléshez setExact-et használnak a következő indítás kiszámításával. Az Intent-ben zászlók küldhetők a különböző emlékeztetőtípusok azonosításához. Győződjön meg róla, hogy a BroadcastReceiver regisztrálva van az AndroidManifest.xml-ben a WAKEUP művelet feldolgozásával.
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 — egy hatékony, de energiaigényes eszköz. Minden WAKEUP ébresztő kiveszi a készüléket az alvó módból, ami akkumulátort fogyaszt. A Google azt ajánlja, hogy minimalizálja a pontos ébresztők használatát, és részesítse előnyben a setExactAndAllowWhileIdle-t Android 6+-on a Doze Mode-ra gyakorolt hatás csökkentése érdekében. Pontosságot nem igénylő időszakos feladatokhoz használja a WorkManager-t PeriodicWorkRequest-tel, amely nem igényli a készülék felébresztését és nem fogyaszt akkumulátort minden egyes végrehajtáskor.
Az AlarmManager teszteléséhez használja a TestAlarmManager-t az Android Test Framework-ből. Ez lehetővé teszi az ébresztő indításának szimulálását anélkül, hogy a valós időre kellene várni. A Robolectric-ben elérhető a ShadowAlarmManager, amely elfogja a set, setExact és setRepeating hívásokat, és metódusokat biztosít a kényszerített indításhoz és az ütemezett feladatok számának ellenőrzéséhez. A BroadcastReceiver egységtesztjeihez használja a Robolectric.getForegroundScheduler()-t. Szintén elérhető egy Espresso teszt IdlingResource-val, amely az ébresztő indítására vár az integrációs tesztekben.
Ha az alkalmazás AlarmManager-t használ olyan időszakos feladatokhoz, amelyek nem igényelnek pontos időt, fontolja meg a migrációt WorkManager-re. A minimális 15 perces intervallumú PeriodicWorkRequest helyettesíti a setRepeating-et, miközben a WorkManager garantálja a végrehajtást újraindítás után, kezeli a Doze Mode-ot, és nem igényel SCHEDULE_EXACT_ALARM engedélyt. Az időben kritikus feladatokhoz (ébresztő reggel 7-kor) az AlarmManager továbbra is az egyetlen helyes választás. Az optimális stratégia — használja az AlarmManager-t csak a setAlarmClock-kal rendelkező ébresztőkhöz, és helyezze át az összes többi háttérfeladatot a WorkManager-re.
Pontosságot nem igénylő időszakos feladatokhoz használja a WorkManager-t PeriodicWorkRequest-tel. Pontos időt igénylő, de alvó módban nem kritikus feladatokhoz — setExact WAKEUP nélkül. És csak a kötelező ébresztéssel rendelkező ébresztőkhöz — setAlarmClock vagy RTC_WAKEUP.
Szintén fontos ellenőrizni a SCHEDULE_EXACT_ALARM engedély meglétét Android 12+-on. Ha az engedély nincs megadva, a setExact úgy fog működni, mint egy sima set (pontatlanul). Használja az AlarmManager.canScheduleExactAlarms()-t az ellenőrzéshez. Az engedély hiányában javasolhatja a felhasználónak, hogy lépjen a beállításokba az Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM) segítségével.
Az AlarmManager kritikus fontosságú jellemzője — az összes ütemezett ébresztő visszaállítódik a készülék újraindítása után. Helyreállításukhoz deklarálni kell egy BroadcastReceiver-t, amely feldolgozza az Intent.ACTION_BOOT_COMPLETED-et, és újra kell ütemezni az összes aktív ébresztőt az onReceive metódusban. Enélkül a felhasználó elveszíti az összes emlékeztetőjét a telefon kikapcsolása és bekapcsolása után.
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)
}
}
}
}
A gyakorlatban az AlarmManager továbbra is a legjobb megoldás az ébresztőalkalmazások, naptárak, gyógyszerbevételi emlékeztetők és minden olyan feladat számára, ahol az indítás időpontja kritikus a felhasználó számára. Az összes többi háttérmunka-forgatókönyvhöz a WorkManager vagy JobScheduler előnyösebb.
Amikor az AlarmManager és a WorkManager között választ, kövesse a szabályt: ha a felhasználó kifejezetten emlékeztetőt kért 14:30-ra — használja az AlarmManager-t setAlarmClock-kal. Ha a feladatnak „körülbelül óránként egyszer" kell végrehajtódnia — a WorkManager PeriodicWorkRequest-tel energiahatékonyabb és megbízhatóbb lesz.
Gyakran ismételt kérdések
Mindkét metódus garantálja a pontos indítást, de a setAlarmClock emellett megjelenít egy ébresztő ikont az állapotsorban, és tájékoztatja a rendszert, hogy ez egy ébresztő a felhasználó számára. Android 6+-on a setAlarmClock immunis a Doze Mode-dal szemben, míg a setExact késleltethető.
Az újraindítás után az összes ütemezett ébresztő visszaállítódik. A helyreállításhoz regisztrálni kell egy BroadcastReceiver-t a BOOT_COMPLETED művelethez, és újra kell ütemezni az összes feladatot az onReceive-ben. Enélkül egyetlen ébresztő sem fog működni a készülék bekapcsolása után.
Az API 19-től kezdve a setRepeating pontatlanná vált — a rendszer eltolhatja az intervallumokat az energiatakarékosság érdekében. Ehelyett használja a setExact-ot kézi újraütemezéssel vagy a WorkManager-t PeriodicWorkRequest-tel, amely kiszámíthatóbb viselkedést biztosít.
A setExact-hez SCHEDULE_EXACT_ALARM engedély szükséges, amelyet a felhasználó megadhat vagy visszavonhat a beállításokban. Az óra felületén megjelenő setAlarmClock-hoz a USE_EXACT_ALARM használatos, amely automatikusan kiadásra kerül a boltból történő telepítéskor.
Nem, az AlarmManager mindig PendingIntent-en keresztül működik. Ez lehet PendingIntent.getBroadcast a BroadcastReceiver-hez, PendingIntent.getService a Service-hez vagy PendingIntent.getActivity az Activity-hez. PendingIntent nélkül a rendszer nem tudja kézbesíteni az eseményt az alkalmazásnak.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is