更改系统时间后,AlarmManager无法取消警报

时间:2019-02-27 20:55:40

标签: android android-asynctask broadcastreceiver alarmmanager android-pendingintent

我正在使用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;
    }
}

}

deleteReminderdeleteWeeklyAlarm方法如下:

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。

0 个答案:

没有答案