android - AlarmManager 设置为在 AM 时间触发 PM
问题描述
问题
我正在使用 AndroidAlarmManager
根据用户在设置屏幕上设置的时间定期在我的应用上触发通知。我已经按照文档来实现它。就像下面的代码片段一样:
fun setDailyAlarm(time: Calendar, id: Int) {
val cal = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY))
set(Calendar.MINUTE, time.get(Calendar.MINUTE))
}
val pi = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
cal.timeInMillis,
AlarmManager.INTERVAL_DAY,
pi
)
}
我还使用Material Dialogs 库来调用时间对话框,如下所示:
MaterialDialog(this).show {
// time here is a Calendar instance
timePicker { _, time ->
setDailyAlarm(time, ALARM_ID)
}
}
屏幕如下例所示:
警报本身正在触发,但发生了一个奇怪的错误。
假设现在是晚上 9 点,我将闹钟设置为上午 10 点。我相信预期的行为应该是第二天上午 10 点发出警报,但是一旦时钟到达晚上 10 点,有时我会得到“误报”。(有时我的意思是这种行为甚至不一致。我设法复制了几次,我的客户也抱怨它)。
注意:该应用的最低 API 级别为 21。
到目前为止我尝试过的
起初,我认为日历对象可能得到了错误的 AM/PM 标志,或者Calendar.HOUR_OF_DAY
属性可能是错误的,但是当我在调试器中检查这些值时,一切似乎都很好。所以现在我对问题可能是什么一无所知。
有什么我在这里想念的吗?
解决方案
我找到了解决这个问题的方法。
在做了一些测试之后,我注意到问题只有在我将时间设置为当前小时之前的某个时间时才会发生。然后我想到可能AlarmManager
会自动触发“旧警报”,所以这可能就是我得到那个误报的原因。
然后我将setDailyAlarm()
函数更改为下面的代码段:
fun setDailyAlarm(time: Calendar, id: Int) {
val now = Calendar.getInstance()
val cal = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY))
set(Calendar.MINUTE, time.get(Calendar.MINUTE))
}
if (time.get(Calendar.HOUR_OF_DAY) <= now.get(Calendar.HOUR_OF_DAY)) {
cal.add(Calendar.DATE, 1)
}
val pi = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
cal.timeInMillis,
AlarmManager.INTERVAL_DAY,
pi
)
}
TL;DR:我正在检查所选时间是否早于当前时间,如果是这种情况,我会Calendar
在创建PendingIntent
. 它似乎已经解决了这个问题,因为警报不再在错误的时间触发。
推荐阅读
- docker - 无法在 Windows 10 上安装桌面 docker
- sql - 子查询 Postgres:两个不直接相关的表
- c# - 允许类库使用来自 UI 项目的 App.config
- pip - 没有这样的选项:--extra-index-url http://localhost:8080 / CondaValueError: pip 返回一个错误
- c# - 如何获取实例化对象的类型并使用它在 C# 中强制转换不同的对象?
- sql - 使用来自一个查找表的多个联接并返回最高值
- c# - System.IO.IOException:由于意外的数据包格式,握手失败
- javascript - 访问同一域中的下一页时,Chrome 不会更新 head 标签
- sql - 将数据从平面文件(文本文件).XYZ 文件导入 SQL 表的脚本
- python - 从python中的命令行中提取“>”后的文件名