AlarmManager é um serviço de sistema Android que permite que aplicativos executem tarefas em um horário determinado, mesmo que o aplicativo não esteja em execução ou o dispositivo esteja em modo de suspensão. Ao contrário do JobScheduler ou WorkManager, o AlarmManager garante a precisão da ativação, tornando-o indispensável para alarmes, lembretes de calendário e tarefas críticas quanto ao tempo de execução. De acordo com Android Developers, 2026, a partir do Android 4.4, o setRepeating se comporta como uma repetição imprecisa, e alarmes precisos exigem setExact ou setAlarmClock.
Pontos principais
AlarmManager é um serviço de sistema Android que fornece uma API para agendar tarefas com tempo de execução preciso ou aproximado. Ele existe desde a primeira versão do Android e continua sendo a única maneira confiável de executar código em um momento determinado, independentemente do estado do aplicativo e do dispositivo.
O princípio de funcionamento é simples: o aplicativo envia ao sistema um PendingIntent com o horário de ativação. Quando o horário especificado chega, o sistema envia o Intent para um BroadcastReceiver registrado ou inicia um Service. Mesmo se o dispositivo estiver em modo de suspensão, o WakeLock permite que o processador acorde e processe o evento.
A principal área de aplicação do AlarmManager são tarefas que exigem temporização precisa: alarmes, lembretes de calendário, início de operações longas em um horário específico. Para tarefas onde a precisão não é crítica (sincronização diária), o Google recomenda WorkManager ou JobScheduler, pois são mais eficientes em termos de energia.
AlarmManager recebe um PendingIntent e um horário de ativação do aplicativo. O sistema salva esta solicitação em seu agendador interno e acorda o processador no horário especificado para entregar o Intent. O desenvolvedor deve registrar um BroadcastReceiver com antecedência para lidar com este Intent.
AlarmManager suporta 4 tipos de alarme: ELAPSED_REALTIME (tempo desde a inicialização, não acorda), RTC (tempo real, não acorda), ELAPSED_REALTIME_WAKEUP (tempo desde a inicialização, acorda o dispositivo) e RTC_WAKEUP (tempo real, acorda). As versões WAKEUP são necessárias se a tarefa deve ser executada mesmo quando o dispositivo está dormindo.
| Tipo | Tempo | Acorda | Exemplo |
|---|---|---|---|
| ELAPSED_REALTIME | desde a inicialização | não | temporizador de atividade |
| RTC | timestamp Unix | não | registro |
| ELAPSED_REALTIME_WAKEUP | desde a inicialização | sim | tarefa periódica |
| RTC_WAKEUP | timestamp Unix | sim | despertador |
A partir do Android 12 (API 31), o uso de alarmes precisos (setExact) requer a permissão SCHEDULE_EXACT_ALARM. O usuário pode revogá-la através das configurações. Para aplicativos que precisam de um alarme preciso com exibição (por exemplo, relógios), é usado USE_EXACT_ALARM, que é concedido durante a instalação.
AlarmManager fornece três métodos principais para agendar tarefas. A escolha do método determina a precisão da ativação e o impacto no consumo de energia do dispositivo.
set — o método básico para uma ativação única imprecisa. O sistema pode deslocar o horário em até alguns minutos para agrupar com outros eventos. Adequado para tarefas onde a precisão não é crítica: lembretes para abrir o aplicativo.
setRepeating — um método para repetições periódicas. Desde o Android 4.4 (API 19), o setRepeating tornou-se impreciso — os intervalos podem variar. O sistema não garante mais um período constante. Em vez de setRepeating, é recomendado usar setExact com reagendamento ou WorkManager com PeriodicWorkRequest.
setExact — um método para ativação única precisa. O sistema acorda o dispositivo o mais próximo possível do horário especificado. setAlarmClock é um caso especial de setExact que também mostra um ícone de alarme na barra de status e tem a maior prioridade entre todos os tipos de alarme.
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// Alarme único preciso
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(
targetTime, pendingIntent
),
pendingIntent
)
Um cenário típico é criar um lembrete diário em um horário específico. RTC_WAKEUP com setExact é usado para este propósito. Quando ativado, o BroadcastReceiver lança uma notificação ou Service. Após o processamento, a tarefa deve ser reagendada para o dia seguinte.
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("Lembrete")
.setContentText("Hora de completar a tarefa")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
Para repetição diária, setExact é usado com cálculo do próximo horário de ativação. Flags podem ser passadas no Intent para identificar diferentes tipos de lembretes. Certifique-se de que o BroadcastReceiver esteja registrado no AndroidManifest.xml com tratamento da ação 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 é uma ferramenta poderosa, mas que consome muita energia. Cada alarme WAKEUP tira o dispositivo do modo de suspensão, consumindo bateria. O Google recomenda minimizar o uso de alarmes precisos e preferir setExactAndAllowWhileIdle no Android 6+ para reduzir o impacto no Doze Mode. Para tarefas periódicas sem requisitos de precisão, use WorkManager com PeriodicWorkRequest, que não requer acordar o dispositivo e não drena a bateria a cada execução.
Para testar AlarmManager, use TestAlarmManager do Android Test Framework. Ele permite simular a ativação de alarmes sem esperar o tempo real. O Robolectric fornece ShadowAlarmManager, que intercepta chamadas set, setExact e setRepeating, fornecendo métodos para ativação forçada e verificação da quantidade de tarefas agendadas. Para testes unitários de BroadcastReceiver, use Robolectric.getForegroundScheduler(). Testes Espresso com IdlingResource que aguarda a ativação do alarme em testes de integração também estão disponíveis.
Se seu aplicativo usa AlarmManager para tarefas periódicas que não exigem temporização precisa, considere migrar para WorkManager. PeriodicWorkRequest com intervalo mínimo de 15 minutos substitui setRepeating, enquanto WorkManager garante execução após reinicialização, lida com Doze Mode e não requer a permissão SCHEDULE_EXACT_ALARM. Para tarefas críticas quanto ao tempo (alarme às 7h), AlarmManager continua sendo a única escolha correta. A estratégia ideal é usar AlarmManager apenas para alarmes com setAlarmClock e mover todas as outras tarefas em segundo plano para WorkManager.
Para tarefas periódicas sem requisitos de precisão, use WorkManager com PeriodicWorkRequest. Para tarefas com tempo preciso, mas não críticas para ativar em modo de suspensão — use setExact sem WAKEUP. E apenas para alarmes com ativação obrigatória — use setAlarmClock ou RTC_WAKEUP.
Também é importante verificar a permissão SCHEDULE_EXACT_ALARM no Android 12+. Se a permissão não for concedida, setExact funcionará como set normal (impreciso). Use AlarmManager.canScheduleExactAlarms() para verificar. Se a permissão estiver ausente, você pode solicitar ao usuário que vá para as configurações através de Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).
Uma característica criticamente importante do AlarmManager — todos os alarmes agendados são redefinidos após a reinicialização do dispositivo. Para restaurá-los, você deve declarar um BroadcastReceiver que manipule Intent.ACTION_BOOT_COMPLETED e reagendar todos os alarmes ativos no método onReceive. Sem isso, o usuário perderá todos os lembretes após desligar e ligar o telefone.
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)
}
}
}
}
Na prática, AlarmManager continua sendo a melhor solução para aplicativos de despertador, calendários, lembretes de medicamentos e qualquer tarefa onde o tempo de execução seja crítico para o usuário. Para todos os outros cenários de trabalho em segundo plano, WorkManager ou JobScheduler são preferíveis.
Ao escolher entre AlarmManager e WorkManager, siga esta regra: se o usuário pediu explicitamente para lembrar às 14:30 — use AlarmManager com setAlarmClock. Se a tarefa deve ser executada “aproximadamente uma vez por hora” — WorkManager com PeriodicWorkRequest será mais eficiente em termos de energia e confiável.
Perguntas frequentes
Ambos os métodos garantem ativação precisa, mas setAlarmClock adicionalmente mostra um ícone de alarme na barra de status e informa o sistema de que é um alarme do usuário. No Android 6+, setAlarmClock tem imunidade ao Doze Mode, enquanto setExact pode ser atrasado.
Após uma reinicialização, todos os alarmes agendados são redefinidos. Para restaurá-los, você deve registrar um BroadcastReceiver para a ação BOOT_COMPLETED e reagendar todas as tarefas em onReceive. Sem isso, nenhum alarme será ativado após ligar o dispositivo.
Desde a API 19, setRepeating tornou-se impreciso — o sistema pode deslocar os intervalos para economizar energia. Em vez disso, use setExact com reagendamento manual ou WorkManager com PeriodicWorkRequest, que fornece um comportamento mais previsível.
Para setExact, é necessária a permissão SCHEDULE_EXACT_ALARM, que o usuário pode conceder ou revogar nas configurações. Para setAlarmClock com exibição na interface do relógio, é usado USE_EXACT_ALARM, concedido automaticamente ao instalar da loja.
Não, AlarmManager sempre funciona através de PendingIntent. Pode ser PendingIntent.getBroadcast para BroadcastReceiver, PendingIntent.getService para Service ou PendingIntent.getActivity para Activity. Sem PendingIntent, o sistema não pode entregar o evento ao aplicativo.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também