Skip to content

Battery alert: stop re-firing the low-battery notification while charging (#80)#82

Merged
ryanbr merged 1 commit into
mainfrom
fix-battery-alert-charging
Jul 9, 2026
Merged

Battery alert: stop re-firing the low-battery notification while charging (#80)#82
ryanbr merged 1 commit into
mainfrom
fix-battery-alert-charging

Conversation

@ryanbr

@ryanbr ryanbr commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Fixes #80 — the "charge your strap" low-battery notification fires repeatedly while the strap is charging.

Root cause (both platforms — identical policy)

BatteryAlertPolicy already knew about charging, but the two conditions interacted badly:

  • re-armed the low flag on charging == true, yet
  • fired whenever charging != true (which includes the null/unknown state).

The strap reports its charge bit only on BATTERY_LEVEL events (~every 8 min), so charging flickers truenull between events:

  1. true read → re-arms low = false (no fire).
  2. null gap → !low is true, pct ≤ 15, charging != true is true → fires again.

Every flicker re-armed then re-fired → repeated notifications while plugged in.

Fix

Re-arm the low flag only on genuine recovery (pct >= lowRearmAbove), not on the charge bit:

- if (charging == true || pct >= LOW_REARM_ABOVE) low = false
+ if (pct >= LOW_REARM_ABOVE) low = false

fireLow's charging != true guard is untouched, so:

  • an explicit charging == true read still suppresses;
  • a strap that never reports a charge bit (charging == null, e.g. generic/FTMS) still gets low alerts (no regression);
  • charging still re-arms for the next cycle — via the recovered percentage once it climbs past 25%, not the flickering bit. A partial top-up that stays < 25% simply won't nag.

Applied identically to iOS (BatteryNotifier) and Android (BatteryAlertPolicy).

Tests

Updated the "charging suppresses low" case (charging must not re-arm now) and added a true→null flicker regression on both platforms. Android unit test green (testFullDebugUnitTest --tests BatteryAlertPolicyTest, exit 0). iOS is the byte-identical mirror (can't run on WSL — StrandTests → GRDB sqlite3.h wall — runs in CI).

Files: Strand/System/BatteryNotifier.swift, StrandTests/BatteryAlertPolicyTests.swift, android/.../BatteryAlertNotifier.kt, android/.../BatteryAlertPolicyTest.kt.

…ing (#80)

The low-battery alert re-fired repeatedly WHILE the strap was charging. The policy
re-armed the low flag on `charging == true` but fired whenever `charging != true`
(which includes the null/unknown state). The strap reports its charge bit only on
BATTERY_LEVEL events (~every 8 min), so it flickers true→null between events: a
`true` read re-armed the flag, then the `null` gap re-fired the alert — on every
flicker, while plugged in.

Fix (both platforms, identical): re-arm the low flag ONLY on genuine recovery
(pct >= lowRearmAbove), not on the charge bit. `fireLow`'s `charging != true` guard
is unchanged, so an explicit charging read still suppresses and a strap that never
reports a charge bit (generic/FTMS, charging == null) still alerts. Charging still
re-arms for the next cycle — via the recovered PERCENTAGE once it climbs past 25%,
not the flickering bit.

Tests: updated the "charging suppresses" case (charging must NOT re-arm) and added
a true→null flicker regression on both iOS and Android. Android unit test green.
@ryanbr ryanbr merged commit 0ef8f05 into main Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"Charge Strap" notification when strap battery is low, even if the strap is charging

1 participant