Android AlarmManager.setExactAndAllowWhileIdle()报警在工作一段时间后未触



我正在使用AlarmManager设置两个不同的重复报警。每小时59分发出一次警报。这个警报器总是能正常工作。但是,另一个每隔5分钟安排一次的警报在1或2小时内开始正常工作。在那之后,我的AlarmManager会安排报警,但它再也不会被触发。

我正在使用setExactAndAllowWhileIdle()方法来安排警报。

为了检查警报是否已安排和激活,我在调用setExactAndAllowWhileIdle():后使用此方法

fun isAlarmActive(frameType: FrameType): Boolean{
val alarmIntent = getAlarmIntent(frameType)
alarmIntent.action = CUSTOM_INTENT
return PendingIntent.getBroadcast(ctx, 0, alarmIntent, PendingIntent.FLAG_NO_CREATE) != null
}

我通过调度和注释执行setExactAndAllowWhileIdle()的行来测试这种方法,然后将其输出与"adb-shell dumpsys alarm"输出进行比较。

我让这个程序工作了24小时。在查看了我的日志后,我发现警报器在2个小时内一直在工作,当它停止工作时,它被激活了,但不再启动。。。

我的应用程序并没有被杀死,因为尽管这个警报停止了,但另一个仍然在继续工作,我遵循的机制与下面的代码完全相同。

这是MyAlarmManager类:

class MyAlarmManager(private val ctx: Context) {
private val TAG = "MyAlarmManager"
val CUSTOM_INTENT = "com.test.intent.action.ALARM"
private val mAlarmManager = ctx.getSystemService(Context.ALARM_SERVICE) as AlarmManager
fun setAlarm(frameType: FrameType, delayInMinutes: Int, force: Boolean) {
LogsHandler.writeLogs(TAG, "setAlarm()")
checkAlarmsToCancel(frameType)
val triggerAt = getTriggerTime(delayInMinutes, force)
mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt.timeInMillis, getPendingIntent(frameType))
LogsHandler.writeLogs(TAG, "Se ha programado la alarma de tipo $frameType a la hora: ${Date(triggerAt.timeInMillis)}")
if(isAlarmActive(frameType))
LogsHandler.writeLogs(TAG, "La alarma está activada")
else
LogsHandler.writeLogs(TAG, "La alarma NO está activada")
}
private fun getAlarmIntent(frameType: FrameType) :Intent{
return when(frameType){
FrameType.PRESENCE -> Intent(ctx, StartPresenceReportService::class.java)
FrameType.STEPS -> Intent(ctx, StartStepsCountReportService::class.java)
FrameType.LOCATION -> Intent(ctx, StartLocationDeliveryService::class.java)
}
}
private fun getPendingIntent(frameType: FrameType): PendingIntent {
val alarmIntent = getAlarmIntent(frameType)
alarmIntent.action = CUSTOM_INTENT
return PendingIntent.getBroadcast(ctx, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT)
}
}

这是我的广播接收器:

class StartLocationDeliveryService: BroadcastReceiver() {
private var TAG = "StartLocationDeliveryService"
override fun onReceive(context: Context, intent: Intent) {
//Irrelevant code
LocationDeliveryService().executeWork(context, intent)
}
}

这是LocationDeliveryService:

class LocationDeliveryService {
private var TAG = "LocationDeliveryService"
fun executeWork(context: Context, intent: Intent) {
//Business logical operations
MyAlarmManager(context).setAlarm(FrameType.LOCATION, minutesBetweenLocationDeliveryMsgs, false)
}
}

我自己解决了这个问题。这不是一个编程问题,它与Android及其Doze模式有关。Wear OS有一个限制,即我们只能每9分钟安排一次警报。

所以我启动了一个测试,每10分钟重复一次警报,问题就解决了!希望我的解决方案能帮助其他人!

最新更新