AlarmManager запускает аварийные сигналы в прошлом непосредственно перед тем, как BroadcastReceiver может перенести его

У меня есть BroadcastReceiver, который переписывает аварийные сигналы на такие события, как загрузка и изменение времени. Но когда время прошло триггерное время сигнала тревоги (например, когда пользователь вручную меняет время от настроек), AlarmManager срабатывает будильник, прежде чем я смогу добавить день, чтобы перенести мой сигнал. Как я могу избежать этого?

В настоящее время я использую методы set и add Calendar для планирования аварийных сигналов.

        for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; dayOfWeek++) {
            if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek >= nowDay &&
                    !(dayOfWeek == nowDay && alarm.timeHour < nowHour) &&
                    !(dayOfWeek == nowDay && alarm.timeHour == nowHour && alarm.timeMinute <= nowMinute)) {

                calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                alarmSet = true;
                break;
            }
        }

        if (!alarmSet) {
            for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; dayOfWeek++) {
                if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek <= nowDay) {
                    calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                    calendar.add(Calendar.WEEK_OF_YEAR, 1);
                    break;
                }
            }
        }

Это также указано в документах:

Если указанное время триггера в прошлом, срабатывание будильника немедленно.

Как можно изменить это поведение?

Ответ 1

Это предназначено. См. Установить сигнал повторения

Время срабатывания. Если заданное вами время запуска указано в прошлом, будильник срабатывает немедленно.

или тот же здесь

Если указанное время триггера прошло, будильник будет немедленно запущен.

Чтобы этого избежать, вам придется либо вручную проверить свои предупреждения перед их добавлением,

if(alarmTimeStamp < System.currentTimeMillis()) {
    // if is repeating schedule in __interval__
    // else ignore
}

или игнорировать их в приемнике, если дата была в прошлом.

Ответ 2

Как сказал Дэвид, предварительно проверьте дату/время предупреждения перед его использованием; если это было в прошлом, затем добавьте вторую или минута или что-то еще, прежде чем подавать ее на AlarmManager.

Если пользователь вводит дату/время, предварительно проверьте вход таким же образом.

Ответ 3

Как насчет создания BroadcastReceiver для прослушивания изменения времени.

В Manifest файле

 <receiver android:name=".MyReceiver">
            <intent-filter >
                <action android:name="android.intent.action.TIME_SET"/>
            </intent-filter>
 </receiver>

и ваш BroadcastReceiver файл

public class MyReceiver extends BroadcastReceiver{

    @Override 
    public void onReceive(final Context context, Intent intent) {
        Log.d("MyReceiver", "Time Changed");
        // The times have changed; so have their signs.
        updateYourAlarm();
    } 
}