AlarmManager не отменяет тревоги при изменении системного времени - PullRequest
0 голосов
/ 27 февраля 2019

Я использую 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();
}

Я исчерпал много других вопросов здесь, ища ответы, и был вдохновлен на удаление и повторное создание аварий с истекшим сроком действия этим вопросом в частности.Мой вопрос: Почему мои просроченные тревоги все еще срабатывают при изменении системного времени?Может ли быть так, что они активируются до того, как у них есть шанс быть удаленными?Если так, как я мог предотвратить это?

Примечание: Для этого приложения minSdkVersion составляет 22.

...