The notification light your phone forgot.
A soft ring glows around the camera hole when something needs you, on any brand, at almost no battery cost.
Most phones dropped the notification LED. Glow LED draws one around the front camera (punch-hole, pill, notch, or a dot on phones without a cutout): while you use the phone, on the lock screen, and while the screen is "off", on a pure black screen. On AMOLED black pixels are switched off, so only the light itself uses power.
| 🔔 Notifications A ring in each app's colour, split when several apps are waiting. A drop falls into the app's icon when a message arrives. |
🌙 Screen off Black always-on screen with AOD-style app icons. Tap one to read the message, Reply or Mark as read. |
⚡ Charging The ring fills with your battery level, with a bolt that flares on every 1 %. |
| ↓ Downloads & uploads Progress fills the ring with a small arrow. Set the arrow per app; well-known apps already know their way. |
🎨 11 animations Pulse, Breathe, Blink, Heartbeat, Spinner, Rainbow, Static, Edge lighting, Edge pulse, Twin orbit, Sparkle. |
🔋 Battery first Event-driven, no foreground service, frame cap, a still ring after 12 s and lights that wait for the phone to move. |
| 📱 iPhone-style settings Grouped lists, sliding switches, one-handed pull-down, light mode, haptics, 120 Hz. |
⬆ Built-in updater Checks for new versions, shows the changelog and installs inside the app. A notification tells you when one is out. |
🌍 13 languages English, Español, Français, Deutsch, Italiano, Português, Русский, Türkçe, العربية, हिन्दी, Indonesia, 日本語, 简体中文. |
| Always-on light | Tap to read | Charging |
|---|---|---|
![]() |
![]() |
![]() |
| Setup | Style | Screen off |
![]() |
![]() |
![]() |
| Screen on | Pull down: See it in action | Settings |
![]() |
![]() |
![]() |
| Per-app arrows | One app | If unknown |
![]() |
![]() |
![]() |
| Update available | Up to date | Light mode |
![]() |
![]() |
![]() |
More: rings, bolt flare, droplet, Português
Rings with icons: charging (bolt), download (↓), upload (↑) and an optional ↕ for an unknown direction. The icon sits in a small gap at the bottom of the ring, in the ring's colour.
Bolt flare: each time the battery goes up 1 %, the bolt grows and glows for a moment (left: resting, right: flaring).
Droplet: a drop in the app's colour stretches out of the camera, falls into the icon row and becomes the app's icon.
Português (Brasil)
- Download GlowLED-latest.apk and open it.
- Open Glow LED and go through Setup: Notification access (required), Display over other apps, Unrestricted battery, and on Xiaomi/OPPO/vivo and similar Autostart. Accessibility is optional.
- Style → Camera position → Auto-detect, then tap the floating Test pill and turn the screen off.
Later versions install from Settings → Updates, inside the app. Every APK is signed with the
official key (SHA-256 5D:04:DE:1A…0C:50:23), so updates keep your settings.
"App blocked to protect your device" (Play Protect)
In India and some other countries, Play Protect blocks apps installed from a browser, messaging app or file manager when they ask for Notification access, which Glow LED needs. It is not a warning about the app's code. Either:
- On the phone: Play Store → profile picture → Play Protect → ⚙ → turn off Scan apps with Play Protect → install → turn it back on straight away.
- With a computer:
adb install GlowLED-latest.apk, then turn Developer options off again.
Android 13+ "Restricted setting"
Apps installed from an APK can't turn on Accessibility straight away. Open Settings → Apps → Glow LED → ⋮ → Allow restricted settings, then try again.
"App not installed" when updating
Your phone has an early build signed with a different key (v1.0.0–v1.2.0). Back up your settings (Settings → Back up), uninstall Glow LED, install the latest APK and restore. Only needed once.
Banking apps
Glow LED has no root or Shizuku code. Some banking apps refuse to open while Developer options / debugging are on, or while an accessibility service from outside the Play Store is on. Glow LED's accessibility is optional: Setup → Accessibility → Turn off. Over apps the ring is a normal overlay that banking apps can hide. A "Play Integrity" failure comes from the phone (unlocked bootloader or root), not from apps.
| Problem | Fix |
|---|---|
| Test does nothing | Make sure Notification access shows a tick in Setup. Glow LED reconnects it by itself after an update; Settings → Event log says why a light was skipped. |
| The lock screen flashes before the light (Xiaomi/HyperOS) | Screen off → Screen-off method → Auto, turn on Accessibility, then the Xiaomi lock-screen step. |
| The light stops after a while | Battery Unrestricted and Autostart on (Setup). On Xiaomi also lock the app in Recents. |
| The ring is slightly off-centre | Style → Camera position, then nudge with the arrows. |
| The screen stays on after the light | Without Accessibility the screen turns off at your normal timeout. |
| Nothing for one app | Alerts → Apps: check it is on; silent notifications are ignored unless you turn off Ignore silent. |
| No charging ring with the screen off | Turn on Charging ring and Screen-off light; Charging when off keeps it on. |
Glow LED uses the internet for one thing only: checking GitHub for a new version and downloading it when you ask. Message text for the tap-to-read card stays in memory only: never stored, logged or sent, and gone when the notification is. Turn off Tap to read to stop reading message text at all.
How it works (for developers)
NotificationListenerService ──► NotificationStore ──► LedController
(system-bound, no polling) (unseen notifications, │
one colour each) ├── screen ON → OverlayHost → LedView
└── screen OFF → AodOverlay / AodActivity → LedView
- Screen on and off: with Accessibility the always-on screen is an accessibility overlay and the
panel wakes only after its first black frame (no lock-screen flash on HyperOS). Without it,
AodActivity(showWhenLocked+turnScreenOn) is used. - Rendering:
LedViewbuilds onePathfor the cutout and animatesPathMeasuresegments, allocating nothing per frame and drawing only as often as the style needs. - Cutout:
Display.getCutout(), plusgetCutoutPath()on Android 12+ for the exact hole; the position scales when the screen resolution changes. - Updater: reads the latest GitHub release, checks the APK is newer and signed with the release
key, and installs it with
PackageInstaller.
Build (JDK 17+, Android SDK 35):
./gradlew assembleDebug # debug APK
./gradlew testDebugUnitTest # unit tests
./gradlew lintDebug # lint













