Как автор приложения-будильника, я накопил многолетний опыт и знания о том, как сделать алармы и уведомления надёжными. С тех пор как я применил следующие советы, я не получил ни одной жалобы от пользователя на то, что уведомления работают неправильно.
Вот всё, что вам нужно знать:
1. Запросите разрешение на исключение из оптимизации батареи
Внимание: Если это недостаточно обосновано (например, уведомления не КРИТИЧЕСКИ важны для людей (будильники или задачи)), или вы злоупотребляете этим для отправки маркетинговых уведомлений или сбора аналитики, вас забанят в Google Play.
2. Используйте AlarmManager с exact алармами
Запрашивайте разрешение на exact alarms. Если это обосновано (ваше приложение буквально является приложением-будильником), получите разрешение USE_EXACT_ALARMS, которое всегда выдаётся и не может быть отклонено. USE_EXACT_ALARMS только для приложений-будильников, иначе не пройдёте ревью в маркете.
2.1 ВАЖНО: Используйте одноразовые алармы
Используйте AlarmManager.setAlarmClock() с одноразовыми триггерами и перепланируйте при каждом запуске приложения + срабатывании аларма. НЕ используйте повторяющиеся алармы - они не точные.
3. Войдите в категорию с исключением из режима Doze
Войдите в категорию с исключением из Doze, рисуя оверлеи или используя full screen intents. Если не обосновано, не пройдёте проверку Google Play. Full screen intents разрешены только для будильников и звонков.
4. Запустите постоянный foreground-сервис (крайняя мера)
В крайнем случае запустите постоянный FGS. Если не обосновано, Google не позволит вам запросить разрешение на эксклюзивный тип FGS который не ограничен 4-5 часами.
5. Зарегистрируйтесь на нужные broadcasts
Зарегистрируйтесь на нужные броадкасты, такие как загрузка, обновление, переустановка, изменение часового пояса, изменение времени и другие; и перепланируйте ваши алармы и перезапустите вычисление дат в таких ресиверах.
6. Создайте отдельную базу данных истории срабатываний алармов
Создайте отдельную базу данных истории срабатываний алармов, которая не зашифрована. Разрешите доступ к ней на заблокированных устройствах (нужно создать отдельную инфраструктуру, так как остальные файлы недоступны до разблокировки), используйте broadcast LOCKED_BOOT для перепланирования алармов раньше первой разблокировки. Это гарантирует, что алармы сработают после перезагрузки и на экране блокировки.
7. Реализуйте механизм восстановления для пропущенных алармов
Используя базу данных из шага 6, запустите регулярный WorkManager worker и проверяйте пропущенные напоминания. Если найдены пропущенные, срабатывайте алармы немедленно и отмечайте ошибку. В следующий раз попросите пользователя помочь предотвратить будущие проблемы, дав разрешения или проверив системные настройки. Пользователи оценят, что вы хотя бы попытались восстановиться после проблемы и знаете о ней.
8. Предупреждайте пользователей о проблемных устройствах
Предупреждайте пользователей о проблемных устройствах (Xiaomi, Samsung, OnePlus и т.д.) и обучайте их, как дать разрешения, специфичные для их прошивки. См. dontkillmyapp.com для деталей.
Например:
- Xiaomi имеет дополнительное разрешение на автозапуск, которое вы должны попросить пользователя дать отдельно, иначе это серьёзно повлияет на работу приложения. Это разрешение отличается от всех других разрешений, объявленных в Android, и не пересекается с ними. У Xiaomi также есть различные оптимизаторы батареи, оптимизаторы безопасности и другие функции, которые вы должны сказать пользователю отключить.
- Samsung имеет функцию продления срока службы батареи и настройку для перевода приложений в спящий режим, которые вы также должны учесть и сказать пользователю отключить.
9. Используйте wake locks для критических алармов
Получите разрешение на wake lock, запланируйте ваш аларм на 10-30 минут раньше чем реально надо, и держите wake lock в FGS до момента аларма. Если аларм задерживается, у вас будет 10-30 минут запаса времени. Также хороший способ подготовки пользователей (уведомление “событие скоро начнётся”).