fix(alarm): honor the persisted trigger on reschedule so app updates stop re-arming the wrong day
Build & Deploy PluriWave / Análisis de código (push) Successful in 40s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m30s

reschedulePersistedAlarms re-armed every stored alarm through the native
recompute engine (trustDartTrigger defaulted to false). That engine can
diverge from Dart's next-occurrence verdict and arm the alarm for the
wrong day, so it silently never fires. Because this runs on boot, unlock
and ACTION_MY_PACKAGE_REPLACED (which fires on every app install), each
new build re-broke correctly-armed alarms while snooze kept working
(snooze never touches the recompute for its trigger value).

Trust the persisted trigger (Dart's own verdict, saved when the alarm was
last armed) whenever it is still in the future; a genuinely stale past
trigger still falls back to the native recompute inside scheduleSpec.
This commit is contained in:
Javier Bautista Fernández
2026-07-14 15:18:38 +02:00
parent 448fbec354
commit 38d78fc4f8
@@ -688,7 +688,16 @@ class AlarmScheduler(private val context: Context) {
for (id in prefs().getStringSet(KEY_IDS, emptySet()).orEmpty()) {
val spec = readSpec(id) ?: continue
try {
scheduleSpec(spec, persistOnSuccess = true)
// Trust the persisted trigger (Dart's own verdict, saved when the
// alarm was last armed) instead of running the native recompute
// engine, which can diverge from Dart and leave the alarm armed
// for the wrong day so it silently never rings (see scheduleSpec
// and scheduleAlarm docs). This path runs on boot, unlock and
// ACTION_MY_PACKAGE_REPLACED (fires on every app update), so a
// recompute here re-broke a correctly-armed alarm on every
// install. A genuinely stale (past) trigger still falls back to
// the native recompute inside scheduleSpec.
scheduleSpec(spec, persistOnSuccess = true, trustDartTrigger = true)
Log.d(tag, "alarm.reschedule OK id=$id")
} catch (error: Throwable) {
Log.e(tag, "alarm.reschedule failed id=$id", error)