One widget for the battery level of all your Bluetooth devices.
Headphones, mouse, keyboard, controller, watch: every one of them seems to want its own companion app just so you can see how much battery is left. Or you dig through Bluetooth settings every time. UniBattery shows them all in one place, so a quick look at your home screen is enough.
This app is vibecoded. It was built almost entirely by prompting an AI (Claude) rather than written by hand. It works for what I need, but don't treat it as production-quality code. Issues and PRs are welcome.
- 🏠 Home-screen widget: all connected devices and their battery levels at a glance
- 📱 Dashboard app: Material 3 Expressive UI with an icon per device type
- 🕘 Last known battery: when a device isn't connected, the app and the widgets show the level it had last time, so you know whether to charge it before you connect
- 🎨 Customisable widgets: background opacity (all the way to 0%), corner roundness, text size, wallpaper or fixed colours, and whether to show last known levels
- 🔔 Optional notification: a silent, persistent notification that keeps the levels current
- 🎧 AirPods and Beats (Android 17+): exact battery levels through Apple's own protocol
- 🔒 Minimal permissions: no location, no scanning, only access to devices you have already paired
- Android 8.0 (API 26) or newer
- Bluetooth devices that actually report their battery level (most modern ones do)
There's no Play Store release. Download the latest APK from Releases, open it on your phone and allow installing from that source when asked.
Or build it yourself with Android Studio, or from the command line:
git clone https://github.com/IanBakeland/UniBattery.git
cd UniBattery
./gradlew :app:installDebug # build and install on a connected phone
./gradlew :app:testDebugUnitTest # run unit testsThen add a widget from your launcher's widget picker: Bluetooth battery (all devices), Device battery (one device) or All devices (compact) (a grid of rings for small sizes).
The app only shows a percentage when one of these sources actually reports one. Otherwise it says "Battery unavailable".
- Android's own per-device level (
BluetoothDevice.getBatteryLevel(), hidden in the SDK but reachable). It covers HFP/AVRCP headsets, Apple accessory reports and, on Android 14+, the LE Battery Service. - The system
BATTERY_LEVEL_CHANGEDbroadcast. - A direct GATT read of the standard Battery Service (
0x180F) on connected LE devices, for example mice and keyboards on older Android versions. - AirPods and Beats: Apple's own accessory protocol (AAP, an L2CAP channel on PSM
0x1001), kept open while they're connected so they push exact levels. Written from tyalie/AAP-Protocol-Definition. Android only allows this channel without root on versions newer than 16 QPR3, and apps can only open it through a hidden constructor, so UniBattery uses HiddenApiBypass for that one class (as LibrePods does).
Devices that only report battery through their own proprietary protocol (some earbuds with a companion app) won't show up with a level.
| Permission | Why |
|---|---|
BLUETOOTH_CONNECT (Android 12+) / BLUETOOTH (11 and lower) |
Read paired devices and their battery level. No scan, no location. |
POST_NOTIFICATIONS |
Only requested when you turn on the battery notification. |
FOREGROUND_SERVICE_CONNECTED_DEVICE |
The notification is a silent foreground service, so it stays current in the background. |
RECEIVE_BOOT_COMPLETED |
Restarts the notification after a reboot if you had it on. |
- Kotlin and Jetpack Compose (Material 3)
- Jetpack Glance for the widget
- Earbuds icon from Pictogrammers Material Design Icons (Apache-2.0)



0 comments
log in to comment.