Programar alarmes

Alarmes (com base no AlarmManager ) oferecem uma maneira de realizar operações baseadas em tempo fora do ciclo de vida do aplicativo. Por exemplo, você pode usar um alarme para iniciar uma operação de longa duração, como como iniciar um serviço uma vez por dia para fazer o download da previsão do tempo.

Os alarmes têm estas características:

  • Permitem que você dispare intents em horários e/ou intervalos definidos

  • É possível usá-los com broadcast receivers para programar empregos ou WorkRequests para realizar outras as operações.

  • Eles operam fora do aplicativo, portanto, você pode usá-los para acionar ou ações, mesmo quando o app não está em execução e mesmo que o dispositivo está adormecido.

  • Eles ajudam a minimizar os requisitos de recursos do app. Você pode programar sem depender de timers nem de serviços em execução contínua.

.

Definir um alarme impreciso

Quando um app define um alarme impreciso, o sistema executa o alarme em algum momento no futuro. Alarmes imprecisos fornecem algumas garantias em relação ao tempo de entrega de alarme, respeitando restrições de economia de bateria, como Soneca.

Os desenvolvedores podem aproveitar as seguintes garantias de API para personalizar o tempo de entrega de alarme inexata.

Enviar um alarme depois de um horário específico

Se o app chamar set(), setInexactRepeating(), ou setAndAllowWhileIdle(), o alarme nunca é acionado antes do tempo de acionamento fornecido.

No Android 12 (nível 31 da API) e versões mais recentes, o sistema invoca o alarme em um hora do tempo de acionamento fornecido, a menos que haja restrições de economia de bateria que estão em vigor, como Economia de bateria ou Soneca.

Enviar um alarme durante uma janela de tempo

Se o app chamar setWindow(), o alarme não será acionado antes que o tempo de acionamento. A menos que haja restrições de economia de bateria em vigor, o alarme será exibidas no período especificado, começando pelo acionador determinado tempo de resposta.

Caso seu app seja destinado ao Android 12 ou versões mais recentes, o sistema pode atrasar a invocação de um alarme inexato com intervalo de tempo de pelo menos 10 minutos. Para Por isso, os valores do parâmetro windowLengthMillis em 600000 são recortados 600000.

Gerar um alarme recorrente em intervalos regulares

Se o app chamar setInexactRepeating(), o sistema invoca vários alarmes:

  1. O primeiro alarme é acionado dentro da janela de tempo especificada, começando pelo tempo de acionamento determinado.
  2. Os alarmes subsequentes geralmente disparam após a janela de tempo especificada passa. O tempo entre duas invocações consecutivas do alarme pode variar.

Definir um alarme exato

O sistema invoca um alarme exato em um momento preciso no futuro.

A maioria dos apps pode programar tarefas e eventos usando alarmes imprecisos para concluir vários casos de uso comuns. Se a base do seu app funcionalidade depende de um alarme com horário preciso, como para um app de despertador ou de calendário, não há problema em usar um alarme exato.

Casos de uso que podem não exigir alarmes exatos

A lista a seguir mostra fluxos de trabalho comuns que podem não exigir um alarme exato:

Programar operações de tempo durante o ciclo de vida do app
A classe Handler inclui várias boas métodos para lidar com operações de tempo, como fazer um trabalho a cada n segundos, enquanto o app está ativo: postAtTime() e postDelayed() Observe que essas APIs dependem do tempo de atividade do sistema. e não em tempo real.
Trabalho programado em segundo plano, como atualizar o app e fazer upload de registros
O WorkManager oferece uma maneira de programar períodos com restrição de tempo funcionam. É possível definir um intervalo de repetição e flexInterval (mínimo de 15 minutos) para definir o ambiente de execução granular para o trabalho.
Ação especificada pelo usuário que precisa acontecer após um período específico (mesmo com o sistema inativo)
Use um alarme não exato. Especificamente, chame setAndAllowWhileIdle()
Ação especificada pelo usuário que acontece após um horário específico
Use um alarme não exato. Especificamente, chame set()
Ação especificada pelo usuário que pode acontecer em uma janela de tempo
Use um alarme não exato. Especificamente, chame setWindow() Caso seu app seja destinado ao Android 12 ou versões mais recentes, as menores a duração permitida da janela é de 10 minutos.

Maneiras de definir um alarme exato

Seu app pode definir alarmes exatos usando um dos métodos a seguir. Esses métodos são ordenados de modo que aqueles mais próximos do fim da lista sejam tarefas críticas em tempo real, mas demandam mais recursos do sistema.

setExact()

Invocar um alarme em um momento quase exato no futuro, contanto que outros as medidas de economia de bateria não estão em vigor.

Use esse método para definir alarmes exatos, a menos que o trabalho do seu app seja urgentes para o usuário.

setExactAndAllowWhileIdle()

Invocar um alarme em um momento quase exato no futuro, mesmo que economize bateria medidas de segurança em vigor.

setAlarmClock()

Invoque um alarme em um momento preciso no futuro. Como esses alarmes são altamente visível para os usuários, o sistema nunca ajusta o tempo de entrega. A identifica esses alarmes como os mais críticos e deixa o baixo consumo modos, se necessário, para enviar os alarmes.

Consumo de recursos do sistema

Quando o sistema aciona alarmes exatos definidos pelo app, o dispositivo consome muitos recursos, como a duração da bateria, especialmente se estiverem um modo de economia de energia. Além disso, o sistema não pode agrupar facilmente essas solicitações para usar os recursos com mais eficiência.

É altamente recomendável criar um alarme impreciso sempre que sempre que possível. Para realizar um trabalho mais longo, programe-o usando WorkManager ou JobScheduler do seu alarme BroadcastReceiver. Para realizar trabalhos enquanto o dispositivo estiver no modo Soneca, crie um alarme impreciso usando setAndAllowWhileIdle(), e iniciar um job pelo alarme.

Declarar a permissão de alarme exato adequada

Caso seu app seja destinado ao Android 12 ou versões mais recentes, é necessário ter a versão "Alarmes e lembretes" acesso especial para apps. Para isso, declare o SCHEDULE_EXACT_ALARM no arquivo de manifesto do app, conforme mostrado no snippet de código a seguir:

<manifest ...>
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
    <application ...>
        ...
    </application>
</manifest>

Caso o app seja direcionado ao Android 13 (nível 33 da API) ou versões mais recentes, você tem a opção de declare o SCHEDULE_EXACT_ALARM ou a USE_EXACT_ALARM permissão.

<manifest ...>
    <uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
    <application ...>
        ...
    </application>
</manifest>

Enquanto as permissões SCHEDULE_EXACT_ALARM e USE_EXACT_ALARM sinalizam os mesmos recursos, eles são concedidos de forma diferente e suportam diferentes para diferentes casos de uso. O app precisa usar alarmes exatos e declarar Permissão SCHEDULE_EXACT_ALARM ou USE_EXACT_ALARM, somente se for voltada ao usuário no seu aplicativo exige ações no momento certo.

USE_EXACT_ALARM

SCHEDULE_EXACT_ALARM

  • Permissão concedida pelo usuário
  • Conjunto mais amplo de casos de uso
  • Os apps precisam confirmar que a permissão não foi revogada

A permissão SCHEDULE_EXACT_ALARM não é concedida previamente a novas instalações de Apps destinados ao Android 13 (nível 33 da API) e versões mais recentes. Se um usuário transferir o app dados para um dispositivo com o Android 14 em uma operação de backup e restauração, A permissão SCHEDULE_EXACT_ALARM será negada no novo dispositivo. No entanto, se um app já existente tiver essa permissão, ela será concedida previamente quando o upgrades de dispositivos para o Android 14.

Observação: se o alarme exato for definido usando um OnAlarmListener objeto, como acontece com o setExact API, a permissão SCHEDULE_EXACT_ALARM não é necessária.

Como usar a permissão SCHEDULE_EXACT_ALARM

Ao contrário de USE_EXACT_ALARM, a permissão SCHEDULE_EXACT_ALARM precisa ser concedidas pelo usuário. O usuário e o sistema podem revogar SCHEDULE_EXACT_ALARM.

Para verificar se a permissão foi concedida ao app, chame canScheduleExactAlarms() antes de tentar definir um alarme exato. Quando a permissão SCHEDULE_EXACT_ALARM for revogado no app, ele será interrompido e todos os alarmes exatos futuros são cancelados. Isso também significa que o valor retornado O canScheduleExactAlarms() permanece válido durante todo o ciclo de vida do app.

Quando a permissão SCHEDULE_EXACT_ALARMS é concedida ao app, o sistema envia a ele ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED transmissão. O app precisa implementar uma receptor que faz a seguinte:

  1. Confirma que seu app ainda tem o acesso especial. Para fazer isso, chame o método canScheduleExactAlarms(). Essa verificação protege o app contra o caso em que o usuário concede a ele o permissão, revoga-a logo em seguida.
  2. Reprograma os alarmes exatos que o app precisa com base no estado atual. Essa lógica precisa ser parecida com a de quando o app recebe a transmissão ACTION_BOOT_COMPLETED.

Pedir aos usuários para conceder a permissão SCHEDULE_EXACT_ALARM

A opção &quot;Autorizar a definição de alarmes e lembretes&quot;
Figura 1. Página de acesso especial aos "Alarmes e lembretes" nas configurações do sistema, onde os usuários podem autorizar o app a definir alarmes exatos.

Se necessário, direcione os usuários para a página Alarmes e tela de lembretes no sistema conforme mostrado na Figura 1. Para isso, siga estas etapas:

  1. Na IU do app, explique ao usuário por que o app precisa programar alarmes exatos.
  2. Invoque uma intent que inclua a ação da intent ACTION_REQUEST_SCHEDULE_EXACT_ALARM.

Definir um alarme recorrente

Alarmes recorrentes permitem que o sistema notifique seu app em um cronograma.

Um alarme mal projetado pode consumir bateria e sobrecarregar servidores. Por esse motivo, no Android 4.4 (nível 19 da API) e versões mais recentes, alarmes recorrentes são alarmes imprecisos.

Um alarme recorrente tem as seguintes características:

  • Um tipo de alarme. Para saber mais, consulte Escolher um tipo de alarme.

  • Um tempo de acionamento. Se o horário de acionamento especificado estiver no passado, o alarme é acionada imediatamente.

  • O intervalo do alarme. Por exemplo, uma vez por dia, a cada hora ou a cada cinco minutos.

  • Um intent pendente que é acionado quando o alarme é disparado. Quando você define segundo alarme que usa a mesma intent pendente, ele substitui o alarme original.

Para cancelar um PendingIntent(), transfira o FLAG_NO_CREATE para PendingIntent.getService() para receber uma instância da intent (se ela existir) e, em seguida, passe-a para AlarmManager.cancel()

Kotlin

val alarmManager =
    context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
val pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE)
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent)
}

Java

AlarmManager alarmManager =
    (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent);
}

Escolher um tipo de alarme

Uma das primeiras considerações sobre o uso de um alarme recorrente é seu tipo deve ser.

Existem dois tipos gerais de relógio para alarmes: "tempo real decorrido" e "relógio em tempo real" (RTC, na sigla em inglês). O tempo real decorrido usa o "tempo desde a inicialização do sistema" como referência, e o relógio em tempo real usa o fuso horário UTC. Isso significa que o tempo real decorrido é adequado para definir um alarme com base na passagem do tempo (por exemplo, um alarme que dispara a cada 30 segundos), já que não é afetado pelo fuso horário ou localidade. O tipo de relógio em tempo real é mais adequado para alarmes que dependem da localidade atual.

Ambos os tipos têm um "despertador" padrão, que diz para ativar a CPU do dispositivo se que a tela esteja desligada. Isso garante que o alarme seja disparado no horário programado. Isso é útil caso seu app tenha uma dependência de tempo. Por exemplo, se tiver uma janela limitada para executar uma operação específica. Se você não usar o método versão de ativação do seu tipo de alarme, todos os alarmes recorrentes serão disparados na próxima vez que o dispositivo estiver ativado.

Se você só precisar que o alarme dispare em um intervalo específico (por exemplo, a cada meia hora), use um dos tipos de tempo real decorrido. Em geral, é a melhor escolha.

Se você precisar que seu alarme dispare em um horário específico do dia, escolha um dos tipos de relógio em tempo real com base em relógio. No entanto, essa abordagem pode têm algumas desvantagens. O app pode não traduzir bem para outras localidades e, se o usuário alterar a configuração de hora do dispositivo, isso poderá causar um comportamento inesperado no seu app. Usar um tipo de alarme de relógio em tempo real também não funciona bem, discutidos acima. Recomendamos o uso de um "tempo real decorrido" alarme se puder.

Veja a lista de tipos:

  • ELAPSED_REALTIME: Dispara a intent pendente com base no tempo decorrido desde o início do dispositivo foi inicializado, mas não ativa o dispositivo. A o tempo decorrido inclui qualquer período em que o dispositivo esteve inativo.

  • ELAPSED_REALTIME_WAKEUP: Ativa o dispositivo e dispara o intent pendente após o comprimento especificado desde a inicialização do dispositivo.

  • RTC: Dispara o intent pendente no horário especificado, mas não ativa o dispositivo.

  • RTC_WAKEUP: ativações o dispositivo para disparar a intent pendente no momento especificado.

Exemplos de alarmes de "tempo real decorrido"

Confira alguns exemplos de como usar ELAPSED_REALTIME_WAKEUP.

Ativar o dispositivo para disparar o alarme em 30 minutos e a cada 30 minutos Depois disso:

Kotlin

// Hopefully your alarm will have a lower frequency than this!
alarmMgr?.setInexactRepeating(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR,
        alarmIntent
)

Java

// Hopefully your alarm will have a lower frequency than this!
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);

Ativar o dispositivo para disparar um alarme único (não recorrente) em um minuto:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

alarmMgr?.set(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + 60 * 1000,
        alarmIntent
)

Java

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() +
        60 * 1000, alarmIntent);

Exemplos de alarmes de "relógio em tempo real"

Aqui estão alguns exemplos de como usar RTC_WAKEUP

Ativar o dispositivo para disparar o alarme por volta das 14h e Repetir uma vez por dia no mesmo horário:

Kotlin

// Set the alarm to start at approximately 2:00 p.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 14)
}

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr?.setInexactRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        AlarmManager.INTERVAL_DAY,
        alarmIntent
)

Java

// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

Ativar o dispositivo para disparar o alarme exatamente às 8h30 e a cada 20 minutos depois disso:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

// Set the alarm to start at 8:30 a.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 8)
    set(Calendar.MINUTE, 30)
}

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr?.setRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        1000 * 60 * 20,
        alarmIntent
)

Java

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000 * 60 * 20, alarmIntent);

Decidir a precisão que o alarme precisa ter

Como descrito anteriormente, escolher o tipo de alarme é muitas vezes a primeira etapa criando um alarme. Outra distinção é a precisão do alarme. ter. Para a maioria dos apps, setInexactRepeating() é a escolha certa. Quando você usa esse método, o Android sincroniza vários alarmes e disparos repetidos imprecisos ao mesmo tempo. Isso reduz o consumo da bateria.

Evite usar alarmes exatos, se possível. No entanto, para um app raro que tem configurações requisitos de tempo, você pode definir um alarme exato chamando setRepeating().

Com o setInexactRepeating(), não é possível especificar um intervalo personalizado setRepeating() Você precisa usar uma das constantes de intervalo, como INTERVAL_FIFTEEN_MINUTES, INTERVAL_DAY, e assim por diante. Consulte AlarmManager. para conferir a lista completa.

Cancelar um alarme

Dependendo do app, convém incluir a capacidade de cancelar o alarme. Para cancelar um alarme, ligue para cancel() no Alarm Manager, transmitindo PendingIntent que você não quer mais disparar. Exemplo:

Kotlin

// If the alarm has been set, cancel it.
alarmMgr?.cancel(alarmIntent)

Java

// If the alarm has been set, cancel it.
if (alarmMgr!= null) {
    alarmMgr.cancel(alarmIntent);
}

Iniciar um alarme quando o dispositivo é reiniciado

Por padrão, todos os alarmes são cancelados quando um dispositivo é desligado. Para evitar que isso aconteça, você pode projetar seu aplicativo para reiniciar automaticamente um alarme recorrente se o usuário reinicializar o dispositivo. Isso garante que o AlarmManager vai continuar realizando a tarefa sem que o usuário precise reiniciar manualmente o alarme.

Veja as etapas:

  1. Defina o RECEIVE_BOOT_COMPLETED. no manifesto do seu aplicativo. Isso permite que o app receba ACTION_BOOT_COMPLETED que é transmitido após a inicialização do sistema (isso só funciona se o app já foi iniciado pelo usuário pelo menos uma vez):

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. Implementar um BroadcastReceiver para receber a transmissão:

    Kotlin

    class SampleBootReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == "android.intent.action.BOOT_COMPLETED") {
                // Set the alarm here.
            }
        }
    }
    

    Java

    public class SampleBootReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
                // Set the alarm here.
            }
        }
    }
    
  3. Adicione o receptor ao arquivo de manifesto do app com um filtro de intent que: na ACTION_BOOT_COMPLETED ação:

    <receiver android:name=".SampleBootReceiver"
            android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
    </receiver>

    Observe que, no manifesto, o receptor de inicialização está definido como android:enabled="false": Isso significa que o receptor só será chamado se o aplicativo o ativar explicitamente. Isso evita que receptor de inicialização seja chamado desnecessariamente. É possível ativar um receptor (por exemplo, se o usuário definir um alarme) da seguinte forma:

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
    )
    

    Java

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
    

    Depois que você ativar o receptor dessa forma, ele permanecerá ativado, mesmo se o usuário reinicializa o dispositivo. Em outras palavras, ativar programaticamente o receptor substitui a configuração do manifesto, mesmo durante as reinicializações. O destinatário vai continuar ativada até ser desativado pelo app. É possível desativar um receptor (por exemplo, se o usuário cancelar um alarme) da seguinte forma:

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
    )
    

    Java

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
    

Invocar alarmes enquanto o dispositivo está no modo Soneca

Dispositivos com suporte ao Android 6.0 (nível 23 da API) Soneca , que ajuda a prolongar a duração da bateria. Os alarmes não disparam quando o dispositivo está ligado Modo Soneca Todos os alarmes programados são adiados até que o dispositivo saia do modo Soneca. Se você precisar concluir o trabalho mesmo quando o dispositivo está inativo, há várias opções disponíveis:

  • Defina um alarme exato.

  • Use a API WorkManager, que foi criada para executar trabalho em segundo plano. Você pode indicar que o sistema deve acelerar seu trabalho para que que o trabalho termine o mais rápido possível. Para mais informações, consulte Programar tarefas com o WorkManager

Práticas recomendadas

Cada escolha que você faz ao criar um alarme recorrente pode ter consequências na forma como o aplicativo usa (ou abusa) de recursos do sistema. Por exemplo, imagine um um aplicativo conhecido que sincroniza com um servidor. Se a operação de sincronização for baseada no relógio e cada instância do aplicativo for sincronizada às 23h00, a carga no servidor de dados pode resultar em alta latência ou até ou “negação de serviço”. Siga estas práticas recomendadas para o uso de alarmes:

  • Adicionar aleatoriedade (instabilidade) a todas as solicitações de rede que ser acionada como resultado de um alarme recorrente:

    • Faça qualquer trabalho local quando o alarme for acionado. "Trabalho local" significa qualquer coisa que não acessa um servidor nem exige os dados do servidor.

    • Ao mesmo tempo, programe o alarme que contém as solicitações de rede para disparar em um período aleatório.

  • Mantenha a frequência do alarme em um nível mínimo.

  • Não ative o dispositivo desnecessariamente. Esse comportamento é determinado pelo tipo de alarme, conforme descrito em Escolher um tipo de alarme).

  • Não faça com que o horário de acionamento do alarme seja mais preciso do que o necessário.

    Usar setInexactRepeating() em vez de setRepeating() Ao usar o setInexactRepeating(), O Android sincroniza alarmes recorrentes de vários apps e dispara alarmes ao mesmo tempo. Isso reduz o número total de vezes que o sistema deve despertar o do dispositivo, reduzindo assim o consumo da bateria. A partir do Android 4.4 (nível 19 da API), todos os alarmes recorrentes são alarme imprecisos. Observação que, enquanto setInexactRepeating() é uma melhoria setRepeating(), ainda pode sobrecarregar o servidor se cada instância de um aplicativo chegar ao servidor no mesmo período. Portanto, para solicitações de rede, adicione alguma aleatoriedade seus alarmes, como discutimos anteriormente.

  • Evite basear seu alarme na hora do relógio, se possível.

    Alarmes recorrentes baseados em um gatilho preciso não funcionam bem. Usar ELAPSED_REALTIME se possível. O alarme diferente são descritos em mais detalhes na próxima seção.