# 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**

