Flutter 鸿蒙实战:用 battery_plus 三方库给应用加上电池状态监测与充电动效
2026/9/11 15:42:57 网站建设 项目流程

Flutter 鸿蒙实战:用 battery_plus 三方库给应用加上电池状态监测与充电动效

Flutter 社区地址: https://atomgit.com/CPF-Flutter/flutter_flutter
github三方库地址:https://github.com/fluttercommunity/plus_plugins/tree/main/packages/battery_plus/battery_plus
pub地址:https://pub.dev/packages/battery_plus
鸿蒙适配版:https://atomgit.com/CPF-Flutter/flutter_plus_plugins
我的工程适配地址:https://atomgit.com/weixin_52908342/battery_demo

库版本:battery_plus 4.1.0(CPF-Flutter 鸿蒙适配版,commit9571de2)|验证环境:Flutter 鸿蒙 SDK 3.44.9(oh-3.44.9-dev)|DevEco Studio 26.0.0.821 | 设备:DevEco 模拟器 Pura X View | HarmonyOS 7.0.0.106(API 26)

应用里的电池状态提示、电量告警、充电动效几乎是移动 App 标配。battery_plus是 Flutter 生态里用得最多的电池状态插件(pub.dev 月下载百万级),CPF-Flutter 社区已在flutter_plus_pluginsmonorepo 里完成鸿蒙适配。本文介绍它在 OpenHarmony 上的引入方式、4 个接口的逐个调用与真实运行效果,并附 FAQ 与问题反馈流程。


一、环境搭建

本章不重复展开,直接引用官方文档:Flutter OH 开发环境搭建指导。

完成后用flutter doctor -v验证,FlutterHarmonyOS toolchain两项均为[√]即可。本文实际使用的版本:Flutter OHoh-3.44.9-dev(commit77e0c8d13b)、DevEco Studio26.0.0.821、HarmonyOS SDK API 26。

二、应用背景

2.1 当前的应用场景与痛点

  • 儿童手表 / 老人手环类 App:需要根据电池余量动态降低刷新率、上传频率
  • 导航 / 出行类:电量不足时提示用户充电,自动降级 UI 亮度
  • 共享设备类:实时上报设备电量给云端
  • 视频 / 游戏类:低电量时关闭高耗电特效

痛点在于:Flutter 官方battery_plus只覆盖 Android/iOS/Web/Windows/macOS/Linux,鸿蒙侧此前一片空白——应用迁到 OpenHarmony 后电池相关功能直接失效。

2.2 为什么需要这个库

自己写插件需要处理 ArkTS 通道、系统 API 差异、事件流生命周期,成本高;battery_plus的鸿蒙适配版由 CPF-Flutter 社区维护,一行 git 依赖即可获得跨端一致的 API。

2.3 解决什么问题

一句话总结:让 Flutter 应用在鸿蒙上以与 Android/iOS 完全相同的 API 读取电池状态。具体提供:

  1. 当前电量百分比(0-100)
  2. 电池状态(充电中 / 放电中 / 已充满 / 未知)
  3. 省电模式查询
  4. 电池状态变化事件流(免轮询、自动推送)

三、功能介绍

功能API说明适用场景
电量查询batteryLevel返回Future<int>,0-100电量展示、低电告警
状态查询batteryState返回Future<BatteryState>枚举充电动效、充电提示音
省电模式isInBatterySaveMode返回Future<bool>省电模式下降低刷新率
状态变化流onBatteryStateChangedStream<BatteryState>,订阅后自动推送实时监听插拔充电线

四、使用方法

4.1 在应用中引入三方库(AtomGit 链接方式)

dependencies:flutter:sdk:flutterbattery_plus:git:url:https://atomgit.com/CPF-Flutter/flutter_plus_plugins.gitref:9571de239933ab2893dbd49037e128135b050a7cpath:packages/battery_plus/battery_plus

三个注意点:

  1. path必须写到双层目录packages/battery_plus/battery_plus(monorepo 里插件在嵌套子目录),写成packages/battery_plus会 404
  2. ref建议写 commit hash(本文用9571de2),tag/分支名可能漂移
  3. URL 用 AtomGit 而非 pub.dev——pub 上的battery_plus没有 ohos 平台实现,必须走 CPF-Flutter 的适配仓库

执行flutter pub get后即可import 'package:battery_plus/battery_plus.dart';

4.2 调用接口实现功能

4.2.1 Battery():获取单例
finalbattery=Battery();

Battery是单例工厂:第二次Battery()会复用同一实例。不要重复创建,否则事件流订阅会被覆盖。

4.2.2 batteryLevel:电量查询

功能说明:异步 getter,返回当前电量百分比(0-100 的整数)。

finallevel=awaitbattery.batteryLevel;print('当前电量:$level%');

运行效果


demo 首屏:大字 100% 即batteryLevel返回值,电量充足时显示绿色。下方副标题标注了对应的 API 名。

4.2.3 batteryState:状态查询

功能说明:异步 getter,返回BatteryState枚举(charging/discharging/full/unknown)。

finalstate=awaitbattery.batteryState;switch(state){caseBatteryState.charging:print('充电中');caseBatteryState.discharging:print('放电中');caseBatteryState.full:print('已充满');default:print('未知');}

运行效果


通过 DevEco 模拟器命令Emulator -instance "Pura X View" -battery 65改变电量后刷新:大字变为 65%,事件流日志累积了多次调用记录。模拟器无真实电池硬件,batteryState显示unknown属正常行为。

4.2.4 isInBatterySaveMode:省电模式查询

功能说明:异步 getter,返回设备是否处于省电模式。注意方法名是isInBatterySaveMode(不是isInPowerSaveMode,早期文档有此拼写错误)。

finalpowerSave=awaitbattery.isInBatterySaveMode;if(powerSave){// 降级:关闭高刷、减少上报频率}

运行效果


右侧卡片:isInBatterySaveMode()返回false(省电模式未开启)。鸿蒙适配版当前固定返回 false,见 5.1 Q5。

4.2.5 onBatteryStateChanged:状态变化事件流

功能说明Stream<BatteryState>,订阅一次持续推送,免去手动轮询。必须在dispose()里 cancel防止泄漏。

StreamSubscription<BatteryState>?_sub;@overridevoidinitState(){super.initState();_sub=battery.onBatteryStateChanged.listen((s){print('电池状态变化:${s.name}');});}@overridevoiddispose(){_sub?.cancel();super.dispose();}

运行效果


通过模拟器命令Emulator -batteryStatus 1(切换到充电态)触发真实事件:底部暗色事件流卡新增一行[00:54:45] onBatteryStateChanged → charging——无需任何手动刷新,事件自动推送到 Dart 层;顶部状态栏电池图标同步出现闪电符号。

补充:battery_plus 4.x没有onBatteryLevelChanged(电量百分比变化流),如需细粒度电量监控请自行Timer.periodic轮询batteryLevel

4.3 完整示例代码

可直接复制运行的main.dart(含 4 个接口的全调用 + 事件流日志 UI):

import'dart:async';import'package:battery_plus/battery_plus.dart';import'package:flutter/material.dart';voidmain()=>runApp(constBatteryApp());classBatteryAppextendsStatelessWidget{constBatteryApp({super.key});@overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:'battery_plus · OpenHarmony',theme:ThemeData(colorSchemeSeed:constColor(0xFF2EA043)),home:constBatteryPage(),);}}classBatteryPageextendsStatefulWidget{constBatteryPage({super.key});@overrideState<BatteryPage>createState()=>_BatteryPageState();}class_BatteryPageStateextendsState<BatteryPage>{final_battery=Battery();int _level=-1;BatteryState_state=BatteryState.unknown;bool _powerSave=false;finalList<String>_events=[];StreamSubscription<BatteryState>?_stateSub;@overridevoidinitState(){super.initState();_refresh();_stateSub=_battery.onBatteryStateChanged.listen((s){_log('onBatteryStateChanged →${s.name}');});}@overridevoiddispose(){_stateSub?.cancel();super.dispose();}void_log(Stringmsg){finalnow=DateTime.now();setState((){_events.insert(0,'[${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}:${now.second.toString().padLeft(2, '0')}]$msg');if(_events.length>30)_events.removeLast();});}Future<void>_refresh()async{finallevel=await_battery.batteryLevel;finalstate=await_battery.batteryState;bool powerSave=false;try{powerSave=await_battery.isInBatterySaveMode;}catch(_){powerSave=false;}if(!mounted)return;setState((){_level=level;_state=state;_powerSave=powerSave;});_log('手动刷新:电量$level%,状态${state.name}');}@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText('battery_plus · OpenHarmony')),body:ListView(padding:constEdgeInsets.all(16),children:[Text('$_level%',style:constTextStyle(fontSize:64)),Text('状态:${_state.name}| 省电:$_powerSave'),FilledButton(onPressed:_refresh,child:constText('手动刷新')),..._events.map(Text.new),],),);}}

签名与构建(活动要求示例工程含signingConfig: "default"):

flutter create--platformsohos.# 生成 ohos 工程目录# 在 ohos/build-profile.json5 填入签名材料(DevEco 自动生成于 ~/.ohos/config/)flutter build hap--debughdcinstallbuild/ohos/hap/entry-default-signed.hap

无真机时,DevEco 模拟器可用命令脚本化触发电池状态,验证全部接口:

Emulator-instance"<模拟器名>"-battery18# 低电量(demo 变红)Emulator-instance"<模拟器名>"-battery65# 中等电量(绿色)Emulator-instance"<模拟器名>"-batteryStatus1# 触发 charging 事件流

五、FAQ

5.1 常见问题

Q1:编译报The getter 'onBatteryLevelChanged' isn't defined
battery_plus 4.x 只有onBatteryStateChanged(状态流),没有电量百分比流。用Timer.periodic轮询batteryLevel替代。

Q2:编译报The getter 'isInPowerSaveMode' isn't defined
拼写错误:正确方法是isInBatterySaveMode

Q3:batteryState在模拟器上一直返回unknown
正常现象——模拟器无真实电池硬件。用Emulator -batteryStatus 0|1强制切换状态可触发事件流;真机上会返回真实状态。

Q4:flutter pub get解析失败/找不到包
检查path: packages/battery_plus/battery_plus是否写完整(双层目录);镜像用export PUB_HOSTED_URL=https://pub.flutter-io.cn

Q5:isInBatterySaveMode始终返回 false
鸿蒙适配版当前实现固定返回 false(省电模式真实监听尚未实现),属于已知限制。可关注上游仓库 issue 跟踪进度。

5.2 库本身存在问题:如何提交 Issue

仓库地址:https://atomgit.com/CPF-Flutter/flutter_plus_plugins

  1. 打开仓库 → Issues → 新建 Issue
  2. 标题:[Bug] 现象简述(如[Bug] isInBatterySaveMode always returns false on OHOS
  3. 正文必备:复现步骤、期望行为、实际行为、设备与 SDK 版本(flutter --version+hdc shell param get const.product.software.version)、最小复现代码
  4. 附上 demo 截图 / hilog 日志(hdc shell hilog -t OHOSAbility -x

5.3 能自己解决:如何提交 PR

  1. Fork仓库到自己账号:AtomGit 仓库页右上角 Fork
  2. 建分支git checkout -b fix/battery-save-mode
  3. 修改并提交
    gitaddpackages/battery_plus/gitcommit-m"fix(battery_plus): read isInBatterySaveMode from PowerManager on OHOS"gitpush-uorigin fix/battery-save-mode
  4. 发 PR:AtomGit 上 从<你的账号>:fix/battery-save-modeCPF-Flutter:master,描述中附鸿蒙设备验证截图(修改后isInBatterySaveMode正确返回 true 的效果)

六、其他内容

battery_plus4.1.0 鸿蒙适配版开箱即用:一行 git 依赖 + 四个 API 即可覆盖电量查询、状态查询、省电模式、状态监听全部场景。配合 DevEco 模拟器的电池模拟命令,无需真机也能完整验证每个接口。已知限制是isInBatterySaveMode固定返回 false(可通过社区 Issue/PR 推动)。相比自己从零写 ArkTS 插件,直接复用 CPF-Flutter 适配成果是明显更优的选择。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询