Flutter for OpenHarmony三方库适配实战:battery_plus 电池状态(未充电有问题)
电池状态监控是移动应用开发中的常见需求,应用需要根据电池电量、充电状态等信息来优化性能或提醒用户。在 Flutter for OpenHarmony 应用开发中,是一个功能完善的电池状态监控插件,提供了跨平台的电池信息获取能力。battery_plus 库为 Flutter for OpenHarmony 开发提供了完整的电池状态监控能力。通过简洁的 API,开发者可以轻松获取电量、充电状态、节能
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
本文基于flutter3.27.5开发
一、battery_plus 库概述
电池状态监控是移动应用开发中的常见需求,应用需要根据电池电量、充电状态等信息来优化性能或提醒用户。在 Flutter for OpenHarmony 应用开发中,battery_plus 是一个功能完善的电池状态监控插件,提供了跨平台的电池信息获取能力。
battery_plus 库特点
battery_plus 库基于 Flutter 平台接口实现,提供了以下核心特性:
电量获取:支持获取当前设备电池电量百分比,帮助应用了解设备剩余电量。
充电状态监控:支持获取当前充电状态(充电中、放电中、满电、未知),并支持状态变化监听。
节能模式检测:支持检测设备是否处于节能模式,帮助应用优化性能策略。
状态变化监听:提供 Stream 接口,实时监听电池状态变化,无需轮询。
功能支持对比
| 功能 | Android | iOS | OpenHarmony |
|---|---|---|---|
| 获取电量 | ✅ | ✅ | ✅ |
| 获取充电状态 | ✅ | ✅ | ✅ |
| 状态变化监听 | ✅ | ✅ | ✅ |
| 节能模式检测 | ✅ | ✅ | ✅ |
使用场景:低电量提醒、性能优化策略、充电状态显示、电池健康监控等。
二、安装与配置
2.1 添加依赖
在项目的 pubspec.yaml 文件中添加 battery_plus 依赖:
dependencies:
battery_plus:
git:
url: https://atomgit.com/openharmony-sig/flutter_plus_plugins.git
path: packages/battery_plus/battery_plus
然后执行以下命令获取依赖:
flutter pub get
2.2 权限配置
battery_plus 在 OpenHarmony 平台上不需要额外权限配置,系统电池信息接口可直接访问。
三、核心 API 详解
3.1 Battery 类
Battery 是 battery_plus 库的核心类,采用单例模式设计,提供电池信息获取的所有方法。
class Battery {
factory Battery() {
_singleton ??= Battery._();
return _singleton!;
}
}
使用示例:
final battery = Battery();
3.2 batteryLevel 属性
batteryLevel 属性用于获取当前电池电量百分比。
Future<int> get batteryLevel
返回值:返回 0-100 之间的整数,表示电池电量百分比。
使用示例:
final battery = Battery();
final level = await battery.batteryLevel;
print('当前电量: $level%');
3.3 batteryState 属性
batteryState 属性用于获取当前电池充电状态。
Future<BatteryState> get batteryState
返回值:返回 BatteryState 枚举值,表示当前充电状态。
使用示例:
final battery = Battery();
final state = await battery.batteryState;
print('充电状态: $state');
3.4 isInBatterySaveMode 属性
isInBatterySaveMode 属性用于检测设备是否处于节能模式。
Future<bool> get isInBatterySaveMode
返回值:返回布尔值,true 表示设备处于节能模式。
使用示例:
final battery = Battery();
final isSaveMode = await battery.isInBatterySaveMode;
if (isSaveMode) {
print('设备处于节能模式');
}
3.5 onBatteryStateChanged 属性
onBatteryStateChanged 属性是一个 Stream,用于监听电池状态变化。
Stream<BatteryState> get onBatteryStateChanged
返回值:返回 BatteryState 的 Stream,每次电池状态变化时触发。
使用示例:
final battery = Battery();
battery.onBatteryStateChanged.listen((BatteryState state) {
print('电池状态变化: $state');
});
3.6 BatteryState 枚举
BatteryState 枚举定义了电池的所有可能状态。
enum BatteryState {
full,
charging,
discharging,
unknown
}
枚举值说明:
| 枚举值 | 说明 |
|---|---|
| full | 电池已充满 |
| charging | 正在充电中 |
| discharging | 正在放电中(使用中) |
| unknown | 状态未知 |
四、OpenHarmony 平台实现原理
4.1 原生 API 映射
battery_plus 在 OpenHarmony 平台上使用 @ohos.batteryInfo 和 @ohos.power 模块实现:
| Flutter API | OpenHarmony API |
|---|---|
| batteryLevel | batteryInfo.batterySOC |
| batteryState | batteryInfo.chargingStatus |
| isInBatterySaveMode | power.getPowerMode() |
4.2 充电状态映射
OpenHarmony 的 BatteryChargeState 与 Flutter 的 BatteryState 映射关系:
| OpenHarmony 状态 | Flutter 状态 |
|---|---|
| BatteryChargeState.NONE | unknown |
| BatteryChargeState.ENABLE | charging |
| BatteryChargeState.DISABLE | discharging |
| BatteryChargeState.FULL | full |
4.3 状态监听实现
OpenHarmony 平台通过定时器轮询实现状态变化监听:
const UPDATE_INTERVAL = 200;
onListen(args: Any, events: EventSink): void {
this.battery_events = events;
this.timerId = setInterval(this.chargeModeCallback, UPDATE_INTERVAL);
}
chargeModeCallback: Callback<EventSink> = () => {
const battertChargeState: string = this.getChargingStatus();
if (battertChargeState != this.chargeMode && this.battery_events) {
this.chargeMode = battertChargeState;
this.battery_events.success(this.chargeMode);
}
}
五、实战案例
5.1 获取电池基本信息
Future<void> getBatteryInfo() async {
final battery = Battery();
final level = await battery.batteryLevel;
final state = await battery.batteryState;
final isSaveMode = await battery.isInBatterySaveMode;
print('电量: $level%');
print('状态: $state');
print('节能模式: $isSaveMode');
}
5.2 监听电池状态变化
StreamSubscription<BatteryState>? _subscription;
void startListening() {
final battery = Battery();
_subscription = battery.onBatteryStateChanged.listen((state) {
switch (state) {
case BatteryState.charging:
print('开始充电');
break;
case BatteryState.discharging:
print('正在使用电池');
break;
case BatteryState.full:
print('充电完成');
break;
case BatteryState.unknown:
print('状态未知');
break;
}
});
}
void stopListening() {
_subscription?.cancel();
_subscription = null;
}
5.3 低电量提醒
Future<void> checkLowBattery() async {
final battery = Battery();
final level = await battery.batteryLevel;
if (level <= 20) {
print('电量不足,请及时充电');
} else if (level <= 10) {
print('电量严重不足!');
}
}
5.4 根据电量优化性能
Future<void> optimizePerformance() async {
final battery = Battery();
final level = await battery.batteryLevel;
final isSaveMode = await battery.isInBatterySaveMode;
if (isSaveMode || level <= 20) {
print('启用省电模式,降低动画帧率');
} else {
print('正常性能模式');
}
}
5.5 完整的电池监控组件
class BatteryMonitor extends StatefulWidget {
const BatteryMonitor({super.key});
State<BatteryMonitor> createState() => _BatteryMonitorState();
}
class _BatteryMonitorState extends State<BatteryMonitor> {
final Battery _battery = Battery();
int _batteryLevel = 0;
BatteryState _batteryState = BatteryState.unknown;
bool _isSaveMode = false;
StreamSubscription<BatteryState>? _subscription;
void initState() {
super.initState();
_initBatteryInfo();
_listenBatteryState();
}
Future<void> _initBatteryInfo() async {
final level = await _battery.batteryLevel;
final state = await _battery.batteryState;
final isSaveMode = await _battery.isInBatterySaveMode;
setState(() {
_batteryLevel = level;
_batteryState = state;
_isSaveMode = isSaveMode;
});
}
void _listenBatteryState() {
_subscription = _battery.onBatteryStateChanged.listen((state) {
setState(() {
_batteryState = state;
});
});
}
void dispose() {
_subscription?.cancel();
super.dispose();
}
Widget build(BuildContext context) {
return Column(
children: [
Text('电量: $_batteryLevel%'),
Text('状态: ${_getStateText()}'),
Text('节能模式: ${_isSaveMode ? "开启" : "关闭"}'),
],
);
}
String _getStateText() {
switch (_batteryState) {
case BatteryState.charging:
return '充电中';
case BatteryState.discharging:
return '使用中';
case BatteryState.full:
return '已充满';
case BatteryState.unknown:
return '未知';
}
}
}
六、最佳实践
6.1 及时取消监听
监听电池状态变化时,务必在组件销毁时取消订阅:
void dispose() {
_subscription?.cancel();
super.dispose();
}
6.2 错误处理
对电池信息获取进行错误处理:
Future<void> safeGetBatteryLevel() async {
try {
final battery = Battery();
final level = await battery.batteryLevel;
print('电量: $level%');
} on PlatformException catch (e) {
print('获取电量失败: ${e.message}');
}
}
6.3 性能优化建议
根据电池状态调整应用行为:
Future<void> adjustAppBehavior() async {
final battery = Battery();
final level = await battery.batteryLevel;
final isSaveMode = await battery.isInBatterySaveMode;
if (isSaveMode || level < 20) {
// 禁用后台任务
// 降低动画帧率
// 减少网络请求频率
}
}
6.4 避免频繁获取
电池状态变化监听已由插件内部处理,避免在代码中频繁调用获取方法:
// 不推荐:频繁轮询
Timer.periodic(Duration(seconds: 1), (_) async {
final state = await battery.batteryState;
});
// 推荐:使用 Stream 监听
battery.onBatteryStateChanged.listen((state) {
// 自动响应状态变化
});
七、常见问题
Q1:为什么获取的电量有时候不准确?
电池电量由系统提供,可能存在一定的延迟或误差。建议在关键操作前重新获取最新电量。
Q2:onBatteryStateChanged 的触发频率是多少?
OpenHarmony 平台实现中,默认每 200ms 检查一次状态变化,只有状态真正改变时才会触发事件。
Q3:节能模式检测支持哪些平台?
目前节能模式检测支持 Android、iOS、Windows 和 OpenHarmony 平台。
Q4:如何在模拟器上测试电池功能?
部分模拟器支持模拟电池状态。建议使用真机测试以获得准确结果。
Q5:Web 平台支持情况如何?
Web 平台依赖浏览器的 Battery Status API,部分浏览器可能不支持或返回有限信息。
Q6:为什么不在充电时显示"未知"而不是"使用中"?
这是 battery_plus OpenHarmony 平台实现的一个已知问题。当设备使用电池供电(不在充电)时,OpenHarmony 的 BatteryChargeState.NONE 状态被错误地映射为 "unknown",而不是 "discharging"。
由于 battery_plus 是第三方库(非本地项目代码),无法直接修改其实现。临时解决方案是在前端代码中处理这种异常情况:
String _getStateText(BatteryState state) {
switch (state) {
case BatteryState.charging:
return '充电中';
case BatteryState.discharging:
case BatteryState.unknown:
// OpenHarmony平台上BatteryChargeState.NONE返回unknown
// 实际上是放电状态
return '使用中';
case BatteryState.full:
return '已充满';
}
}
或者在获取状态时进行转换:
BatteryState convertUnknownToDischarging(BatteryState state) {
if (state == BatteryState.unknown) {
return BatteryState.discharging;
}
return state;
}
八、总结
battery_plus 库为 Flutter for OpenHarmony 开发提供了完整的电池状态监控能力。通过简洁的 API,开发者可以轻松获取电量、充电状态、节能模式等信息,并实时监听状态变化。该库在鸿蒙平台上已经完成了完整的适配,支持所有核心功能,开发者可以放心使用。
九、完整代码示例
以下是一个完整的可运行示例,展示了 battery_plus 库的核心功能:
pubspec.yaml
name: battery_plus_demo
description: Flutter for OpenHarmony battery_plus 演示项目
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
battery_plus:
git:
url: https://atomgit.com/openharmony-sig/flutter_plus_plugins.git
path: packages/battery_plus/battery_plus
flutter:
uses-material-design: true
main.dart
import 'dart:async';
import 'package:battery_plus/battery_plus.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Battery Plus Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final Battery _battery = Battery();
int _batteryLevel = 0;
BatteryState _batteryState = BatteryState.unknown;
bool _isSaveMode = false;
StreamSubscription<BatteryState>? _subscription;
List<String> _stateHistory = [];
void initState() {
super.initState();
_initBatteryInfo();
_listenBatteryState();
}
Future<void> _initBatteryInfo() async {
try {
final level = await _battery.batteryLevel;
final state = await _battery.batteryState;
final isSaveMode = await _battery.isInBatterySaveMode;
setState(() {
_batteryLevel = level;
_batteryState = state;
_isSaveMode = isSaveMode;
});
} catch (e) {
_showMessage('获取电池信息失败: $e');
}
}
void _listenBatteryState() {
_subscription = _battery.onBatteryStateChanged.listen((state) {
setState(() {
_batteryState = state;
_stateHistory.insert(0, '${DateTime.now().toString().substring(11, 19)} - ${_getStateText(state)}');
if (_stateHistory.length > 10) {
_stateHistory.removeLast();
}
});
});
}
void _showMessage(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
}
void dispose() {
_subscription?.cancel();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Battery Plus 演示'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'电池状态监控',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
const SizedBox(height: 24),
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Icon(
_getBatteryIcon(),
size: 80,
color: _getBatteryColor(),
),
const SizedBox(height: 16),
Text(
'$_batteryLevel%',
style: const TextStyle(
fontSize: 48,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
_getStateText(_batteryState),
style: TextStyle(
fontSize: 18,
color: _getBatteryColor(),
),
),
],
),
),
),
const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'详细信息',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
const Divider(),
_buildInfoRow('电量', '$_batteryLevel%'),
_buildInfoRow('状态', _getStateText(_batteryState)),
_buildInfoRow('节能模式', _isSaveMode ? '开启' : '关闭'),
],
),
),
),
const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'状态变化历史',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
TextButton(
onPressed: () {
setState(() {
_stateHistory.clear();
});
},
child: const Text('清空'),
),
],
),
const Divider(),
if (_stateHistory.isEmpty)
const Text('暂无状态变化记录')
else
Column(
children: _stateHistory.map((record) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Text(record),
);
}).toList(),
),
],
),
),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: _initBatteryInfo,
icon: const Icon(Icons.refresh),
label: const Text('刷新电池信息'),
),
],
),
),
);
}
Widget _buildInfoRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label, style: const TextStyle(color: Colors.grey)),
Text(value, style: const TextStyle(fontWeight: FontWeight.bold)),
],
),
);
}
IconData _getBatteryIcon() {
if (_batteryState == BatteryState.charging) {
return Icons.battery_charging_full;
}
if (_batteryLevel >= 90) return Icons.battery_full;
if (_batteryLevel >= 70) return Icons.battery_6_bar;
if (_batteryLevel >= 50) return Icons.battery_5_bar;
if (_batteryLevel >= 30) return Icons.battery_4_bar;
if (_batteryLevel >= 20) return Icons.battery_3_bar;
if (_batteryLevel >= 10) return Icons.battery_2_bar;
if (_batteryLevel >= 5) return Icons.battery_1_bar;
return Icons.battery_0_bar;
}
Color _getBatteryColor() {
if (_batteryState == BatteryState.charging) {
return Colors.green;
}
if (_batteryLevel <= 20) {
return Colors.red;
}
if (_batteryLevel <= 50) {
return Colors.orange;
}
return Colors.green;
}
String _getStateText(BatteryState state) {
switch (state) {
case BatteryState.charging:
return '充电中';
case BatteryState.discharging:
return '使用中';
case BatteryState.full:
return '已充满';
case BatteryState.unknown:
return '未知';
}
}
}
运行此示例后,您将看到一个完整的电池状态监控界面,包含电量显示、充电状态、节能模式状态以及状态变化历史记录。连接充电器或断开充电时,界面会自动更新显示最新状态。
更多推荐
所有评论(0)