Repository navigation
Re-arm alarms on every app start, and report when Android has dropped them - #3
Merged
Merged
Conversation
… them Third report of an alarm set hours ahead not ringing while one set minutes ahead works. That difference points at the schedule being lost rather than the ring path failing, and there was a real gap behind it. AlarmManager entries survive ordinary process death but not a force-stop, and force-stopping idle apps is what OEM battery managers do. Nothing tells an app it happened. rescheduleAll() was only ever called from BootReceiver, so a dropped schedule stayed dropped until the next reboot while the alarm list went on showing the alarm as enabled - a silent inconsistency whose only symptom is not waking up. HaAlarmClockApp.onCreate now re-arms everything on every process start. Rescheduling is idempotent, so this is just a repair pass that any run of the app performs. Adds ScheduleHealth, which compares the app's next trigger against AlarmManager.getNextAlarmClock() - the same source as the status-bar alarm icon - and surfaces the result in Settings with a Re-arm button, so a dropped schedule is visible instead of silent. That API reports the next alarm clock across all apps, so it is conclusive in only two directions; when another app has a sooner alarm the check reports that rather than guessing. Also documents the limit honestly: an app cannot make itself force-stop-proof, and once Android force-stops it nothing of its own runs again until something launches it. The README now describes the redundancy that does close that gap - a Home Assistant backup automation firing when the alarm time passes with no ring reported, on hardware the phone's battery manager has no say over. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01C7x8v5c5Lu29PBWy1LdfCe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The gap
An alarm set 10 hours ahead didn't ring; one set minutes ahead did. That difference points at the schedule being lost, not the ring path failing — the ring path demonstrably works.
AlarmManagerentries survive ordinary process death, but not a force-stop — and force-stopping idle apps is exactly what OEM battery managers do. Nothing notifies an app that it happened.rescheduleAll()was only ever called fromBootReceiver. So once the OS dropped this app's alarms, they stayed dropped until the next reboot, while the alarm list went on showing them as enabled. A silent inconsistency whose only symptom is not waking up.Changes
Re-arm on every process start.
HaAlarmClockApp.onCreatenow re-arms alarms and timers, not justBootReceiver. Rescheduling replaces the existing entry, so this is an idempotent repair pass that any run of the app performs.Make a dropped schedule visible. New
ScheduleHealthcompares the app's next trigger againstAlarmManager.getNextAlarmClock()— the same source as the status-bar alarm icon — and Settings shows the result with a Re-arm button. That API reports the next alarm clock across all apps, so it's conclusive in only two directions; when another app has a sooner alarm the check says so rather than guessing.The honest limit
An app cannot make itself force-stop-proof. Once Android force-stops it, the alarms are cancelled and nothing belonging to it runs again — no service, no receiver, no
WorkManagerjob, no watchdog — until something launches it. Everything above improves the odds and makes failure visible. None of it makes ringing certain.What does close the gap is redundancy off the phone, which this project is unusually well placed for: Home Assistant already knows the next alarm time and whether the phone reported ringing. The README now carries a backup automation that fires when the alarm time passes with no ring reported — a second alarm on hardware the phone's battery manager has no say over.
Not verified
Uncompiled here, as usual —
./gradlew assembleDebugfirst.Generated by Claude Code