导航栏电量显示必须绕过uni.getBatteryInfo:App端Android用sticky广播监听ACTION_BATTERY_CHANGED并校验level/scale,iOS需先启用监控;小程序无法获取真实电量,应条件编译隐藏。

导航栏里显示电量,不能靠 uni.getBatteryInfo
Vue2 项目中这个 API 是个“静默失效”陷阱:调了没反应,不进 success 也不进 fail,控制台无报错;Vue3 虽能触发回调,但依赖插件、Android/iOS 行为不一致,真机上容易返回 null 或 -1。导航栏需要稳定、实时、跨平台可读的值,必须绕过它。
App 端电量获取:Android 用 sticky 广播,iOS 必须先启用监控
Android 要读 ACTION_BATTERY_CHANGED 广播里的 level 和 scale,不能用 BatteryManager.BATTERY_PROPERTY_CAPACITY(Android 10+ 上基本返回 0);iOS 则必须先调 dev.setBatteryMonitoringEnabled(true),否则 dev.batteryLevel() 永远是 -1.0。
- Android 权限缺
android.permission.BATTERY_STATS→ 真机直接闪退(不是报错) - 注册广播时
registerReceiver第一个参数不能传null,得用plus.android.implements('android.content.BroadcastReceiver')实现一个真实 receiver 类 - level 可能为
-1,scale 可能为0,计算前要 guard:if (level > 0 && scale > 0) { Math.floor((level / scale) * 100) } - iOS 模拟器永远返回
false和-1.0,不连真机测不出结果
微信小程序端:无法读取真实电量,只能隐藏或留空
小程序平台不开放电池状态 API,wx.getBatteryInfo 在基础库 2.27.0+ 才有,且仅部分安卓机型支持,iOS 完全不可用。你在导航栏里放电量图标或数字,对小程序用户来说注定是“固定值”或“-”。
- 如果坚持统一 UI,建议在小程序环境直接隐藏电量区域:
v-if="!uni.getSystemInfoSync().platform.startsWith('ios') && !uni.getSystemInfoSync().platform.startsWith('android')"不够准,更可靠的是用条件编译:#ifdef MP-WEIXIN - 别试图用 canvas 或定时器模拟“电量下降动画”——既无依据,又误导用户
把电量塞进导航栏:高度、刷新、样式三处易翻车
导航栏本身是自定义的(navigationStyle: "custom"),电量显示区域要嵌入其中,不是加个 text 就完事。常见坑点:
- 电量文本高度未适配状态栏:需用
uni.getSystemInfoSync().statusBarHeight动态算出顶部安全距离,否则在 iPhone X+ 上被刘海吞掉 - 电量值更新不及时:App 端不能只 onload 读一次,得用
setInterval轮询(Android 建议 10–30s 间隔,iOS 建议 60s 以上,避免后台耗电) - 颜色冲突:电量数字若用白色,但导航栏背景是浅色,就得同步改
navigationBarTextStyle或手动加color样式,不能指望全局配置自动生效
最麻烦的其实是“一致性”——App 端能拿到真实值,小程序端拿不到,H5 根本没这个概念。一旦你把电量作为导航栏核心元素,就等于主动放弃多端视觉统一。真正落地的做法,是把它做成可选模块,按平台能力降级:App 显示数值,小程序显示图标+文字“电量”,H5 隐藏。


















