AlarmManager est un service système Android qui permet aux applications d'exécuter des tâches à un moment donné, même si l'application ne tourne pas ou si l'appareil est en mode veille. Contrairement à JobScheduler ou WorkManager, AlarmManager garantit la précision du déclenchement, ce qui le rend indispensable pour les alarmes, les rappels de calendrier et les tâches critiques en termes de temps d'exécution. Selon Android Developers, 2026, à partir d'Android 4.4, setRepeating se comporte comme une répétition inexacte, et les alarmes précises nécessitent setExact ou setAlarmClock.
Points clés
AlarmManager est un service système Android qui fournit une API pour planifier des tâches avec un temps d'exécution précis ou approximatif. Il existe depuis la première version d'Android et reste le seul moyen fiable d'exécuter du code à un moment donné, quel que soit l'état de l'application et de l'appareil.
Le principe de fonctionnement est simple : l'application envoie au système un PendingIntent avec l'heure de déclenchement. Lorsque l'heure spécifiée arrive, le système envoie l'Intent à un BroadcastReceiver enregistré ou démarre un Service. Même si l'appareil était en mode veille, WakeLock permet au processeur de se réveiller et de traiter l'événement.
Le principal domaine d'application d'AlarmManager concerne les tâches nécessitant une synchronisation précise : alarmes, rappels de calendrier, lancement d'opérations longues à une heure spécifique. Pour les tâches où la précision n'est pas critique (synchronisation quotidienne), Google recommande WorkManager ou JobScheduler, car ils sont plus économes en énergie.
AlarmManager reçoit un PendingIntent et une heure de déclenchement de l'application. Le système enregistre cette demande dans son planificateur interne et réveille le processeur à l'heure spécifiée pour délivrer l'Intent. Le développeur doit enregistrer un BroadcastReceiver à l'avance pour gérer cet Intent.
AlarmManager prend en charge 4 types d'alarmes : ELAPSED_REALTIME (temps depuis le démarrage, ne réveille pas), RTC (temps réel, ne réveille pas), ELAPSED_REALTIME_WAKEUP (temps depuis le démarrage, réveille l'appareil) et RTC_WAKEUP (temps réel, réveille). Les versions WAKEUP sont nécessaires si la tâche doit s'exécuter même lorsque l'appareil dort.
| Type | Temps | Réveille | Exemple |
|---|---|---|---|
| ELAPSED_REALTIME | depuis le démarrage | non | minuteur de fonctionnement |
| RTC | timestamp Unix | non | journalisation |
| ELAPSED_REALTIME_WAKEUP | depuis le démarrage | oui | tâche périodique |
| RTC_WAKEUP | timestamp Unix | oui | réveil |
À partir d'Android 12 (API 31), l'utilisation d'alarmes précises (setExact) nécessite l'autorisation SCHEDULE_EXACT_ALARM. L'utilisateur peut la révoquer via les paramètres. Pour les applications qui ont besoin d'une alarme précise avec affichage (par exemple, les applications d'horloge), USE_EXACT_ALARM est utilisé, accordé lors de l'installation.
AlarmManager fournit trois méthodes principales pour planifier des tâches. Le choix de la méthode détermine la précision du déclenchement et l'impact sur la consommation d'énergie de l'appareil.
set — la méthode de base pour un déclenchement unique inexact. Le système peut décaler l'heure jusqu'à quelques minutes pour la regrouper avec d'autres événements. Convient aux tâches où la précision n'est pas critique : rappels pour ouvrir l'application.
setRepeating — une méthode pour les répétitions périodiques. Depuis Android 4.4 (API 19), setRepeating est devenu inexact — les intervalles peuvent varier. Le système ne garantit plus une période constante. Au lieu de setRepeating, il est recommandé d'utiliser setExact avec replanification ou WorkManager avec PeriodicWorkRequest.
setExact — une méthode pour un déclenchement unique précis. Le système réveille l'appareil aussi près que possible de l'heure spécifiée. setAlarmClock est un cas particulier de setExact qui affiche également une icône d'alarme dans la barre d'état et a la priorité la plus élevée parmi tous les types d'alarmes.
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// Alarme unique précise
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(
targetTime, pendingIntent
),
pendingIntent
)
Un scénario typique est la création d'un rappel quotidien à une heure spécifique. RTC_WAKEUP avec setExact est utilisé à cette fin. Lors du déclenchement, le BroadcastReceiver lance une notification ou un Service. Après le traitement, la tâche doit être replanifiée pour le jour suivant.
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("Rappel")
.setContentText("Il est temps d'effectuer la tâche")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
Pour la répétition quotidienne, setExact est utilisé avec le calcul du prochain déclenchement. Des drapeaux peuvent être passés dans l'Intent pour identifier différents types de rappels. Assurez-vous que le BroadcastReceiver est enregistré dans AndroidManifest.xml avec la gestion de l'action 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 est un outil puissant mais énergivore. Chaque alarme WAKEUP sort l'appareil du mode veille, consommant la batterie. Google recommande de minimiser l'utilisation des alarmes précises et de préférer setExactAndAllowWhileIdle sur Android 6+ pour réduire l'impact sur le Doze Mode. Pour les tâches périodiques sans exigence de précision, utilisez WorkManager avec PeriodicWorkRequest, qui ne nécessite pas de réveiller l'appareil et ne draine pas la batterie à chaque exécution.
Pour tester AlarmManager, utilisez TestAlarmManager d'Android Test Framework. Il permet d'émuler le déclenchement d'alarmes sans attendre le temps réel. Robolectric fournit ShadowAlarmManager, qui intercepte les appels set, setExact et setRepeating, fournissant des méthodes pour le déclenchement forcé et la vérification du nombre de tâches planifiées. Pour les tests unitaires de BroadcastReceiver, utilisez Robolectric.getForegroundScheduler(). Des tests Espresso avec IdlingResource qui attend le déclenchement de l'alarme dans les tests d'intégration sont également disponibles.
Si votre application utilise AlarmManager pour des tâches périodiques qui ne nécessitent pas de synchronisation précise, envisagez de migrer vers WorkManager. PeriodicWorkRequest avec un intervalle minimum de 15 minutes remplace setRepeating, tandis que WorkManager garantit l'exécution après redémarrage, gère le Doze Mode et ne nécessite pas l'autorisation SCHEDULE_EXACT_ALARM. Pour les tâches critiques en termes de temps (réveil à 7h), AlarmManager reste le seul choix correct. La stratégie optimale consiste à utiliser AlarmManager uniquement pour les alarmes avec setAlarmClock et à déplacer toutes les autres tâches d'arrière-plan vers WorkManager.
Pour les tâches périodiques sans exigence de précision, utilisez WorkManager avec PeriodicWorkRequest. Pour les tâches avec un timing précis mais non critiques pour le déclenchement en mode veille — utilisez setExact sans WAKEUP. Et seulement pour les alarmes avec réveil obligatoire — utilisez setAlarmClock ou RTC_WAKEUP.
Il est également important de vérifier l'autorisation SCHEDULE_EXACT_ALARM sur Android 12+. Si l'autorisation n'est pas accordée, setExact fonctionnera comme un set normal (inexact). Utilisez AlarmManager.canScheduleExactAlarms() pour vérifier. Si l'autorisation est manquante, vous pouvez inviter l'utilisateur à aller dans les paramètres via Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).
Une caractéristique critique d'AlarmManager — toutes les alarmes planifiées sont réinitialisées après le redémarrage de l'appareil. Pour les restaurer, vous devez déclarer un BroadcastReceiver gérant Intent.ACTION_BOOT_COMPLETED et replanifier toutes les alarmes actives dans la méthode onReceive. Sans cela, l'utilisateur perdra tous les rappels après avoir éteint et rallumé le téléphone.
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)
}
}
}
}
En pratique, AlarmManager reste la meilleure solution pour les applications de réveil, les calendriers, les rappels de médicaments et toute tâche où le temps d'exécution est critique pour l'utilisateur. Pour tous les autres scénarios de travail en arrière-plan, WorkManager ou JobScheduler sont préférables.
Lors du choix entre AlarmManager et WorkManager, suivez cette règle : si l'utilisateur a explicitement demandé un rappel à 14h30 — utilisez AlarmManager avec setAlarmClock. Si la tâche doit s'exécuter « environ une fois par heure » — WorkManager avec PeriodicWorkRequest sera plus économe en énergie et plus fiable.
Foire aux questions
Les deux méthodes garantissent un déclenchement précis, mais setAlarmClock affiche en plus une icône d'alarme dans la barre d'état et informe le système qu'il s'agit d'une alarme utilisateur. Sur Android 6+, setAlarmClock est immunisé contre le Doze Mode, tandis que setExact peut être retardé.
Après un redémarrage, toutes les alarmes planifiées sont réinitialisées. Pour les restaurer, vous devez enregistrer un BroadcastReceiver pour l'action BOOT_COMPLETED et replanifier toutes les tâches dans onReceive. Sans cela, aucune alarme ne se déclenchera après la mise sous tension de l'appareil.
Depuis l'API 19, setRepeating est devenu inexact — le système peut décaler les intervalles pour économiser l'énergie. Utilisez plutôt setExact avec replanification manuelle ou WorkManager avec PeriodicWorkRequest, qui offre un comportement plus prévisible.
Pour setExact, l'autorisation SCHEDULE_EXACT_ALARM est requise, que l'utilisateur peut accorder ou révoquer dans les paramètres. Pour setAlarmClock avec affichage dans l'interface de l'horloge, USE_EXACT_ALARM est utilisé, accordé automatiquement lors de l'installation depuis le magasin.
Non, AlarmManager fonctionne toujours via PendingIntent. Il peut s'agir de PendingIntent.getBroadcast pour BroadcastReceiver, PendingIntent.getService pour Service ou PendingIntent.getActivity pour Activity. Sans PendingIntent, le système ne peut pas délivrer l'événement à l'application.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi