У меня есть следующие требования. Пользователь должен иметь возможность планировать повторяющиеся напоминания в моем приложении, которые будут запускать push-уведомления в точное время каждый день.
Это один из тех вопросов, на которые я надеялся, что в конечном итоге не буду отвечать, поскольку подобные вопросы были рекомендованы при его написании. Однако несколько членов команды часами часами просматривали Документы для разработчиков Android и Stackoverflow, и мы, похоже, не приблизились к ответу, поэтому мы здесь.
Если я создаю напоминание и устанавливаю его для запуска уведомления через 5 минут в будущем, уведомление срабатывает очень хорошо.
Я подозреваю, что это может быть проблема, вызванная изменениями в энергосбережении, блокировке пробуждения и т. Д., Появившимися в Android P, поскольку у нас не было этой проблемы до обновления нашего целевого SDK до 28. При этом я не уверен, что это единственная проблема, но я могу последовательно воспроизвести проблему на Pixel и Pixel 3 XL под управлением Android P.
Пример, когда уведомление не срабатывает, возникает, когда, например, пользователь устанавливает напоминание на какое-то время среди ночи (предположительно, когда пользователь спит и, следовательно, не будет использовать телефон в течение нескольких часов). Эти напоминания не стреляют никогда.
В настоящее время я пытаюсь выполнить это с помощью диспетчера аварийных сигналов.
Эта проблема, похоже, похожа на другой вопрос, который использует метод setRepeating Alarm Manager * Manager, который не работает. Вместо этого мы используем метод setExactAndAllowWhileIdle диспетчера тревог. Мы также попробовали эту же реализацию с методом Alarm Managers setAlarmClock , который в соответствии с документацией Android "будет разрешено запускать, даже если система находится в режиме низкого энергопотребления (в режиме ожидания)", однако это было также неудачно.
Я подозреваю, что причина, по которой это не работает, заключается в том, что setExactAndAllowWhileIdle не будет срабатывать, когда телефон находится в режиме ожидания, аналогично проблемам, выраженным в в этом вопросе . В этом вопросе рекомендуется использовать Firebase JobDispatcher, но поскольку это внутреннее уведомление, мне необходимо запустить уведомление с сетевым подключением или без него, что, по-видимому, исключает Firebase JobDispatcher в качестве опции. Этот вопрос также указывает на то, что как только телефон выходит из режима ожидания, пользователь получает уведомление, однако мы никогда не получаем уведомление, они, похоже, теряются из-за отсутствия лучшего термина.
Я добавил разрешение блокировки пробуждения в свой AndroidManifest.xml:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Вот как мой приемник зарегистрирован в AndroidManifest.xml
<receiver android:name="com.myapp.receiver.AlarmReceiver">
</receiver>
Вот моя текущая реализация:
Ожидание обработки уведомлений
Intent i = new Intent(context, ScheduleAllReceiver.class);
PendingIntent scheduleAllPendingIntent = PendingIntent.getBroadcast(context, SCHEDULER_DAILY_ALL, i, PendingIntent.FLAG_UPDATE_CURRENT);
Я впоследствии вызываю метод «createAlarm» следующим образом
createAlarm(context, scheduleAllPendingIntent, calendar.getTimeInMillis());
Создание будильника
public static void createAlarm(Context context, PendingIntent pendingIntent, long timeinMilli) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if(alarmManager != null) {
if (Build.VERSION.SDK_INT >= 23) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeinMilli, pendingIntent);
} else {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeinMilli, pendingIntent);
}
}
}