HarmonyOS NEXT 电池信息全解析:@ohos.batteryInfo 设备健康诊断实战
引言
电池是移动设备的"心脏"。无论是开发系统工具类应用、性能监控面板,还是做电量敏感的功耗优化,都需要精准掌握设备的电池状态。HarmonyOS NEXT 提供了 @ohos.batteryInfo 模块,它以同步常量的形式暴露设备的电池信息——电量、充电状态、健康度、温度、电压、电流等十余项关键指标。
相比 @ohos.wifiManager 和 @ohos.window 这些需要处理 Promise 的模块,batteryInfo 的使用方式更加直观:所有属性都是可直接读取的常量,无需 await,无需 .then(),一行代码即可获取数据。
本文将以"电池健康实验室"Demo 为线索,逐一拆解 @ohos.batteryInfo 的全部属性,并探讨如何将这些数据组织为一个实用、美观的电池诊断面板。
@ohos.batteryInfo 模块概述
@ohos.batteryInfo 是 HarmonyOS NEXT 提供的电池信息查询模块,位于 @kit.BasicServicesKit 工具包。它的设计哲学非常简洁:将设备的电池状态封装为一组同步可读的常量,开发者无需任何异步操作即可获取完整信息。
导入方式
import batteryInfo from '@ohos.batteryInfo';
与 wifiManager 一致,采用 default import。
API 全貌
| 属性 | 类型 | 单位 | 说明 |
|---|---|---|---|
batterySOC |
number | % (0-100) | 当前电量百分比 |
chargingStatus |
BatteryChargeState | 枚举 | 充电状态 |
healthStatus |
BatteryHealthState | 枚举 | 电池健康状态 |
pluggedType |
BatteryPluggedType | 枚举 | 充电器类型 |
batteryTemperature |
number | 0.1°C | 电池温度 |
voltage |
number | µV | 电池电压 |
nowCurrent |
number | mA | 瞬时电流(API 12+) |
batteryCapacityLevel |
BatteryCapacityLevel | 枚举 | 电量等级 |
technology |
string | — | 电池技术(如 Li-poly) |
isBatteryPresent |
boolean | — | 电池是否存在 |
全部同步可用——这是 batteryInfo 最显著的特征。你可以在组件初始化、事件回调、定时器中的任意位置直接读取这些值。
核心属性详解
1. batterySOC — 电量百分比
const batterySOC: number;
这是最常用的电池指标,返回一个 0 到 100 的整数,表示当前剩余电量百分比。它是 UI 中"电池电量"显示的直接数据源。
const level: number = batteryInfo.batterySOC;
console.log('当前电量: ' + level + '%');
注意:batterySOC 的值可能受系统电量显示策略影响——部分厂商会在 UI 层做"平滑处理",导致 API 返回的百分比与状态栏显示的百分比存在微小偏差。
2. chargingStatus — 充电状态
const chargingStatus: BatteryChargeState;
BatteryChargeState 是一个枚举,包含四种充电状态:
| 枚举值 | 数值 | 含义 | UI 表现建议 |
|---|---|---|---|
NONE |
0 | 未知状态 | 灰色问号 |
ENABLE |
1 | 充电中 | 绿色闪电图标 |
DISABLE |
2 | 未充电(放电中) | 橙色电池图标 |
FULL |
3 | 已充满 | 绿色对勾图标 |
Demo 中的判断逻辑:
private chargeLabel(s: batteryInfo.BatteryChargeState): string {
if (s === batteryInfo.BatteryChargeState.NONE) return '未知';
if (s === batteryInfo.BatteryChargeState.ENABLE) return '充电中';
if (s === batteryInfo.BatteryChargeState.DISABLE) return '未充电';
if (s === batteryInfo.BatteryChargeState.FULL) return '已充满';
return '—';
}
实战技巧:不要使用 === 1 这样的魔法数字。始终使用枚举值(如 BatteryChargeState.ENABLE)进行比较,这既增强可读性,又避免因枚举值变更导致的 bug。
3. healthStatus — 电池健康状态
const healthStatus: BatteryHealthState;
这是判断电池是否需要更换的关键指标。BatteryHealthState 包含六种状态:
| 枚举值 | 含义 | 严重程度 |
|---|---|---|
UNKNOWN |
未知 | 灰 |
GOOD |
良好 | 绿 — 正常 |
OVERHEAT |
过热 | 红 — 需要降温 |
OVERVOLTAGE |
电压过高 | 红 — 充电异常 |
COLD |
温度过低 | 橙 — 影响续航 |
DEAD |
电池损坏 | 红 — 需要更换 |
温度与健康的关系:OVERHEAT 和 COLD 两种状态与 batteryTemperature 联动。当温度超出安全范围时,系统会自动将健康状态标记为异常。锂电池的最佳工作温度在 20°C ~ 35°C,极端温度会加速电池老化。
Demo 中的颜色映射:
private healthColor(): string {
if (this.healthEnum === batteryInfo.BatteryHealthState.GOOD) return '#10B981'; // 绿
if (this.healthEnum === batteryInfo.BatteryHealthState.UNKNOWN) return '#94A3B8'; // 灰
return '#EF4444'; // 红 — 所有异常状态
}
4. pluggedType — 充电器类型
const pluggedType: BatteryPluggedType;
这个属性告诉你设备是如何充电的,对于功耗分析和充电策略优化很重要。
| 枚举值 | 含义 | 典型场景 |
|---|---|---|
NONE |
未连接充电器 | 电池供电 |
AC |
交流电源 | 充电器直插 |
USB |
USB 充电 | 电脑/移动电源 |
WIRELESS |
无线充电 | Qi 充电板 |
充电功率提示:AC 充电通常意味着更高的充电功率(快充),USB 充电受限于接口功率(通常 5V/500mA 或 5V/1A),无线充电效率较低但更方便。你可以在应用中根据充电器类型向用户展示预估充满时间。
5. batteryTemperature — 电池温度
const batteryTemperature: number; // 单位:0.1°C
这是最容易被用错的属性。 batteryTemperature 的单位是 0.1°C,不是 °C。必须除以 10 才能得到摄氏度值:
// 错误写法!
const temp: number = batteryInfo.batteryTemperature;
console.log('电池温度: ' + temp + '°C'); // 显示 350°C??
// 正确写法
const tempC: number = batteryInfo.batteryTemperature / 10;
console.log('电池温度: ' + tempC.toFixed(1) + '°C'); // 35.0°C
为什么使用 0.1°C 为单位? 这是嵌入式系统的常见做法——用整数代替浮点数,避免浮点运算开销,同时保留一位小数精度。类似的设计在 Android 的 BatteryManager.EXTRA_TEMPERATURE 中也能看到。
6. voltage — 电池电压
const voltage: number; // 单位:µV(微伏)
与温度类似,voltage 使用了一个"非直觉"的单位——微伏(µV)。标准锂电池电压约 3.7V(即 3,700,000 µV)。转换为可读格式:
const voltageV: number = batteryInfo.voltage / 1000000;
console.log('电池电压: ' + voltageV.toFixed(3) + ' V'); // 3.702 V
电压与电量的关系:锂电池的电压并非恒定不变——满电时约 4.2V,放电至 3.0V 左右自动关机。电压是判断电池剩余容量的物理依据,但系统已经将其封装为更直观的 batterySOC 百分比。
7. nowCurrent — 瞬时电流
const nowCurrent: number; // 单位:mA(毫安)
nowCurrent 是 API 12 新增的属性,表示电池当前的瞬时电流。正值表示充电电流,负值表示放电电流。这个数据对于电池健康监控应用至关重要——它可以用来:
- 计算实时功耗(结合电压):
power_mW = |nowCurrent| * voltage / 1000 - 检测快充是否激活(电流 > 2000mA 通常意味着快充)
- 异常电流告警(电流突增可能意味着应用异常耗电)
const current: number = batteryInfo.nowCurrent;
if (current > 2000) {
console.log('快充已激活 (电流: ' + current + ' mA)');
} else if (current > 0) {
console.log('普通充电中 (电流: ' + current + ' mA)');
} else if (current < 0) {
console.log('放电中 (电流: ' + Math.abs(current) + ' mA)');
}
8. batteryCapacityLevel — 电量等级
const batteryCapacityLevel: BatteryCapacityLevel;
除了精确的百分比,系统还提供了一个语义化的电量等级,适合用于通知和 UI 决策:
| 枚举值 | 含义 | 建议动作 |
|---|---|---|
LEVEL_FULL |
满电 | 可断开充电器 |
LEVEL_HIGH |
高电量 (≥60%) | 正常使用 |
LEVEL_NORMAL |
正常 (20%-60%) | 正常使用 |
LEVEL_LOW |
低电量 (10%-20%) | 建议开启省电模式 |
LEVEL_WARNING |
电量警告 (5%-10%) | 提示用户充电 |
LEVEL_CRITICAL |
严重低电 (3%-5%) | 强制省电 |
LEVEL_SHUTDOWN |
即将关机 (❤️%) | 保存数据,即将关机 |
这个等级比百分比更适合用于用户通知——"电量低"比"电量 12%"更具可操作性。
9. technology 与 isBatteryPresent
const technology: string; // 如 "Li-poly"(锂聚合物)、"Li-ion"(锂离子)
const isBatteryPresent: boolean; // 电池是否存在
technology标识电池的化学类型。目前主流移动设备使用锂聚合物(Li-poly)或锂离子(Li-ion)电池isBatteryPresent在普通手机/平板上始终为true,但在某些可拆卸电池设备或开发板上可能为false
实战:电池健康实验室
页面结构设计
整个页面分为六个区域:
┌─────────────────────────────────┐
│ < 电池健康实验室 @ohos.batteryInfo │ ← 标题栏(#10B981 翠绿)
├─────────────────────────────────┤
│ 电池电量 │
│ ┌─────────────────────────┐ │
│ │ ┌──┐ │ │ ← 圆形电量仪表 + 充电信息
│ │ │85│% 充电状态 充电中 │ │ 左侧:大数字电量百分比
│ │ └──┘ 充电器 交流电源 │ │ 右侧:充电状态/充电器/电流
│ │ 当前电流 1580mA │ │
│ └─────────────────────────┘ │
├─────────────────────────────────┤
│ 电池详情 │
│ ┌─────────────────────────┐ │
│ │ 健康状态 良好 温度 35.2°C│ ← 四宫格详情
│ │ 电压 3.702V 电池技术 Li-poly│
│ │ 电池存在 是 容量等级 高电量│
│ └─────────────────────────┘ │
├─────────────────────────────────┤
│ 充电与健康可视化 │
│ ┌─────────────────────────┐ │
│ │ ● 充电中 ● 良好 │ ← 双栏状态 + 建议文案
│ │ 设备正在充电... 电池状态良好│
│ └─────────────────────────┘ │
├─────────────────────────────────┤
│ [ 刷新电池数据 ] │ ← 操作按钮
├─────────────────────────────────┤
│ 操作日志 │ ← 时间戳日志列表
└─────────────────────────────────┘
状态管理
@State batterySOC: number = 0;
@State chargingStatus: string = '—';
@State chargingEnum: number = -1; // 保存枚举值用于颜色判断
@State healthStatus: string = '—';
@State healthEnum: number = -1; // 保存枚举值用于颜色判断
@State pluggedType: string = '—';
@State voltageText: string = '—';
@State temperatureText: string = '—';
@State technology: string = '—';
@State isBatteryPresent: boolean = false;
@State capacityLevel: string = '—';
@State nowCurrent: string = '—';
@State eventLogs: EventLog[] = [];
@State loading: boolean = true;
设计要点:除了中文标签(chargingStatus),还保留了原始的枚举值(chargingEnum)。这是因为后续的颜色逻辑需要根据枚举值判断——例如 BatteryChargeState.ENABLE 显示绿色,BatteryChargeState.DISABLE 显示橙色。如果仅保留中文字符串,就无法进行枚举比较。
数据读取:一读全读
由于所有属性都是同步常量,数据读取极其简洁——一个方法完成全部:
private loadBattery(): void {
this.addLog('开始读取电池信息...');
try {
this.batterySOC = batteryInfo.batterySOC;
this.chargingEnum = batteryInfo.chargingStatus;
this.chargingStatus = this.chargeLabel(batteryInfo.chargingStatus);
this.healthEnum = batteryInfo.healthStatus;
this.healthStatus = this.healthLabel(batteryInfo.healthStatus);
this.pluggedEnum = batteryInfo.pluggedType;
this.pluggedType = this.pluggedLabel(batteryInfo.pluggedType);
const voltageV: number = batteryInfo.voltage / 1000000;
this.voltageText = voltageV.toFixed(3) + ' V';
const tempC: number = batteryInfo.batteryTemperature / 10;
this.temperatureText = tempC.toFixed(1) + ' °C';
this.technology = batteryInfo.technology !== '' ? batteryInfo.technology : '未知';
this.isBatteryPresent = batteryInfo.isBatteryPresent;
this.capacityLevel = this.capacityLabel(batteryInfo.batteryCapacityLevel);
const current: number = batteryInfo.nowCurrent;
this.nowCurrent = current !== 0 ? current + ' mA' : '—';
this.loading = false;
} catch (e) {
this.loading = false;
this.addLog('读取电池信息失败');
}
}
与 WiFi 实验室的对比:WiFi 管理器需要使用 .then().then().catch() 的 Promise 链式调用处理异步数据,而电池信息是纯同步的——一个方法内即可完成全部读取和格式化。这体现了 HarmonyOS API 设计中的"恰如其分的复杂度":对于 I/O 密集型操作(网络/WiFi)使用异步,对于系统状态查询(电池)使用同步。
圆形电量仪表
使用 Stack 叠加实现中心大字 + 百分号的效果:
Stack({ alignContent: Alignment.Center }) {
Circle({ width: 100, height: 100 })
.fill('#F1F5F9')
Text(this.batterySOC.toString())
.fontSize(36).fontColor(this.socColor())
.fontWeight(FontWeight.Bold)
Text('%')
.fontSize(14).fontColor(this.socColor())
.fontWeight(FontWeight.Bold)
.margin({ top: 24 })
}
电量颜色动态变化:绿色(≥50%)、橙色(20-49%)、红色(<20%)。
充电与健康可视化面板
Demo 中的双栏可视化面板是用户友好的设计亮点。它不只是展示数据,还根据状态给出人性化的建议:
Text(this.chargingEnum === batteryInfo.BatteryChargeState.ENABLE ?
'设备正在充电,请注意散热' :
this.chargingEnum === batteryInfo.BatteryChargeState.FULL ?
'电池已充满,可断开充电器' :
this.chargingEnum === batteryInfo.BatteryChargeState.DISABLE ?
'电池正在放电中' : '充电状态未知')
这个模式可以扩展到更多的上下文感知场景——例如当温度 > 40°C 且正在充电时,提示"充电中温度较高,建议暂停使用"。

枚举值比较 vs 魔法数字
在 Demo 中,所有的枚举比较都使用了完整的枚举路径:
// 推荐
if (h === batteryInfo.BatteryHealthState.GOOD) { ... }
// 不推荐
if (h === 1) { ... }
前者的优势:
- 语义明确——一眼就知道在比较什么
- IDE 支持自动补全和跳转定义
- 如果 SDK 更新改变了枚举值,编译器会报错而不是静默产生逻辑 bug
- 代码审查友好
完整代码
import { router } from '@kit.ArkUI';
import batteryInfo from '@ohos.batteryInfo';
import { FontSize, Spacing } from '../common/Constants';
interface EventLog {
time: string;
msg: string;
}
@Entry
@Component
struct BatteryLabPage {
@State batterySOC: number = 0;
@State chargingStatus: string = '—';
@State chargingEnum: number = -1;
@State healthStatus: string = '—';
@State healthEnum: number = -1;
@State pluggedType: string = '—';
@State pluggedEnum: number = -1;
@State voltageText: string = '—';
@State temperatureText: string = '—';
@State technology: string = '—';
@State isBatteryPresent: boolean = false;
@State capacityLevel: string = '—';
@State nowCurrent: string = '—';
@State eventLogs: EventLog[] = [];
@State loading: boolean = true;
aboutToAppear(): void {
this.loadBattery();
}
private loadBattery(): void {
this.addLog('开始读取电池信息...');
try {
this.batterySOC = batteryInfo.batterySOC;
this.chargingEnum = batteryInfo.chargingStatus;
this.chargingStatus = this.chargeLabel(batteryInfo.chargingStatus);
this.healthEnum = batteryInfo.healthStatus;
this.healthStatus = this.healthLabel(batteryInfo.healthStatus);
this.pluggedEnum = batteryInfo.pluggedType;
this.pluggedType = this.pluggedLabel(batteryInfo.pluggedType);
const voltageV: number = batteryInfo.voltage / 1000000;
this.voltageText = voltageV.toFixed(3) + ' V';
const tempC: number = batteryInfo.batteryTemperature / 10;
this.temperatureText = tempC.toFixed(1) + ' °C';
this.technology = batteryInfo.technology !== '' ?
batteryInfo.technology : '未知';
this.isBatteryPresent = batteryInfo.isBatteryPresent;
this.capacityLevel = this.capacityLabel(
batteryInfo.batteryCapacityLevel);
const current: number = batteryInfo.nowCurrent;
this.nowCurrent = current !== 0 ? current + ' mA' : '—';
this.addLog('电池电量: ' + this.batterySOC + '%');
this.addLog('充电状态: ' + this.chargingStatus);
this.addLog('健康状态: ' + this.healthStatus);
this.loading = false;
} catch (e) {
this.loading = false;
this.addLog('读取电池信息失败');
}
}
private chargeLabel(s: batteryInfo.BatteryChargeState): string {
if (s === batteryInfo.BatteryChargeState.NONE) return '未知';
if (s === batteryInfo.BatteryChargeState.ENABLE) return '充电中';
if (s === batteryInfo.BatteryChargeState.DISABLE) return '未充电';
if (s === batteryInfo.BatteryChargeState.FULL) return '已充满';
return '—';
}
private healthLabel(h: batteryInfo.BatteryHealthState): string {
if (h === batteryInfo.BatteryHealthState.UNKNOWN) return '未知';
if (h === batteryInfo.BatteryHealthState.GOOD) return '良好';
if (h === batteryInfo.BatteryHealthState.OVERHEAT) return '过热';
if (h === batteryInfo.BatteryHealthState.OVERVOLTAGE) return '过压';
if (h === batteryInfo.BatteryHealthState.COLD) return '过冷';
if (h === batteryInfo.BatteryHealthState.DEAD) return '损坏';
return '—';
}
private pluggedLabel(p: batteryInfo.BatteryPluggedType): string {
if (p === batteryInfo.BatteryPluggedType.NONE) return '未充电';
if (p === batteryInfo.BatteryPluggedType.AC) return '交流电源';
if (p === batteryInfo.BatteryPluggedType.USB) return 'USB';
if (p === batteryInfo.BatteryPluggedType.WIRELESS) return '无线充电';
return '—';
}
private capacityLabel(l: batteryInfo.BatteryCapacityLevel): string {
if (l === batteryInfo.BatteryCapacityLevel.LEVEL_FULL) return '满电';
if (l === batteryInfo.BatteryCapacityLevel.LEVEL_HIGH) return '高电量';
if (l === batteryInfo.BatteryCapacityLevel.LEVEL_NORMAL) return '正常';
if (l === batteryInfo.BatteryCapacityLevel.LEVEL_LOW) return '低电量';
if (l === batteryInfo.BatteryCapacityLevel.LEVEL_WARNING) return '电量警告';
if (l === batteryInfo.BatteryCapacityLevel.LEVEL_CRITICAL) return '严重低电';
if (l === batteryInfo.BatteryCapacityLevel.LEVEL_SHUTDOWN) return '即将关机';
return '—';
}
private healthColor(): string {
if (this.healthEnum === batteryInfo.BatteryHealthState.GOOD)
return '#10B981';
if (this.healthEnum === batteryInfo.BatteryHealthState.UNKNOWN)
return '#94A3B8';
return '#EF4444';
}
private chargeColor(): string {
if (this.chargingEnum === batteryInfo.BatteryChargeState.ENABLE ||
this.chargingEnum === batteryInfo.BatteryChargeState.FULL)
return '#10B981';
if (this.chargingEnum === batteryInfo.BatteryChargeState.DISABLE)
return '#F59E0B';
return '#94A3B8';
}
private socColor(): string {
if (this.batterySOC >= 50) return '#10B981';
if (this.batterySOC >= 20) return '#F59E0B';
return '#EF4444';
}
// ... build() 方法省略,参见项目源码
}
权限与系统能力
@ohos.batteryInfo 的所有属性均无需额外权限即可读取。它属于 SystemCapability.PowerManager.BatteryManager.Core 系统能力,这是所有鸿蒙设备的基础能力。
无需在 module.json5 中声明任何 requestPermissions。
与其它平台对比
| 平台 | 获取电池信息的方式 | 同步/异步 |
|---|---|---|
| HarmonyOS NEXT | batteryInfo.batterySOC 等同步常量 |
同步 |
| Android | IntentFilter + BroadcastReceiver 监听 BATTERY_CHANGED |
异步(广播) |
| iOS | UIDevice.current.isBatteryMonitoringEnabled + batteryLevel |
同步(需开启监控) |
| Web | navigator.getBattery() |
异步(Promise) |
HarmonyOS 的设计在简洁性上最接近 iOS——同步读取,无需注册监听器。区别在于 iOS 需要先设置 isBatteryMonitoringEnabled = true 才能读取,而 HarmonyOS 随时可读。
扩展实践:定时刷新
虽然 batteryInfo 的属性是同步的,但电池状态会实时变化。要提高数据的新鲜度,可以使用 setInterval 定时刷新:
private timerId: number = -1;
aboutToAppear(): void {
this.loadBattery();
this.timerId = setInterval(() => {
this.loadBattery();
}, 5000); // 每 5 秒刷新
}
aboutToDisappear(): void {
if (this.timerId !== -1) {
clearInterval(this.timerId);
}
}
注意:过于频繁的轮询(如 1 秒以下)会增加不必要的 CPU 开销。5~10 秒的间隔对于电池数据来说已经足够。如果需要实时响应电池状态变化,更好的做法是订阅系统广播 COMMON_EVENT_BATTERY_CHANGED,这需要使用 @ohos.commonEventManager,超出本文范围。
常见问题
1. 模拟器上所有电池数据都为 0 或默认值
原因:模拟器没有真实电池硬件,系统返回默认值。
解决:在真机上测试可获得真实数据。模拟器仅用于验证 UI 渲染和编译。
2. batteryTemperature 显示温度异常高(如 350°C)
原因:忘记除以 10。batteryTemperature 单位为 0.1°C。
解决:始终使用 batteryInfo.batteryTemperature / 10 获取摄氏度。
3. nowCurrent 始终为 0
原因:nowCurrent 是 API 12 新增的属性,旧版本设备可能返回 0。
解决:做好兜底处理——current !== 0 ? current + ' mA' : '—'。
总结
本文系统讲解了 HarmonyOS NEXT 中 @ohos.batteryInfo 模块的全部 10 个属性,并通过"电池健康实验室"Demo 展示了实战应用。核心要点:
-
全同步 API:所有属性均为常量,无需异步操作——这是
batteryInfo最大的便利之处。 -
单位陷阱:温度是 0.1°C(需除 10),电压是 µV(需除 10^6),使用前务必完成单位转换。
-
枚举优于数字:始终使用
BatteryHealthState.GOOD而非1进行比较——这是工程质量的底线。 -
数据 + 建议 = 好 UX:仅仅展示数字是不够的。Demo 中的"充电与健康可视化"面板将枚举值转化为人性化的建议——这才是面向用户的应用应有的设计水准。
-
电量等级 ≠ 电量百分比:
batteryCapacityLevel提供的是语义化等级,更适合用于通知和 UI 决策。
掌握 @ohos.batteryInfo,你就能开发出电池诊断、功耗监控、充电优化等一系列实用工具。作为 BasicServicesKit 的核心模块之一,它与 @ohos.wifiManager(网络)、@ohos.deviceInfo(设备)、@ohos.power(电源管理)共同构成了鸿蒙设备信息的基础能力矩阵。
更多推荐


所有评论(0)