Android AlarmManager - RTC_WAKEUP与ELAPSED_REALTIME_WAKEUP

Cam*_*gny 84 android alarmmanager

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

示例代码:

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

    alarmManager.set(AlarmManager.RTC_WAKEUP, 
                     scheduledAlarmTime, 
                     pendingIntent);
Run Code Online (Sandbox Code Playgroud)

这两行代码的执行方式有何不同?这两行代码何时相对于彼此执行?

我感谢您的帮助.

Rej*_*eri 131

AlarmManager.ELAPSED_REALTIME_WAKEUP type用于在启动时触发警报:

alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 600000, pendingIntent);
Run Code Online (Sandbox Code Playgroud)

实际上会在设备启动后10分钟使闹钟响起.

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

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

long thirtySecondsFromNow = System.currentTimeMillis() + 30 * 1000;
alarmManager.set(AlarmManager.RTC_WAKEUP, thirtySecondsFromNow , pendingIntent);
Run Code Online (Sandbox Code Playgroud)

另一方面,这将在30秒后触发警报.

AlarmManager.ELAPSED_REALTIME_WAKEUP类型很少使用相比AlarmManager.RTC_WAKEUP.

  • "与AlarmManager.RTC_WAKEUP相比,很少使用AlarmManager.ELAPSED_REALTIME_WAKEUP类型." 这是猜测和不好的建议.根据文档:https://developer.android.com/training/scheduling/alarms.html"如果您只是需要以特定间隔(例如,每半小时)触发警报,请使用已经过去的一个时间类型.总的来说,这是更好的选择." (15认同)
  • 请注意,代码应该是`System.currentTimeMillis()`而不是`System.currentTimeMills()`:) (2认同)
  • 很好的解释:)!我想添加一个重要的评论:关于来自 Android 的官方文档,当涉及向服务器发出 HTTP 请求的应用程序时,使用“AlarmManager.ELAPSED_REALTIME_WAKEUP”可能会很有趣,并且您不想生成任何在您的网络服务器上加载。想想晚上 10 点 30 分在网络服务器上执行 GET 的数千个 Android 设备:由于在设备的启动时间内工作,“AlarmManager.ELAPSED_REALTIME_WAKEUP”可能会使这些“数千个”设备触发请求,而不是同时,避免负载:)。 (2认同)

mbo*_*suk 106

尽管目前已接受并已投票,但AlarmManager.ELAPSED_REALTIME*类型以及SystemClock.elapsedRealtime()始终比报警和计时的RTC时钟更可靠.

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

alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
                 + 60*1000, pendingIntent);
Run Code Online (Sandbox Code Playgroud)

将在1分钟(60*1000毫秒)内使你的PendingIntent射击.

而AlarmManager.RTC_WAKEUP用于自纪元以来的标准"墙"时间(以毫秒为单位).所以,

alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
                 + 60*10000, pendingIntent);
Run Code Online (Sandbox Code Playgroud)

也可能从现在起60秒后触发警报,但不可靠,因为如SystemClock文档中所述:

挂钟可以由用户或电话网络设置(请参阅setCurrentTimeMillis(long)),因此时间可能会不可预测地向后或向前跳转.只有在与实际日期和时间对应很重要时,例如在日历或闹钟应用程序中,才应使用此时钟.间隔或经过时间测量应使用不同的时钟.如果您使用的是System.currentTimeMillis(),请考虑侦听ACTION_TIME_TICK,ACTION_TIME_CHANGED和ACTION_TIMEZONE_CHANGED Intent广播以查明时间的变化.

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

  • 这很好,但这是一个更准确的问题答案,并纠正当前接受的答案中的事情. (7认同)

Ena*_*Ena 17

只是一张纸条.您可以通过以下方式获取正常运行时间:

long uptimeMillis =  SystemClock.elapsedRealtime();
Run Code Online (Sandbox Code Playgroud)

因此,如果您想在30秒后触发警报,并且您想使用正常运行时钟而不是正常时钟,您可以执行以下操作:

long thirtySecondsFromNow =  SystemClock.elapsedRealtime() + 30 * 1000;
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent);
Run Code Online (Sandbox Code Playgroud)

每当您想要检查一些经过的时间而不是特定的日期/时间时,最好使用正常运行时间.这是因为如果用户使用设置更改设备,用户在设备中设置的当前时间可能会发生变化.

  • +1指示使用"无论何时你想检查经过的时间".完全有道理. (3认同)