在某些时间工作后未触发Android AlarmManager.setExactAndAllowWhileIdle()警报

时间:2019-01-14 10:20:47

标签: android kotlin alarmmanager android-alarms

我正在使用AlarmManager设置2种不同的重复警报。每小时在第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)
    }

}


这是我的BroadcastReceiver:

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:-4)

请浏览以下库以完成您的工作。 link

谢谢