# Android Alarm Persistence, Recovery, and Limitations **⚠️ DEPRECATED**: This document has been superseded by [01-platform-capability-reference.md](./alarms/01-platform-capability-reference.md) as part of the unified alarm documentation structure. **See**: [Unified Alarm Directive](./alarms/000-UNIFIED-ALARM-DIRECTIVE.md) for the new documentation structure. **Author**: Matthew Raymer **Date**: November 2025 **Status**: **DEPRECATED** - Superseded by unified structure ## Purpose This document provides a **clean, consolidated, engineering-grade directive** summarizing Android's abilities and limitations for remembering, firing, and restoring alarms across: - App kills - Swipes from recents - Device reboot - **Force stop** - User-triggered reactivation This is the actionable version you can plug directly into your architecture docs. --- ## 1. Core Principle Android does **not** guarantee persistence of alarms across process death, swipes, or reboot. It is the app's responsibility to **persist alarm definitions** and **re-schedule them** under allowed system conditions. The following directives outline **exactly what is possible** and **what is impossible**. --- ## 2. Allowed Behaviors (What *Can* Work) ### 2.1 Alarms survive UI kills (swipe from recents) `AlarmManager.setExactAndAllowWhileIdle(...)` alarms **will fire** even after: - App is swiped away - App process is killed by the OS The OS recreates your app's process to deliver the `PendingIntent`. **Directive:** Use `setExactAndAllowWhileIdle` for alarm execution. --- ### 2.2 Alarms can be preserved across device reboot Android wipes all alarms on reboot, but **you may recreate them**. **Directive:** 1. Persist all alarms in storage (Room DB or SharedPreferences). 2. Add a `BOOT_COMPLETED` / `LOCKED_BOOT_COMPLETED` broadcast receiver. 3. On boot, load all enabled alarms and reschedule them using AlarmManager. **Permissions required:** - `RECEIVE_BOOT_COMPLETED` **Conditions:** - User must have launched your app at least once before reboot to grant boot receiver execution. --- ### 2.3 Alarms can fire full-screen notifications and wake the device **Directive:** Implement `setFullScreenIntent(...)`, use an IMPORTANCE_HIGH channel with `CATEGORY_ALARM`. This allows Clock-app–style alarms even when the app is not foregrounded. --- ### 2.4 Alarms can be restored after app restart If the user re-opens the app (direct user action), you may: - Scan the persistent DB - Detect "missed" alarms - Reschedule future alarms - Fire "missed alarm" notifications - Reconstruct WorkManager/JobScheduler tasks wiped by OS **Directive:** Create a `ReactivationManager` that runs on every app launch and recomputes the correct alarm state. --- ## 3. Forbidden Behaviors (What *Cannot* Work) ### 3.1 You cannot survive "Force Stop" **Settings → Apps → YourApp → Force Stop** triggers: - Removal of all alarms - Removal of WorkManager tasks - Blocking of all broadcast receivers (including BOOT_COMPLETED) - Blocking of all JobScheduler jobs - Blocking of AlarmManager callbacks - Your app will NOT run until the user manually launches it again **Directive:** Accept that FORCE STOP is a hard kill. No scheduling, alarms, jobs, or receivers may execute afterward. --- ### 3.2 You cannot auto-resume after "Force Stop" You may only resume tasks when: - The user opens your app - The user taps a notification belonging to your app - The user interacts with a widget/deep link - Another app explicitly targets your component **Directive:** Provide user-facing reactivation pathways (icon, widget, notification). --- ### 3.3 Alarms cannot be preserved solely in RAM Android can kill your app's RAM state at any time. **Directive:** All alarm data must be persisted in durable storage. --- ### 3.4 You cannot bypass Doze or battery optimization restrictions without permission Doze may defer inexact alarms; exact alarms with `setExactAndAllowWhileIdle` are allowed. **Directive:** Request `SCHEDULE_EXACT_ALARM` on Android 12+. --- ## 4. Required Implementation Components ### 4.1 Persistent Storage Create a table or serialized structure for alarms: ``` id: Int timeMillis: Long repeat: NONE | DAILY | WEEKLY | CUSTOM label: String enabled: Boolean ``` --- ### 4.2 Alarm Scheduling Use: ```kotlin alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent ) ``` --- ### 4.3 Boot Receiver Reschedules alarms from storage. --- ### 4.4 Reactivation Manager Runs on **every app launch** and performs: - Load pending alarms - Detect overdue alarms - Reschedule future alarms - Trigger notifications for missed alarms --- ### 4.5 Full-Screen Alarm UI Use a `BroadcastReceiver` → Notification with full-screen intent → Activity. --- ## 5. Summary of Android Alarm Capability Matrix | Scenario | Will Alarm Fire? | Reason | | --------------------------------------- | --------------------------------------- | --------------------------------------------------------------- | | **Swipe from Recents** | ✅ Yes | AlarmManager resurrects the app process | | **App silently killed by OS** | ✅ Yes | AlarmManager still holds scheduled alarms | | **Device Reboot** | ❌ No (auto) / ✅ Yes (if you reschedule) | Alarms wiped on reboot | | **Doze Mode** | ⚠️ Only "exact" alarms | Must use `setExactAndAllowWhileIdle` | | **Force Stop** | ❌ Never | Android blocks all callbacks + receivers until next user launch | | **User reopens app** | ✅ You may reschedule & recover | All logic must be implemented by app | | **PendingIntent from user interaction** | ✅ If triggered by user | User action unlocks the app | --- ## 6. Final Directive > **Design alarm behavior with the assumption that Android will destroy all scheduled work on reboot or force-stop. > > Persist all alarm definitions. On every boot or app reactivation, reconstruct and reschedule alarms. > > Never rely on the OS to preserve alarms except across UI process kills. > > Accept that "force stop" is a hard stop that cannot be bypassed.** --- ## Related Documentation - [Boot Receiver Testing Guide](./boot-receiver-testing-guide.md) - [App Startup Recovery Solution](./app-startup-recovery-solution.md) - [Reboot Testing Procedure](./reboot-testing-procedure.md) --- ## Future Directives Potential follow-up directives: - **How to implement the minimal alarm system** - **How to implement a Clock-style robust alarm system** - **How to map this to your own app's architecture**