AlarmManager es un servicio del sistema Android que permite a las aplicaciones ejecutar tareas en un momento determinado, incluso si la aplicación no se está ejecutando o el dispositivo está en modo de suspensión. A diferencia de JobScheduler o WorkManager, AlarmManager garantiza la precisión de la activación, lo que lo hace indispensable para alarmas, recordatorios de calendario y tareas críticas en cuanto al tiempo de ejecución. Según Android Developers, 2026, a partir de Android 4.4, setRepeating se comporta como una repetición inexacta, y para alarmas precisas se requiere setExact o setAlarmClock.
Puntos clave
AlarmManager es un servicio del sistema Android que proporciona una API para programar tareas con un tiempo de ejecución preciso o aproximado. Existe desde la primera versión de Android y sigue siendo la única forma fiable de ejecutar código en un momento determinado, independientemente del estado de la aplicación y del dispositivo.
El principio de funcionamiento es sencillo: la aplicación envía al sistema un PendingIntent con la hora de activación. Cuando llega el momento indicado, el sistema envía el Intent a un BroadcastReceiver registrado o inicia un Service. Incluso si el dispositivo estaba en modo de suspensión, WakeLock permite que el procesador se active y procese el evento.
El área de aplicación principal de AlarmManager son las tareas que requieren una sincronización precisa: alarmas, recordatorios de calendario, inicio de operaciones de larga duración a una hora determinada. Para tareas donde la precisión no es crítica (sincronización diaria), Google recomienda WorkManager o JobScheduler, ya que son más eficientes energéticamente.
AlarmManager recibe un PendingIntent y una hora de activación de la aplicación. El sistema guarda esta solicitud en su planificador interno y activa el procesador en el momento indicado para entregar el Intent. El desarrollador debe registrar un BroadcastReceiver con antelación para manejar este Intent.
AlarmManager soporta 4 tipos de alarmas: ELAPSED_REALTIME (tiempo desde el arranque, no activa), RTC (tiempo real, no activa), ELAPSED_REALTIME_WAKEUP (tiempo desde el arranque, activa el dispositivo) y RTC_WAKEUP (tiempo real, activa). Las versiones WAKEUP son necesarias si la tarea debe ejecutarse incluso cuando el dispositivo está dormido.
| Tipo | Tiempo | Activa | Ejemplo |
|---|---|---|---|
| ELAPSED_REALTIME | desde el arranque | no | temporizador de actividad |
| RTC | timestamp Unix | no | registro |
| ELAPSED_REALTIME_WAKEUP | desde el arranque | sí | tarea periódica |
| RTC_WAKEUP | timestamp Unix | sí | alarma |
A partir de Android 12 (API 31), el uso de alarmas precisas (setExact) requiere el permiso SCHEDULE_EXACT_ALARM. El usuario puede revocarlo a través de la configuración. Para aplicaciones que necesitan una alarma precisa con visualización (por ejemplo, relojes), se utiliza USE_EXACT_ALARM, que se concede durante la instalación.
AlarmManager proporciona tres métodos principales para programar tareas. La elección del método determina la precisión de la activación y el impacto en el consumo de energía del dispositivo.
set — el método básico para una activación única inexacta. El sistema puede desplazar la hora hasta unos minutos para agruparla con otros eventos. Adecuado para tareas donde la precisión no es crítica: recordatorios para abrir la aplicación.
setRepeating — un método para repeticiones periódicas. Desde Android 4.4 (API 19), setRepeating se ha vuelto inexacto — los intervalos pueden variar. El sistema ya no garantiza un período constante. En lugar de setRepeating, se recomienda usar setExact con replanificación o WorkManager con PeriodicWorkRequest.
setExact — un método para una activación única precisa. El sistema activa el dispositivo lo más cerca posible de la hora indicada. setAlarmClock es un caso especial de setExact que también muestra un icono de alarma en la barra de estado y tiene la prioridad más alta entre todos los tipos de alarma.
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// Alarma única 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
)
Un escenario típico es crear un recordatorio diario a una hora específica. Para ello se utiliza RTC_WAKEUP con setExact. Cuando se activa, el BroadcastReceiver lanza una notificación o Service. Después del procesamiento, la tarea debe reprogramarse para el día siguiente.
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("Recordatorio")
.setContentText("Hora de completar la tarea")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
Para la repetición diaria, se utiliza setExact con el cálculo de la siguiente activación. Se pueden pasar banderas en el Intent para identificar diferentes tipos de recordatorios. Asegúrese de que BroadcastReceiver esté registrado en AndroidManifest.xml con el manejo de la acción 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 es una herramienta potente pero que consume mucha energía. Cada alarma WAKEUP saca al dispositivo del modo de suspensión, consumiendo batería. Google recomienda minimizar el uso de alarmas precisas y preferir setExactAndAllowWhileIdle en Android 6+ para reducir el impacto en Doze Mode. Para tareas periódicas sin requisitos de precisión, use WorkManager con PeriodicWorkRequest, que no requiere activar el dispositivo y no agota la batería en cada ejecución.
Para probar AlarmManager, use TestAlarmManager de Android Test Framework. Permite emular la activación de alarmas sin esperar el tiempo real. Robolectric proporciona ShadowAlarmManager, que intercepta las llamadas a set, setExact y setRepeating, proporcionando métodos para la activación forzada y la verificación del número de tareas programadas. Para pruebas unitarias de BroadcastReceiver, use Robolectric.getForegroundScheduler(). También están disponibles pruebas Espresso con IdlingResource que espera la activación de la alarma en pruebas de integración.
Si su aplicación utiliza AlarmManager para tareas periódicas que no requieren una sincronización precisa, considere migrar a WorkManager. PeriodicWorkRequest con un intervalo mínimo de 15 minutos reemplaza a setRepeating, mientras que WorkManager garantiza la ejecución después del reinicio, maneja Doze Mode y no requiere el permiso SCHEDULE_EXACT_ALARM. Para tareas críticas en cuanto al tiempo (alarma a las 7 AM), AlarmManager sigue siendo la única opción correcta. La estrategia óptima es usar AlarmManager solo para alarmas con setAlarmClock y mover todas las demás tareas en segundo plano a WorkManager.
Para tareas periódicas sin requisitos de precisión, use WorkManager con PeriodicWorkRequest. Para tareas con tiempo preciso pero no críticas para activarse en modo de suspensión — use setExact sin WAKEUP. Y solo para alarmas con activación obligatoria — use setAlarmClock o RTC_WAKEUP.
También es importante verificar el permiso SCHEDULE_EXACT_ALARM en Android 12+. Si el permiso no se concede, setExact funcionará como un set normal (inexacto). Use AlarmManager.canScheduleExactAlarms() para verificar. Si falta el permiso, puede solicitar al usuario que vaya a la configuración a través de Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).
Una característica críticamente importante de AlarmManager — todas las alarmas programadas se restablecen después del reinicio del dispositivo. Para restaurarlas, debe declarar un BroadcastReceiver que maneje Intent.ACTION_BOOT_COMPLETED y reprogramar todas las alarmas activas en el método onReceive. Sin esto, el usuario perderá todos los recordatorios después de apagar y encender el teléfono.
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 la práctica, AlarmManager sigue siendo la mejor solución para aplicaciones de reloj despertador, calendarios, recordatorios de medicamentos y cualquier tarea donde el tiempo de ejecución sea crítico para el usuario. Para todos los demás escenarios de trabajo en segundo plano, se prefieren WorkManager o JobScheduler.
Al elegir entre AlarmManager y WorkManager, siga esta regla: si el usuario solicitó explícitamente un recordatorio a las 2:30 PM — use AlarmManager con setAlarmClock. Si la tarea debe ejecutarse “aproximadamente una vez por hora” — WorkManager con PeriodicWorkRequest será más eficiente energéticamente y fiable.
Preguntas frecuentes
Ambos métodos garantizan una activación precisa, pero setAlarmClock además muestra un icono de alarma en la barra de estado e informa al sistema de que es una alarma de usuario. En Android 6+, setAlarmClock tiene inmunidad contra Doze Mode, mientras que setExact puede retrasarse.
Después de un reinicio, todas las alarmas programadas se restablecen. Para restaurarlas, debe registrar un BroadcastReceiver para la acción BOOT_COMPLETED y reprogramar todas las tareas en onReceive. Sin esto, ninguna alarma se activará después de encender el dispositivo.
Desde API 19, setRepeating se ha vuelto inexacto — el sistema puede desplazar los intervalos para ahorrar energía. En su lugar, use setExact con reprogramación manual o WorkManager con PeriodicWorkRequest, que proporciona un comportamiento más predecible.
Para setExact, se requiere el permiso SCHEDULE_EXACT_ALARM, que el usuario puede conceder o revocar en la configuración. Para setAlarmClock con visualización en la interfaz del reloj, se utiliza USE_EXACT_ALARM, que se concede automáticamente al instalarlo desde la tienda.
No, AlarmManager siempre funciona a través de PendingIntent. Puede ser PendingIntent.getBroadcast para BroadcastReceiver, PendingIntent.getService para Service o PendingIntent.getActivity para Activity. Sin PendingIntent, el sistema no puede entregar el evento a la aplicación.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también