警报管理器:重复警报并不总是触发
Alarm manager: repeating alarm not always fires
我正在尝试开发一种提醒系统,因此用户可以输入提醒的日期(星期一、星期二...)和提醒将触发的时间(仅小时和分钟)。它可以是一周中的任何一天或一周中的多天。以下是设置这些提醒的代码:
final AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
for (final Day day: reminder.getDays()) {
for (final ReminderTime reminderTime: reminder.getTimes()) {
final Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, reminderTime.getHour());
calendar.set(Calendar.MINUTE, reminderTime.getMinute());
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.DAY_OF_WEEK, day.getCalendarDay());
if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
// final long daysDifference = DateUtils.getDaysDifference(calendar.getTimeInMillis(), System.currentTimeMillis());
// calendar.add(Calendar.DAY_OF_YEAR, (int) (daysDifference + 1));
calendar.add(Calendar.DAY_OF_YEAR, 7);
}
final Intent intent = createReminderIntent(context, reminder.getReminderType(), reminderTime, day);
final PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, sender);
}
}
我稍后在自定义 BroadcastReceiver
中收到的警报。
问题是提醒有时会触发,有时不会,在我看来,这几天有些事情很烦人。我想知道是错误还是我做错了什么?
Calendar Calendar_Object = Calendar.getInstance();
Calendar_Object.set(Calendar.DAY_OF_WEEK, 6);
Calendar_Object.setTimeInMillis(System.currentTimeMillis());
Calendar_Object.set(Calendar.HOUR_OF_DAY, 16);
Calendar_Object.set(Calendar.MINUTE, 51);
Calendar_Object.set(Calendar.SECOND, 0);
// MyView is my current Activity, and AlarmReceiver is the
// BoradCastReceiver
Intent myIntent = new Intent(MyView.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MyView.this,
0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
/*
* The following sets the Alarm in the specific time by getting the long
* value of the alarm date time which is in calendar object by calling
* the getTimeInMillis(). Since Alarm supports only long value , we're
* using this method.
*/
Long alarmTime = Calendar_Object.getTimeInMillis();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, alarmTime, 7 * 24 * 60 * 60 * 1000 , pendingIntent);
当使用相同的 Intent
和请求代码调用 PendingIntent.get*(...)
时,返回 PendingIntent
的相同实例。
AlarmManager
只能有一个规则与一个 PendingIntent
关联,这意味着只有 AlarmManager.setRepeating(...)
在您的代码中设置的最后一个警报实际上处于活动状态。其他人被最后一条规则覆盖。
区分具有相同 Intent
的 PendingIntent
的一种方法是为每个使用不同的请求代码。当传递给 AlarmManager
时,这些将按预期触发单独的警报。
遗憾的是,无法取消定义的多个警报,例如按基数 Intent
所以你必须
- 保留最初用于安排警报的所有
PendingIntent
个实例
- 保留所有请求码并重构所述
PendingIntent
s
- 或使用类似的机制。
然后您需要分别对这些 PendingIntent
中的每一个调用 AlarmManager.cancel(pi)
以取消关联的警报。
我正在尝试开发一种提醒系统,因此用户可以输入提醒的日期(星期一、星期二...)和提醒将触发的时间(仅小时和分钟)。它可以是一周中的任何一天或一周中的多天。以下是设置这些提醒的代码:
final AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
for (final Day day: reminder.getDays()) {
for (final ReminderTime reminderTime: reminder.getTimes()) {
final Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, reminderTime.getHour());
calendar.set(Calendar.MINUTE, reminderTime.getMinute());
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.DAY_OF_WEEK, day.getCalendarDay());
if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
// final long daysDifference = DateUtils.getDaysDifference(calendar.getTimeInMillis(), System.currentTimeMillis());
// calendar.add(Calendar.DAY_OF_YEAR, (int) (daysDifference + 1));
calendar.add(Calendar.DAY_OF_YEAR, 7);
}
final Intent intent = createReminderIntent(context, reminder.getReminderType(), reminderTime, day);
final PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, sender);
}
}
我稍后在自定义 BroadcastReceiver
中收到的警报。
问题是提醒有时会触发,有时不会,在我看来,这几天有些事情很烦人。我想知道是错误还是我做错了什么?
Calendar Calendar_Object = Calendar.getInstance();
Calendar_Object.set(Calendar.DAY_OF_WEEK, 6);
Calendar_Object.setTimeInMillis(System.currentTimeMillis());
Calendar_Object.set(Calendar.HOUR_OF_DAY, 16);
Calendar_Object.set(Calendar.MINUTE, 51);
Calendar_Object.set(Calendar.SECOND, 0);
// MyView is my current Activity, and AlarmReceiver is the
// BoradCastReceiver
Intent myIntent = new Intent(MyView.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MyView.this,
0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
/*
* The following sets the Alarm in the specific time by getting the long
* value of the alarm date time which is in calendar object by calling
* the getTimeInMillis(). Since Alarm supports only long value , we're
* using this method.
*/
Long alarmTime = Calendar_Object.getTimeInMillis();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, alarmTime, 7 * 24 * 60 * 60 * 1000 , pendingIntent);
当使用相同的 Intent
和请求代码调用 PendingIntent.get*(...)
时,返回 PendingIntent
的相同实例。
AlarmManager
只能有一个规则与一个 PendingIntent
关联,这意味着只有 AlarmManager.setRepeating(...)
在您的代码中设置的最后一个警报实际上处于活动状态。其他人被最后一条规则覆盖。
区分具有相同 Intent
的 PendingIntent
的一种方法是为每个使用不同的请求代码。当传递给 AlarmManager
时,这些将按预期触发单独的警报。
遗憾的是,无法取消定义的多个警报,例如按基数 Intent
所以你必须
- 保留最初用于安排警报的所有
PendingIntent
个实例 - 保留所有请求码并重构所述
PendingIntent
s - 或使用类似的机制。
然后您需要分别对这些 PendingIntent
中的每一个调用 AlarmManager.cancel(pi)
以取消关联的警报。