Android AlarmManager在空闲时不会在第二天触发警报 [英] Android AlarmManager is not triggering alarm on next day when idle

查看:67
本文介绍了Android AlarmManager在空闲时不会在第二天触发警报的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道关于这个话题有数十个类似的话题,但是我只是找不到一个真正能够解决问题或确定根本原因的话题。

I know there are dozens of similar threads on SO about this topic but I just couldn't find one that really solves the problem / or identifies the root cause.

首先,我的目标是SDK 22(Android 5.1),这意味着即使这不是最新的操作方式,我也可以使用AlarmManager + WakefulBroadcastReceiver + IntentService的东西。
我对JobScheduler等解决方案不感兴趣,我只想了解发生了什么以及为什么。

First of all, I'm targetting SDK 22 (Android 5.1) which means I could use the AlarmManager + WakefulBroadcastReceiver + IntentService even if this is not the latest way of doing things. I'm not interested in the JobScheduler etc solutions, I just want to understand what is happening and why.

我正在测试的手机具有Android 8.0,但这并不重要,因为我的目标是Android 5.1。

The phone I'm testing on has Android 8.0, but it shouldn't matter as I'm targeting Android 5.1.

所以我要处理的代码会在第二天06:00发出警报

So the code I'm dealing with sets the alarm for the next day, 06:00.

private fun setupAlarm() {
    val calendar = Calendar.getInstance()
    calendar.timeInMillis = System.currentTimeMillis()
    calendar.add(Calendar.DAY_OF_YEAR, 1)
    calendar.set(Calendar.HOUR_OF_DAY, 6)
    calendar.set(Calendar.MINUTE, 0)

    val alarmIntent = Intent(this, AlarmReceiver::class.java)
    val alarmPendingIntent = PendingIntent.getBroadcast(this, 1221, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT)

    val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, AlarmManager.INTERVAL_DAY, alarmPendingIntent)
}

AlarmReciever仅启动服务:

The AlarmReciever only starts a service:

class AlarmReceiver : WakefulBroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        startWakefulService(context, Intent(context, DownloadingIntentService::class.java));
    }
}

此服务在完成后尝试下载文件它会调用completeWakefulIntent(intent)方法,让它知道系统已完成其工作。

This Service then tries to download a file, when finished it calls the completeWakefulIntent(intent) method letting know the system that it's done with its job.

我不知道它何时工作,什么时候不工作。一天早晨,它做了应该做的事情,另一方面,它没有做到。

I could not figure out when it is working and when it is not. One morning it did what it should have, on the other, it didn't.

我设置了一个远程LogCat功能,以查看IntentService是否已启动,但是到目前为止,我从中看不到任何日志,因此这意味着该警报没有

I set up a remote LogCat feature to see whether the IntentService is started but so far I can't see any logs from it, so it means that the alarm is not triggered.

如果我在下一分钟设置了闹钟,则即使重复响铃,也要按其应有的方式重复。但是当我把时间安排在明天早上的时候,那是非常不可靠的。

If I set up an alarm for the next minute, even repeating one whatever it works like it should. But when I set back the time for tomorrow morning then it's very unreliable.

感谢您的帮助。

推荐答案

我自己已经遇到了这个问题。看看发生了什么事,setRepeating方法让我们的android系统调整应触发警报的时间。它最有可能尝试批处理不同的警报,以优化电池使用量。但是在正常情况下,如果电话没有打...睡……通常会在正确的时间触发警报。

I've faced this exact issue myself. See what happens is that setRepeating method let's the android system adjust the time when the alarm should get fired. It will most likely try to batch different alarms in order to optimise battery usage. But in regular cases, if the phone isn't dozing... It generally fires the alarm at correct times.

但是,如果电话闲置了一段时间,手机进入打ze模式,因此闹铃延迟。我亲自观察到最多延迟1个1:30小时。

However if the phone has been idle for a time, the phone goes into doze mode and due to this the alarm gets delayed. I have personally observed delays of upto 1 1:30 hours.

如果您要精确触发,则必须使用setExactAndAllowWhileIdle方法或setAlarmClock方法。在这种情况下,您将必须自行处理下一个警报的计划。该方法在打ze模式下效果很好,并且可以在准确的时间触发警报。

If you want it to fire exactly, you'll have to use the setExactAndAllowWhileIdle method or setAlarmClock method. In this case, you will have to handle the scheduling of your next alarm on your own. The methods work well with doze mode and do fire the alarms at exact times.

这些方法也有缺点。 setExactAndAllowWhileIdle方法只能用于每九分钟左右调度一次警报最大值。 setAlarmClock方法通常会向用户显示一条类似于常规警报的通知,并将指示警报的详细信息(此行为随不同的操作系统版本而有所不同)

There are cons to these methods too. The setExactAndAllowWhileIdle method can only be used to schedule alarms Max once per nine minutes or so. The setAlarmClock method will mostly show a notification like a regular alarm to the user and will indicate the details of the alarm ( this behaviour varies with different os versions )

这篇关于Android AlarmManager在空闲时不会在第二天触发警报的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆