AlarmManager è un servizio di sistema Android che consente alle applicazioni di eseguire attività in un momento specificato, anche se l'applicazione non è in esecuzione o il dispositivo è in modalità sospensione. A differenza di JobScheduler o WorkManager, AlarmManager garantisce la precisione dell'attivazione, rendendolo indispensabile per sveglie, promemoria del calendario e attività critiche per quanto riguarda il tempo di esecuzione. Secondo Android Developers, 2026, a partire da Android 4.4, setRepeating si comporta come una ripetizione imprecisa e per sveglie precise è necessario setExact o setAlarmClock.
Punti chiave
AlarmManager è un servizio di sistema Android che fornisce un'API per pianificare attività con tempo di esecuzione preciso o approssimativo. Esiste dalla prima versione di Android e rimane l'unico modo affidabile per eseguire codice in un momento specificato, indipendentemente dallo stato dell'applicazione e del dispositivo.
Il principio di funzionamento è semplice: l'applicazione invia al sistema un PendingIntent con l'ora di attivazione. Quando arriva l'ora specificata, il sistema invia l'Intent a un BroadcastReceiver registrato o avvia un Service. Anche se il dispositivo era in modalità sospensione, WakeLock consente al processore di svegliarsi ed elaborare l'evento.
L'area di applicazione principale di AlarmManager sono le attività che richiedono una temporizzazione precisa: sveglie, promemoria del calendario, avvio di operazioni lunghe a un'ora specifica. Per le attività in cui la precisione non è critica (sincronizzazione giornaliera), Google raccomanda WorkManager o JobScheduler, poiché sono più efficienti dal punto di vista energetico.
AlarmManager riceve un PendingIntent e un'ora di attivazione dall'applicazione. Il sistema salva questa richiesta nel suo pianificatore interno e sveglia il processore all'ora specificata per consegnare l'Intent. Lo sviluppatore deve registrare in anticipo un BroadcastReceiver per gestire questo Intent.
AlarmManager supporta 4 tipi di sveglia: ELAPSED_REALTIME (tempo dall'avvio, non sveglia), RTC (tempo reale, non sveglia), ELAPSED_REALTIME_WAKEUP (tempo dall'avvio, sveglia il dispositivo) e RTC_WAKEUP (tempo reale, sveglia). Le versioni WAKEUP sono necessarie se l'attività deve essere eseguita anche quando il dispositivo dorme.
| Tipo | Tempo | Sveglia | Esempio |
|---|---|---|---|
| ELAPSED_REALTIME | dall'avvio | no | timer di attività |
| RTC | timestamp Unix | no | registrazione |
| ELAPSED_REALTIME_WAKEUP | dall'avvio | sì | attività periodica |
| RTC_WAKEUP | timestamp Unix | sì | sveglia |
A partire da Android 12 (API 31), l'uso di sveglie precise (setExact) richiede l'autorizzazione SCHEDULE_EXACT_ALARM. L'utente può revocarla tramite le impostazioni. Per le applicazioni che necessitano di una sveglia precisa con visualizzazione (ad esempio, app orologio), viene utilizzato USE_EXACT_ALARM, concesso durante l'installazione.
AlarmManager fornisce tre metodi principali per pianificare attività. La scelta del metodo determina la precisione dell'attivazione e l'impatto sul consumo energetico del dispositivo.
set — il metodo di base per un'attivazione unica imprecisa. Il sistema può spostare l'ora fino a pochi minuti per raggrupparla con altri eventi. Adatto per attività in cui la precisione non è critica: promemoria per aprire l'applicazione.
setRepeating — un metodo per ripetizioni periodiche. Da Android 4.4 (API 19), setRepeating è diventato impreciso — gli intervalli possono variare. Il sistema non garantisce più un periodo costante. Invece di setRepeating, si raccomanda di utilizzare setExact con riprogrammazione o WorkManager con PeriodicWorkRequest.
setExact — un metodo per un'attivazione unica precisa. Il sistema sveglia il dispositivo il più vicino possibile all'ora specificata. setAlarmClock è un caso speciale di setExact che mostra anche un'icona di sveglia nella barra di stato e ha la priorità più alta tra tutti i tipi di sveglia.
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// Sveglia unica precisa
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(
targetTime, pendingIntent
),
pendingIntent
)
Uno scenario tipico è la creazione di un promemoria quotidiano a un'ora specifica. A questo scopo viene utilizzato RTC_WAKEUP con setExact. Quando viene attivato, il BroadcastReceiver avvia una notifica o un Service. Dopo l'elaborazione, l'attività deve essere riprogrammata per il giorno successivo.
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("Promemoria")
.setContentText("È ora di completare l'attività")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
Per la ripetizione quotidiana, setExact viene utilizzato con il calcolo della prossima attivazione. Nell'Intent possono essere passati flag per identificare diversi tipi di promemoria. Assicurati che il BroadcastReceiver sia registrato in AndroidManifest.xml con la gestione dell'azione 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 è uno strumento potente ma energivoro. Ogni sveglia WAKEUP porta il dispositivo fuori dalla modalità sospensione, consumando batteria. Google raccomanda di minimizzare l'uso di sveglie precise e di preferire setExactAndAllowWhileIdle su Android 6+ per ridurre l'impatto su Doze Mode. Per attività periodiche senza requisiti di precisione, utilizza WorkManager con PeriodicWorkRequest, che non richiede di svegliare il dispositivo e non consuma batteria a ogni esecuzione.
Per testare AlarmManager, utilizza TestAlarmManager di Android Test Framework. Permette di emulare l'attivazione delle sveglie senza attendere il tempo reale. Robolectric fornisce ShadowAlarmManager, che intercetta le chiamate set, setExact e setRepeating, fornendo metodi per l'attivazione forzata e la verifica del numero di attività pianificate. Per i test unitari di BroadcastReceiver, utilizza Robolectric.getForegroundScheduler(). Sono disponibili anche test Espresso con IdlingResource che attende l'attivazione della sveglia nei test di integrazione.
Se la tua applicazione utilizza AlarmManager per attività periodiche che non richiedono una temporizzazione precisa, considera la migrazione a WorkManager. PeriodicWorkRequest con un intervallo minimo di 15 minuti sostituisce setRepeating, mentre WorkManager garantisce l'esecuzione dopo il riavvio, gestisce Doze Mode e non richiede l'autorizzazione SCHEDULE_EXACT_ALARM. Per attività critiche in termini di tempo (sveglia alle 7:00), AlarmManager rimane l'unica scelta corretta. La strategia ottimale è utilizzare AlarmManager solo per le sveglie con setAlarmClock e spostare tutte le altre attività in background su WorkManager.
Per attività periodiche senza requisiti di precisione, utilizza WorkManager con PeriodicWorkRequest. Per attività con temporizzazione precisa ma non critiche per l'attivazione in modalità sospensione — utilizza setExact senza WAKEUP. E solo per le sveglie con risveglio obbligatorio — utilizza setAlarmClock o RTC_WAKEUP.
È anche importante verificare l'autorizzazione SCHEDULE_EXACT_ALARM su Android 12+. Se l'autorizzazione non è concessa, setExact funzionerà come un set normale (impreciso). Utilizza AlarmManager.canScheduleExactAlarms() per verificare. Se manca l'autorizzazione, puoi invitare l'utente ad andare nelle impostazioni tramite Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).
Una caratteristica critica di AlarmManager — tutte le sveglie pianificate vengono reimpostate dopo il riavvio del dispositivo. Per ripristinarle, devi dichiarare un BroadcastReceiver che gestisca Intent.ACTION_BOOT_COMPLETED e riprogrammare tutte le sveglie attive nel metodo onReceive. Senza questo, l'utente perderà tutti i promemoria dopo aver spento e riacceso il telefono.
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)
}
}
}
}
In pratica, AlarmManager rimane la soluzione migliore per le applicazioni sveglia, calendari, promemoria di farmaci e qualsiasi attività in cui il tempo di esecuzione è critico per l'utente. Per tutti gli altri scenari di lavoro in background, sono preferibili WorkManager o JobScheduler.
Quando scegli tra AlarmManager e WorkManager, segui questa regola: se l'utente ha esplicitamente chiesto un promemoria alle 14:30 — utilizza AlarmManager con setAlarmClock. Se l'attività deve essere eseguita “circa una volta all'ora” — WorkManager con PeriodicWorkRequest sarà più efficiente dal punto di vista energetico e affidabile.
Domande frequenti
Entrambi i metodi garantiscono un'attivazione precisa, ma setAlarmClock mostra inoltre un'icona di sveglia nella barra di stato e informa il sistema che si tratta di una sveglia dell'utente. Su Android 6+, setAlarmClock ha immunità da Doze Mode, mentre setExact può essere ritardato.
Dopo un riavvio, tutte le sveglie pianificate vengono reimpostate. Per ripristinarle, devi registrare un BroadcastReceiver per l'azione BOOT_COMPLETED e riprogrammare tutte le attività in onReceive. Senza questo, nessuna sveglia si attiverà dopo l'accensione del dispositivo.
Dall'API 19, setRepeating è diventato impreciso — il sistema può spostare gli intervalli per risparmiare energia. Invece, utilizza setExact con riprogrammazione manuale o WorkManager con PeriodicWorkRequest, che offre un comportamento più prevedibile.
Per setExact, è richiesta l'autorizzazione SCHEDULE_EXACT_ALARM, che l'utente può concedere o revocare nelle impostazioni. Per setAlarmClock con visualizzazione dell'interfaccia dell'orologio, viene utilizzato USE_EXACT_ALARM, concesso automaticamente all'installazione dal negozio.
No, AlarmManager funziona sempre tramite PendingIntent. Può essere PendingIntent.getBroadcast per BroadcastReceiver, PendingIntent.getService per Service o PendingIntent.getActivity per Activity. Senza PendingIntent, il sistema non può consegnare l'evento all'applicazione.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche