As an author of an alarm clock app, I have accumulated years of experience and knowledge in how to make alarms and notifications reliable. Since I implemented the following advice, I haven’t received a single report from a user about notifications not working properly.

Here’s everything you need to know:

1. Ask for battery exclusion permission

Caveat: If not justified enough (e.g. the notifications are CRITICAL for people such as alarms or tasks), or you abuse it to send marketing notifications or collect analytics, you will face a ban on Google Play.

2. Use AlarmManager with exact alarms

Ask for exact alarm permission after priming users. If justified (your app is literally an alarm app), obtain USE_EXACT_ALARMS permission that is always granted and can’t be denied. Use exact alarms is only for alarm apps or won’t pass review.

2.1 IMPORTANT: Use single-fire alarms

Use AlarmManager.setAlarmClock() with single-fire alarms and reschedule on each app start + alarm trigger. Do NOT use repeating alarms - they aren’t exact.

3. Enter doze exempted bucket

Enter doze exempted bucket by drawing overlays or using full screen intents. If unjustified, won’t pass Google Play review. Full screen intents are only allowed for alarms and calls.

4. Run a permanent foreground service (last resort)

As a last resort, run a permanent FGS. If unjustified, Google won’t let you claim an FGS type permission.

5. Register for proper broadcasts

Register for proper broadcasts such as boot, update, reinstall, time zone change, time change, and more; and reschedule your alarms and rerun date computation in such receivers.

6. Create a separate alarm trigger history database

Create a separate alarm trigger history database which is unencrypted. Allow accessing it on locked devices (must create a separate infra since the rest of files are all inaccessible until unlocked), use LOCKED_BOOT broadcast to reschedule alarms earlier than first unlock. This will ensure alarms fire after reboot and on lock screen.

7. Implement recovery mechanism for missed alarms

Using the database from step 6, run a regular WorkManager worker and check for missed reminders. If missed found, fire alarms immediately and note the error. Next time, ask user to help prevent future mishaps by giving permissions or investigating system settings. Users will appreciate that you at least tried to recover from the problem and are aware of it.

8. Warn users on faulty devices

Warn users on faulty devices (Xiaomi, Samsung, OnePlus etc) and educate them on how to give permissions specific to their ROM. Check dontkillmyapp.com for details.

For example:

9. Use wake locks for critical alarms

Get wake lock permission, fire your alarm 10-30 mins earlier and hold a wake lock in a FGS until alarm is due. If alarm is delayed, you will have 10-30 mins of runway time. Also good way of priming users (“event coming up soon” notification).