我正在使用AlarmManager设置多个警报,这些警报在我的应用程序中充当提醒。这个想法是,用户将设置自己的警报,提醒他们使用该应用程序。 但是我遇到了一个问题。更改系统时间后,所有过期的警报都会立即关闭(例如,如果将警报设置为星期三,而日期更改为星期四,则星期三的警报将关闭)。
我的闹钟设置如下:
private static void setWeeklyAlarm(Reminder reminder, Context context, String day) throws ParseException {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, ReminderReceiver.class);
...
intent.putExtra(ALARM_ID, _id);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context,_id, intent, 0);
long alarmTime = 0;
if(DateTimeAssist.getCalendarTimeFromReminder(reminder, day) <= Calendar.getInstance().getTimeInMillis()){
alarmTime = DateTimeAssist.getCalendarTimeFromReminder(reminder, day) + (AlarmManager.INTERVAL_DAY * 7);
} else {
alarmTime = DateTimeAssist.getCalendarTimeFromReminder(reminder, day);
}
alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmTime,
alarmIntent);
}
警报响起时,ReminderReceiver
类将发送通知。然后将闹钟设置为在下周重复:
public class ReminderReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
...
int _id = intent.getIntExtra(AlarmAssist.ALARM_ID, 0);
AlarmAssist.resetWeeklyAlarm(_id, context);
}
resetWeeklyAlarm
方法如下:
public static void resetWeeklyAlarm(int _id, Context context){
Intent repeatIntent = new Intent(context, ReminderReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context,_id,repeatIntent,0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + (AlarmManager.INTERVAL_DAY * 7),
pendingIntent);
}
更改系统时间后,将调用ReminderTimeChangeReceiver
类。由于提醒数据存储在Room数据库中,因此删除和重新创建提醒是在后台线程上进行的:
public class ReminderTimeChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
new cancelAndSetAsyncTask().execute(context);
}
private static class cancelAndSetAsyncTask extends AsyncTask<Context, Void, Void> {
@Override
protected Void doInBackground(Context... contexts) {
AppDatabase db = AppDatabase.getDatabase(contexts[0]);
ReminderDao reminderDao = db.reminderDao();
List<Reminder> allReminders = reminderDao.getAllRemindersNotLive();
for(Reminder current : allReminders){
AlarmAssist.deleteReminder(current, contexts[0]);
try {
AlarmAssist.createReminder(current, contexts[0]);
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
}
}
}
deleteReminder
和deleteWeeklyAlarm
方法如下:
public static void deleteReminder(Reminder reminder, Context context) {
ComponentName receiver = new ComponentName(context, ReminderBootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
List<String> days = ListAssist.convertStringToListOf(reminder.getRepeating());
for(String day : days){
deleteWeeklyAlarm(reminder, context, day);
}
}
public static void deleteWeeklyAlarm(Reminder reminder, Context context, String day){
//Disables the receiver for this alarm
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, ReminderReceiver.class);
final int _id = StringsAssist.concatInts(reminder.getTimeHrs(),
reminder.getTimeMins(), DateTimeAssist.dayToInt(day));
Log.d(TAG, "deleteWeeklyAlarm() called with: reminder = [" + reminder + "], context = [" + context + "], day = [" + day + "]");
Log.d(TAG, "deleteWeeklyAlarm: id" + _id);
PendingIntent deleteIntent = PendingIntent.getBroadcast(context, _id, intent, 0);
alarmManager.cancel(deleteIntent);
deleteIntent.cancel();
}
我在这里用了许多其他问题来寻找答案,尤其是受this question的启发,他删除并重新创建了过期的警报。我的问题是:为什么在更改系统时间时我的过期警报仍会关闭?可能是它们在被删除之前就处于激活状态吗?如果是这样,我该如何防止呢?
注意::此应用程序的minSdkVersion为22。