在 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+ 中使用短时间重复警报的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章