Android AlarmManager – RTC_WAKEUP vs ELAPSED_REALTIME_WAKEUP

有人可以向我解释AlarmManager.RTC_WAKEUPAlarmManager.ELAPSED_REALTIME_WAKEUP之间的区别吗? 我已经阅读了文档,但仍然没有真正理解使用其中一个的含义。

示例代码:

  alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, scheduledAlarmTime, pendingIntent); alarmManager.set(AlarmManager.RTC_WAKEUP, scheduledAlarmTime, pendingIntent); 

这两行代码的执行有何不同? 这两行代码何时相互执行?

我感谢您的帮助。

AlarmManager.ELAPSED_REALTIME_WAKEUPtypes用于从启动时间起触发报警:

 alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 600000, pendingIntent); 

实际上会在设备启动10分钟后使报警熄灭。

有一个定时器在设备启动时开始运行,以测量设备的正常运行时间,这是根据设备正常运行时间触发警报的types。

AlarmManager.RTC_WAKEUP会根据时钟的时间触发报警。 例如,如果你这样做:

 long thirtySecondsFromNow = System.currentTimeMillis() + 30 * 1000; alarmManager.set(AlarmManager.RTC_WAKEUP, thirtySecondsFromNow , pendingIntent); 

另一方面,这将从现在起30秒触发报警。

AlarmManager.RTC_WAKEUP相比, AlarmManager.RTC_WAKEUPtypes很less使用。

尽pipe目前已经被接受,并且最新的答案是,AlarmManager.ELAPSED_REALTIME *types与SystemClock.elapsedRealtime()一起比RTC时钟更加可靠。

与AlarmManager一起使用ELAPSED_REALTIME_WAKEUP将依赖于从启动时间开始的单调时钟, 并且即使在CPU处于省电模式时也继续打勾,因此是通用间隔时序的推荐基础 。 所以,

 alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60*1000, pendingIntent); 

会使你的PendingIntent在1分钟(60 * 1000毫秒)内激发。

而AlarmManager.RTC_WAKEUP是从历元开始的标准“墙”时间,以毫秒为单位。 所以,

 alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 60*10000, pendingIntent); 

也可能从现在开始的60秒内触发警报,但不可靠,因为正如SystemClock文档中所述 :

挂钟可以由用户或电话networking设置(参见setCurrentTimeMillis(long)),所以时间可能会跳跃或转发不可预知的。 此时钟只能用于与真实世界date和时间的对应关系,例如在日历或闹钟应用程序中。 间隔或经过时间测量应使用不同的时钟。 如果您正在使用System.currentTimeMillis(),请考虑监听ACTION_TIME_TICK,ACTION_TIME_CHANGED和ACTION_TIMEZONE_CHANGED Intent广播以了解时间更改的时间。

此外,该问题仅引用了* _WAKEUP警报,另请参阅AlarmManager文档,以确保您了解唤醒与非唤醒警报提供的内容。

只是一个说明。 你可以得到毫秒的正常运行时间:

 long uptimeMillis = SystemClock.elapsedRealtime(); 

所以如果你想从现在开始的30秒内发出警报,而你想使用正常运行时间而不是正常的时钟,你可以这样做:

 long thirtySecondsFromNow = SystemClock.elapsedRealtime() + 30 * 1000; alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent); 

每当你想检查一些时间,而不是一个特定的date/时间,最好使用正常运行时间。 这是因为用户在设备中设置的当前时间可能会更改,如果用户使用设置更改它。

我用这种方式在我自己的项目中编写了这个问题。 在下面的代码中我正在使用

 AlarmManager.ELAPSED_REALTIME_WAKEUP 

在特定的时间设置闹钟。 在intentFilter中使用variables“intentName”来接收此警报。 因为我正在发射这种types的很多警报。 当我取消所有的警报。 我使用方法取消。 在底部给出。

//保持警报并在需要时取消

  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); 

span函数是这样的:

  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); } 

报警取消function是这样的。

 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(); } } 

select使用哪个闹钟时需要注意以下几点:(已经阅读了最高票数的人)

RTC_WAKEUP 死亡谷 – 时间变化:
如果用户手动将时间更改为过去,则闹钟不会closures,如果将来会超过RTC时间戳,将立即closures闹钟。
请勿使用此警报进行任何客户端validation/重要工作,因为它有可能失败。

WAKEUP 含义(棉花糖及以上)
一般 – 并不多。 idledoze时不会唤醒设备,为此alarmManager.setExactAndAllowWhileIdlealarmManager.setAndAllowWhileIdle ( 打盹和空闲 )