Skip to content

fix(widget): fix battery widget charging status not updating (#1269) - #1671

Open
ArunaK-netizen wants to merge 1 commit into
sameerasw:developfrom
ArunaK-netizen:fix/battery-widget-not-updating-on-charge
Open

ArunaK-netizen wants to merge 1 commit into
sameerasw:developfrom
ArunaK-netizen:fix/battery-widget-not-updating-on-charge

Conversation

@ArunaK-netizen

Copy link
Copy Markdown

Resolve #1269 where existing battery widgets fail to update charging status on charger connect/disconnect.

  • Overcome Android 8.0+ implicit broadcast restrictions for power connect/disconnect by registering a dynamic BroadcastReceiver in EssentialsApp for 0ms in-memory updates and adding BatteryWidgetJobService (JobScheduler requiresCharging) for background wakeup.
  • Fix Glance stale DataStore preference poisoning where cached false locked existing widgets by dynamically reading the sticky Intent.ACTION_BATTERY_CHANGED and BatteryManager in provideGlance.
  • Force Glance RemoteViews recomposition by updating a timestamp key across all GlanceIds in updateWidgets.
  • Fix crash on widget placement by safely guarding goAsync execution.
  • Update widget on user present (screen unlock) and status bar automation events.

Description

Closes #1269

This PR fixes an issue where existing home-screen battery widgets failed to update their charging state (lightning bolt and charging ring) when plugging in or unplugging the charger.

Technical Details:

  1. Dynamic Battery State in Glance (BatteriesWidget.kt): Previously, provideGlance fell back to a cached boolean in DataStore. Once the phone was unplugged, false was saved; because false != null, existing widgets were permanently locked into false, ignoring actual hardware status (while newly placed widgets with null preferences rendered correctly). The widget now directly inspects the sticky Intent.ACTION_BATTERY_CHANGED intent and BatteryManager.isCharging.
  2. Android 8.0+ Implicit Broadcast Wall (EssentialsApp.kt & BatteryWidgetJobService.kt): Manifest receivers for implicit broadcasts like ACTION_POWER_CONNECTED are dropped by Android OS when the app is in the background. We resolved this across three tiers:
    • Dynamic BroadcastReceiver in EssentialsApp for 0ms latency when the app is in memory.
    • BatteryWidgetJobService (JobScheduler with setRequiresCharging(true)) to wake up and refresh the widget when connected even if the app process was terminated.
    • ACTION_USER_PRESENT in BatteriesWidgetReceiver to refresh widgets immediately when unlocking the screen.
  3. Glance Recomposition (BatteriesWidgetReceiver.kt): Added a timestamp key (widget_last_update_ts) so Glance detects state changes and recomposes RemoteViews. Also guarded goAsync() calls to prevent IllegalStateException crashes during initial widget placement.

Type of change

  • Bug fix
  • New feature
  • UI / visual update
  • Performance improvement
  • Refactoring / cleanup
  • Translations
  • Build / CI tooling

UI changes

Before After
before.mp4
after.mp4

Checklist

Before submitting, please make sure:

  • The base branch is set to develop (not main).
  • The app builds cleanly locally with ./gradlew assembleDebug.
  • Unit tests pass with ./gradlew testDebugUnitTest.
  • You tested the changes on a device or emulator (including Shizuku or Root if applicable).
  • New preferences use SettingsRepository for keys and getter/setter methods.
  • New user-facing settings are registered in FeatureRegistry.kt for search indexing.
  • New UI follows the design system in ui/core/ (RoundedCardContainer, IconToggleItem, etc.).
  • Strings are added to res/values/strings.xml and drawables use rounded variants (R.drawable.rounded_*).

…sw#1269)

Resolve sameerasw#1269 where existing battery widgets fail to update charging status on charger connect/disconnect.

- Overcome Android 8.0+ implicit broadcast restrictions for power connect/disconnect by registering a dynamic BroadcastReceiver in EssentialsApp for 0ms in-memory updates and adding BatteryWidgetJobService (JobScheduler requiresCharging) for background wakeup.
- Fix Glance stale DataStore preference poisoning where cached false locked existing widgets by dynamically reading the sticky Intent.ACTION_BATTERY_CHANGED and BatteryManager in provideGlance.
- Force Glance RemoteViews recomposition by updating a timestamp key across all GlanceIds in updateWidgets.
- Fix crash on widget placement by safely guarding goAsync execution.
- Update widget on user present (screen unlock) and status bar automation events.
@ArunaK-netizen
ArunaK-netizen force-pushed the fix/battery-widget-not-updating-on-charge branch from 731603b to dad3e8e Compare November 6, 2026 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant