Alguém pode me explicar a diferença entre AlarmManager.RTC_WAKEUP
e AlarmManager.ELAPSED_REALTIME_WAKEUP
? Eu li a documentação, mas ainda não entendo realmente a implicação de usar um em vez do outro.
Código de exemplo:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
scheduledAlarmTime,
pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP,
scheduledAlarmTime,
pendingIntent);
Quão diferentes serão as duas linhas de código executadas? Quando essas duas linhas de código serão executadas em relação uma à outra?
Eu aprecio sua ajuda.
fonte
System.currentTimeMillis()
vez deSystem.currentTimeMills()
:)thirtySecondsFromNow
.Apesar da resposta atualmente aceita e votada, AlarmManager.ELAPSED_REALTIME * digita junto com SystemClock.elapsedRealtime () sempre foi mais confiável do que os relógios RTC para alarmes e tempo.
O uso de ELAPSED_REALTIME_WAKEUP com AlarmManager dependerá de um relógio monotônico começando na hora da inicialização " e continua a funcionar mesmo quando a CPU está em modos de economia de energia, então é a base recomendada para cronometragem de intervalo de uso geral ". Então,
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60*1000, pendingIntent);
fará seu PendingIntent disparar em 1 min (60 * 1000 milissegundos).
Considerando que AlarmManager.RTC_WAKEUP é o tempo de "parede" padrão em milissegundos desde a época. Então,
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 60*10000, pendingIntent);
também pode disparar o alarme daqui a 60 segundos, mas não de maneira confiável, porque conforme observado na documentação do SystemClock :
Além disso, a questão referia-se apenas aos alarmes * _WAKEUP, mas consulte também a documentação do AlarmManager para ter certeza de que entendeu o que os alarmes de ativação versus não ativação fornecem.
fonte
elapsedRealtime()
está abaixo de emSystemClock
vez deSystem
. EDITAR: ... Limite de votos diários atingido ...Apenas uma nota. Você pode obter os milis de tempo de atividade chamando:
long uptimeMillis = SystemClock.elapsedRealtime();
Portanto, se você deseja disparar o alarme daqui a 30 segundos e deseja usar o relógio de tempo de atividade em vez do relógio normal, pode fazer:
long thirtySecondsFromNow = SystemClock.elapsedRealtime() + 30 * 1000; alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent);
Sempre que você quiser verificar algum tempo decorrido em vez de uma data / hora específica, é melhor usar o tempo de atividade. Isso porque a hora atual definida pelo usuário no dispositivo pode mudar se o usuário alterá-la usando as configurações.
fonte
Eu programei este problema em meu próprio projeto desta forma. no código abaixo que estou usando
AlarmManager.ELAPSED_REALTIME_WAKEUP
para definir o alarme em um horário específico. a variável 'intentName' é usada no intentFilter para receber este alarme. porque estou disparando muitos alarmes desse tipo. quando eu cancelo todos os alarmes. eu uso o método cancel. dado na parte inferior.
// para manter alarmes e cancelar quando necessário
public static ArrayList<String> alarmIntens = new ArrayList<String>();
//
public static String setAlarm(int hour, int minutes, long repeatInterval, final Context c) { /* * to use elapsed realTime monotonic clock, and fire alarm at a specific time * we need to know the span between current time and the time of alarm. * then we can add this span to 'elapsedRealTime' to fire the alarm at that time * this way we can get alarms even when device is in sleep mood */ Time nowTime = new Time(); nowTime.setToNow(); Time startTime = new Time(nowTime); startTime.hour = hour; startTime.minute = minutes; //get the span from current time to alarm time 'startTime' long spanToStart = TimeUtils.spanInMillis(nowTime, startTime); // intentName = "AlarmBroadcast_" + nowTime.toString(); Intent intent = new Intent(intentName); alarmIntens.add(intentName); PendingIntent pi = PendingIntent.getBroadcast(c, alarms++, intent, PendingIntent.FLAG_UPDATE_CURRENT); // AlarmManager am = (AlarmManager) c .getSystemService(Context.ALARM_SERVICE); //adding span to elapsedRealTime long elapsedRealTime = SystemClock.elapsedRealtime(); Time t1 = new Time(); t1.set(elapsedRealTime); t1.second=0;//cut inexact timings, seconds etc elapsedRealTime = t1.toMillis(true); if (!(repeatInterval == -1)) am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, elapsedRealTime + spanToStart, repeatInterval, pi); else am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, elapsedRealTime + spanToStart, pi);
onde a função span é esta:
public static long spanInMillis(Time startTime, Time endTime) { long diff = endTime.toMillis(true) - startTime.toMillis(true); if (diff >= 0) return diff; else return AlarmManager.INTERVAL_DAY - Math.abs(diff); }
função de cancelamento de alarme é esta.
public static void cancel(Context c) { AlarmManager am = (AlarmManager) c .getSystemService(Context.ALARM_SERVICE); // cancel all alarms for (Iterator<String> iterator = alarmIntens.iterator(); iterator .hasNext();) { String intentName = (String) iterator.next(); // cancel Intent intent = new Intent(intentName); PendingIntent pi = PendingIntent.getBroadcast(c, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); am.cancel(pi); // iterator.remove(); } }
fonte
Algumas observações importantes ao escolher qual alarme usar : (para quem já leu os votos favoráveis)
O
RTC_WAKEUP
vale da morte - mudança de tempo:Se o usuário alterou manualmente o tempo para o passado, o alarme não disparará, e o futuro fará com que o alarme toque imediatamente se ele passar do
RTC
timestamp.Não use este alarme para fazer qualquer verificação do lado do cliente / trabalhos importantes porque ele pode falhar.
O
WAKEUP
significado (Marshmallow e acima)Em geral - não muito. Não vai despertar o dispositivo quando
idle
ou enquanto estiver dentrodoze
, por issoalarmManager.setExactAndAllowWhileIdle
oualarmManager.setAndAllowWhileIdle
( Soneca e inatividade )fonte