在 Android 5.0+ 中使用短时间重复警报的正确方法是啥?

Posted

技术标签:

【中文标题】在 Android 5.0+ 中使用短时间重复警报的正确方法是啥?【英文标题】:What is the correct way to use repeating alarms for short intervals in Android 5.0+?在 Android 5.0+ 中使用短时间重复警报的正确方法是什么? 【发布时间】:2016-10-12 13:42:09 【问题描述】:

所以我需要以非常短的频率(30 秒)将坐标从我当前的位置发送到服务器。现在我正在使用 AlarmManager setRepeating(),但 android 5.0+ 允许最多 1 分钟的间隔以节省电池。

我的问题是:

我的方法真的有效吗?即使设备关闭,我也需要在后台运行此重复警报。目前我正在执行pendingintent,这导致broadcastreceiver,而asynctasks,一个用于服务器身份验证,一个用于发布坐标。

【问题讨论】:

【参考方案1】:

我的方法真的有效吗?

没有。这就是 Android 5.1+ 不支持开箱即用的原因,这也是 Android 6.0 引入 Doze 模式的原因。

即使设备关闭,我也需要在后台运行此重复警报。

我认为“设备已关闭”实际上是指“屏幕已关闭”。如果设备断电,您的代码将无法运行。

您可以使用setExact()“手动”以 30 秒的间隔执行您自己的重复事件,其中您对警报事件所做的工作包括安排下一个警报。当设备处于打盹模式时,这也会在 Android 6.0+ 设备上失败。在 Android 6.0+ 上获得每 30 秒行为的唯一方法是让用户将您的应用添加到“设置”中的电池优化白名单中。

目前我正在执行导致广播接收器的挂起意图,广播接收器依次执行异步任务,一个用于服务器身份验证,一个用于发布坐标。

首先,这不太可能是可靠的。你的进程可以在onReceive() 返回后立即终止,因为 Android 认为你的工作已经完成。

其次,AsyncTask 通常对于广播等后台操作毫无意义。 AsyncTask 背后的全部要点是让您在后台工作结束时在主应用程序线程上工作,几乎没有理由在后台在主应用程序线程上工作。由于这个和上述原因,请使用单个IntentService 替换两个AsyncTasks

第三,在任何给定的警报事件中,由于网络拥塞、服务器问题等原因,您很有可能无法在 30 秒内完成工作。您需要确保妥善处理此问题, 这样您就不会将各种请求排入队列(或者,在您当前的实现中,fork 大量并行的 AsyncTasks 都在尝试完成它们的工作)。

【讨论】:

据我了解,setExact() 不是重复警报,那么我该如何安排重复警报,比如说,使用 setExact() 30 秒? @MarkTyers:引用我的回答:“您可以使用 setExact() 以 30 秒的间隔“手动”执行您自己的重复事件,其中您对警报事件所做的工作包括安排下一个警报”。您表示您的警报触发了接收器(希望是WakefulBroadcastReceiver)。让接收者启动IntentService 并致电setExact() 安排下一个活动。或者,让IntentService 呼叫setExact() 安排下一个活动,一旦工作完成,以避免排队工作。 所以基本上我必须在按钮按下时为BroadcastReceiver 设置setExact(),并在BroadcastReceiver 中的代码末尾设置另一个setExact()?我该如何阻止它? @MarkTyers:在AlarmManager 上致电cancel(),或者只是不安排下一个(跳过setExact() 电话),以适合您的场景为准。

以上是关于在 Android 5.0+ 中使用短时间重复警报的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中停止重复警报服务?

Android - 空闲时允许重复警报

在android中每周重复一次警报

在Android警报管理器中设置时间-立即触发警报[重复]

Android简单的警报对话框[重复]

android重复警报,应按月重复,每个月在同一天重复,依此类推