Files
daily-notification-plugin/docs/platform/android/ALARM_PERSISTENCE_DIRECTIVE.md
Matthew Raymer c39bd7cec6 docs: Consolidate documentation structure (139 files, zero information loss)
Consolidate all markdown documentation into organized structure per
CONSOLIDATION_DIRECTIVE. All files preserved (canonical, merged, or archived).

- docs/integration/ - Integration documentation (7 files)
- docs/platform/ios/ - iOS platform docs (12 files)
- docs/platform/android/ - Android platform docs (9 files)
- docs/testing/ - Testing documentation (15 files)
- docs/design/ - Design & research (5 files)
- docs/ai/ - AI/ChatGPT artifacts (7 files)
- docs/archive/2025-legacy-doc/ - Historical docs (17 files)

- Integration: Root INTEGRATION_GUIDE.md → docs/integration/
- Platform: Separated iOS and Android into platform/ subdirectories
- Testing: Consolidated all testing docs to docs/testing/
- Legacy: Archived entire doc/ directory to archive/
- AI: Moved all ChatGPT artifacts to docs/ai/

- Added docs/00-INDEX.md - Central navigation hub
- Added docs/CONSOLIDATION_SOURCE_MAP.md - Complete audit trail
- Added docs/CONSOLIDATION_COMPLETE.md - Consolidation summary
- Updated README.md with links to documentation index

- All 139 files have destinations (see CONSOLIDATION_SOURCE_MAP.md)
- Zero information loss (all files preserved)
- Archive preserves original structure
- Index provides clear navigation

- 87 files moved/created/updated
- Root-level docs consolidated
- Legacy doc/ directory archived
- Test app docs remain with test apps (indexed)

Ref: CONSOLIDATION_DIRECTIVE
Author: Matthew Raymer
2025-12-18 09:13:18 +00:00

7.0 KiB
Raw Blame History

Android Alarm Persistence, Recovery, and Limitations

⚠️ DEPRECATED: This document has been superseded by 01-platform-capability-reference.md as part of the unified alarm documentation structure.

See: Unified Alarm Directive 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-appstyle 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:

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



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