Flutter for OpenHarmony 第三方库实战:电池状态监测 —— battery_plus
电池状态是移动应用开发中重要的系统信息,合理利用电池信息可以优化应用行为,提升用户体验。提供了跨平台的电池状态监控能力,支持获取电池电量、充电状态、节能模式检测以及实时监听电池状态变化。🔋 电量获取:获取当前电池电量百分比(0-100)。⚡ 充电状态:获取电池状态(充电中、放电中、满电、未知)。🌱 节能模式:检测设备是否处于节能模式。📡 实时监听:监听电池状态的实时变化。fill:#333;

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
🎯 欢迎来到 Flutter for OpenHarmony 第三方库实战系列!本文将带你实现电池状态监测功能,通过
battery_plus库获取设备电量、充电状态、节能模式等信息。
🚀 项目概述:我们要构建什么?
电池状态是移动应用开发中重要的系统信息,合理利用电池信息可以优化应用行为,提升用户体验。battery_plus 提供了跨平台的电池状态监控能力,支持获取电池电量、充电状态、节能模式检测以及实时监听电池状态变化。
本文将构建的应用具备以下核心特性:
🔋 电量获取:获取当前电池电量百分比(0-100)。
⚡ 充电状态:获取电池状态(充电中、放电中、满电、未知)。
🌱 节能模式:检测设备是否处于节能模式。
📡 实时监听:监听电池状态的实时变化。
🎯 核心功能一览
| 功能模块 | 属性/方法 | 核心能力 |
|---|---|---|
| 🔋 电量获取 | batteryLevel | 获取电池电量百分比 |
| ⚡ 充电状态 | batteryState | 获取充电状态 |
| 🌱 节能模式 | isInBatterySaveMode | 检测节能模式 |
| 📡 状态监听 | onBatteryStateChanged | 监听电池状态变化 |
💡 为什么选择 battery_plus?
1️⃣ 官方维护
Flutter Community 官方维护的插件,质量和更新有保障。
2️⃣ 跨平台支持
支持 Android、iOS、macOS、Windows、Linux、Web 和 OpenHarmony 等多个平台。
3️⃣ 功能完整
支持电量获取、状态检测、节能模式判断和状态变化监听。
4️⃣ OpenHarmony 原生适配
专门针对 OpenHarmony 平台进行了适配,完整支持所有功能。
📋 电池状态枚举
| 状态 | 说明 |
|---|---|
BatteryState.full |
电池处于满电状态 |
BatteryState.charging |
电池处于充电状态 |
BatteryState.discharging |
电池处于放电状态 |
BatteryState.unknown |
电池状态未知 |
📦 第一步:环境配置
1.1 添加依赖
在开始编码之前,我们需要先配置项目的依赖。打开项目根目录下的 pubspec.yaml 文件,添加以下内容。
dependencies:
flutter:
sdk: flutter
# 电池状态监测(OpenHarmony 适配版本)
battery_plus:
git:
url: "https://atomgit.com/openharmony-sig/flutter_plus_plugins.git"
path: "packages/battery_plus/battery_plus"
1.2 执行依赖安装
配置完成后,在项目根目录执行以下命令来下载并安装所有依赖包。
flutter pub get
1.3 权限配置
在 OpenHarmony 平台上,使用 battery_plus 获取电池信息不需要额外配置权限。该插件使用系统公开的电池信息接口,无需申请特殊权限。
📱 第二步:电池功能详解
2.1 核心 API 介绍
Battery 类
主接口类,提供电池信息获取功能。
class Battery {
// 获取电池电量百分比(0-100)
Future<int> get batteryLevel;
// 获取电池状态
Future<BatteryState> get batteryState;
// 检测是否处于节能模式
Future<bool> get isInBatterySaveMode;
// 监听电池状态变化
Stream<BatteryState> get onBatteryStateChanged;
}
BatteryState 枚举
enum BatteryState {
// 满电状态
full,
// 充电中
charging,
// 放电中
discharging,
// 未知状态
unknown,
}
⚠️ 重要说明:
batteryLevel返回 0-100 的整数- 模拟器上可能返回
unknown状态 - 监听状态变化时记得在 dispose 时取消订阅
2.2 电池服务实现
下面的 BatteryService 类封装了电池信息获取的逻辑。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:battery_plus/battery_plus.dart';
class BatteryService extends ChangeNotifier {
final Battery _battery = Battery();
int _batteryLevel = 0;
BatteryState _batteryState = BatteryState.unknown;
bool _isInBatterySaveMode = false;
StreamSubscription<BatteryState>? _subscription;
int get batteryLevel => _batteryLevel;
BatteryState get batteryState => _batteryState;
bool get isInBatterySaveMode => _isInBatterySaveMode;
bool get isCharging => _batteryState == BatteryState.charging;
bool get isFull => _batteryState == BatteryState.full;
bool get isLowBattery => _batteryLevel < 20;
Future<void> initialize() async {
await _loadBatteryInfo();
_startListening();
}
Future<void> _loadBatteryInfo() async {
try {
final level = await _battery.batteryLevel;
final state = await _battery.batteryState;
final saveMode = await _battery.isInBatterySaveMode;
_batteryLevel = level;
_batteryState = state;
_isInBatterySaveMode = saveMode;
notifyListeners();
} catch (e) {
debugPrint('获取电池信息失败: $e');
}
}
void _startListening() {
_subscription = _battery.onBatteryStateChanged.listen((state) {
_batteryState = state;
notifyListeners();
});
}
Future<void> refresh() async {
await _loadBatteryInfo();
}
void dispose() {
_subscription?.cancel();
super.dispose();
}
}
🎨 第三步:完整示例代码
下面是一个完整的电池状态监测应用。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:battery_plus/battery_plus.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 BatteryPage(),
debugShowCheckedModeBanner: false,
);
}
}
class BatteryPage extends StatefulWidget {
const BatteryPage({super.key});
State<BatteryPage> createState() => _BatteryPageState();
}
class _BatteryPageState extends State<BatteryPage> {
final Battery _battery = Battery();
int _batteryLevel = 0;
BatteryState _batteryState = BatteryState.unknown;
bool _isInBatterySaveMode = false;
StreamSubscription<BatteryState>? _batteryStateSubscription;
void initState() {
super.initState();
_initBatteryInfo();
_listenBatteryState();
}
Future<void> _initBatteryInfo() async {
final level = await _battery.batteryLevel;
final state = await _battery.batteryState;
final saveMode = await _battery.isInBatterySaveMode;
setState(() {
_batteryLevel = level;
_batteryState = state;
_isInBatterySaveMode = saveMode;
});
}
void _listenBatteryState() {
_batteryStateSubscription = _battery.onBatteryStateChanged.listen((state) {
setState(() {
_batteryState = state;
});
});
}
String _getBatteryStateText(BatteryState state) {
switch (state) {
case BatteryState.full:
return '满电';
case BatteryState.charging:
return '充电中';
case BatteryState.discharging:
return '放电中';
case BatteryState.unknown:
return '未知';
}
}
IconData _getBatteryIcon(BatteryState state, int level) {
if (state == BatteryState.charging) {
return Icons.battery_charging_full;
} else if (state == BatteryState.full) {
return Icons.battery_full;
} else if (level <= 20) {
return Icons.battery_alert;
} else if (level <= 50) {
return Icons.battery_4_bar;
} else if (level <= 80) {
return Icons.battery_5_bar;
} else {
return Icons.battery_full;
}
}
Color _getBatteryColor(int level, BatteryState state) {
if (state == BatteryState.charging) {
return Colors.green;
} else if (level <= 20) {
return Colors.red;
} else if (level <= 50) {
return Colors.orange;
} else {
return Colors.green;
}
}
void dispose() {
_batteryStateSubscription?.cancel();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('电池状态'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _initBatteryInfo,
tooltip: '刷新',
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
_buildBatteryCard(),
const SizedBox(height: 16),
_buildStatusCard(),
const SizedBox(height: 16),
_buildSaveModeCard(),
const SizedBox(height: 16),
_buildTipsCard(),
],
),
),
);
}
Widget _buildBatteryCard() {
final color = _getBatteryColor(_batteryLevel, _batteryState);
final icon = _getBatteryIcon(_batteryState, _batteryLevel);
return Card(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Icon(
icon,
size: 100,
color: color,
),
const SizedBox(height: 16),
Text(
'$_batteryLevel%',
style: TextStyle(
fontSize: 56,
fontWeight: FontWeight.bold,
color: color,
),
),
const SizedBox(height: 8),
Text(
'电池电量',
style: TextStyle(
fontSize: 16,
color: Colors.grey.shade600,
),
),
const SizedBox(height: 16),
_buildBatteryBar(),
],
),
),
);
}
Widget _buildBatteryBar() {
return Column(
children: [
Row(
children: [
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: LinearProgressIndicator(
value: _batteryLevel / 100,
backgroundColor: Colors.grey.shade300,
valueColor: AlwaysStoppedAnimation<Color>(
_getBatteryColor(_batteryLevel, _batteryState),
),
minHeight: 12,
),
),
),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('0%', style: TextStyle(color: Colors.grey.shade500)),
Text('50%', style: TextStyle(color: Colors.grey.shade500)),
Text('100%', style: TextStyle(color: Colors.grey.shade500)),
],
),
],
);
}
Widget _buildStatusCard() {
IconData statusIcon;
Color statusColor;
String statusDescription;
switch (_batteryState) {
case BatteryState.charging:
statusIcon = Icons.power;
statusColor = Colors.green;
statusDescription = '设备正在充电,可以执行耗电任务';
break;
case BatteryState.full:
statusIcon = Icons.battery_full;
statusColor = Colors.green;
statusDescription = '电池已充满,电量充足';
break;
case BatteryState.discharging:
statusIcon = Icons.power_off;
statusColor = _batteryLevel < 20 ? Colors.red : Colors.orange;
statusDescription = _batteryLevel < 20
? '电量较低,建议充电'
: '设备正在使用电池供电';
break;
case BatteryState.unknown:
statusIcon = Icons.help_outline;
statusColor = Colors.grey;
statusDescription = '无法获取电池状态';
break;
}
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Container(
width: 56,
height: 56,
decoration: BoxDecoration(
color: statusColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Icon(
statusIcon,
size: 28,
color: statusColor,
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'状态: ${_getBatteryStateText(_batteryState)}',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
statusDescription,
style: TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
),
),
],
),
),
],
),
),
);
}
Widget _buildSaveModeCard() {
return Card(
child: ListTile(
leading: Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: _isInBatterySaveMode
? Colors.orange.withOpacity(0.1)
: Colors.grey.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Icon(
_isInBatterySaveMode ? Icons.energy_savings_leaf : Icons.eco,
color: _isInBatterySaveMode ? Colors.orange : Colors.grey,
),
),
title: const Text('节能模式'),
subtitle: Text(
_isInBatterySaveMode
? '已开启 - 系统将限制后台活动'
: '未开启',
),
trailing: Switch(
value: _isInBatterySaveMode,
onChanged: null,
),
),
);
}
Widget _buildTipsCard() {
return Card(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Icons.lightbulb_outline,
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(width: 8),
Text(
'使用场景',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 12),
const Text('• 低电量时减少后台任务'),
const Text('• 充电时执行耗电操作'),
const Text('• 节能模式下降低刷新频率'),
const Text('• 根据电量调整动画效果'),
const Text('• 低电量警告提示用户'),
],
),
),
);
}
}
❓ 第四步:常见问题与解决方案
1. 电池状态返回 unknown
原因:模拟器或某些特殊设备无法获取电池状态。
解决方案:
String getSafeStateText(BatteryState state) {
if (state == BatteryState.unknown) {
return '无法获取';
}
return _getBatteryStateText(state);
}
// 建议在真机上测试
2. 电池状态监听不触发
原因:某些设备不会频繁触发状态变化事件。
解决方案:
// 结合定时刷新和事件监听
class BatteryManager {
final Battery _battery = Battery();
Timer? _refreshTimer;
StreamSubscription? _subscription;
void startMonitoring(Function onUpdate) {
// 定时刷新(每分钟)
_refreshTimer = Timer.periodic(
const Duration(minutes: 1),
(_) => onUpdate(),
);
// 监听状态变化
_subscription = _battery.onBatteryStateChanged.listen((_) => onUpdate());
}
void stopMonitoring() {
_refreshTimer?.cancel();
_subscription?.cancel();
}
}
3. 根据电量优化应用行为
解决方案:
class BatteryAwareTaskManager {
final Battery _battery = Battery();
Future<bool> shouldExecuteTask() async {
final batteryLevel = await _battery.batteryLevel;
final isInSaveMode = await _battery.isInBatterySaveMode;
final state = await _battery.batteryState;
if (batteryLevel < 20 || isInSaveMode) {
return false;
}
if (state == BatteryState.discharging && batteryLevel < 50) {
return false;
}
return true;
}
Future<void> executeHeavyTask() async {
if (await shouldExecuteTask()) {
print('执行耗电任务');
} else {
print('跳过耗电任务');
}
}
}
4. 低电量警告提示
解决方案:
class LowBatteryWarning {
final Battery _battery = Battery();
StreamSubscription? _subscription;
static const int _warningThreshold = 20;
bool _hasShownWarning = false;
void startMonitoring(BuildContext context) {
_subscription = _battery.onBatteryStateChanged.listen((state) async {
if (state == BatteryState.discharging) {
final level = await _battery.batteryLevel;
if (level < _warningThreshold && !_hasShownWarning) {
_hasShownWarning = true;
_showWarningDialog(context, level);
} else if (level >= _warningThreshold) {
_hasShownWarning = false;
}
}
});
}
void _showWarningDialog(BuildContext context, int level) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Row(
children: [
Icon(Icons.battery_alert, color: Colors.red),
SizedBox(width: 8),
Text('低电量警告'),
],
),
content: Text('当前电量仅剩 $level%,请及时充电'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('知道了'),
),
],
),
);
}
void stopMonitoring() {
_subscription?.cancel();
}
}
5. 充电状态检测
解决方案:
Future<bool> isCharging() async {
final battery = Battery();
final state = await battery.batteryState;
return state == BatteryState.charging || state == BatteryState.full;
}
Future<void> performHeavyTask() async {
if (await isCharging()) {
print('正在充电,可以执行耗电任务');
// 执行同步、下载、处理等任务
} else {
print('未在充电,建议推迟耗电任务');
}
}
6. 结合 StreamBuilder 实现响应式 UI
解决方案:
class BatteryStatusWidget extends StatelessWidget {
final Battery _battery = Battery();
BatteryStatusWidget({super.key});
Widget build(BuildContext context) {
return StreamBuilder<BatteryState>(
stream: _battery.onBatteryStateChanged,
builder: (context, snapshot) {
final state = snapshot.data ?? BatteryState.unknown;
return FutureBuilder<int>(
future: _battery.batteryLevel,
builder: (context, levelSnapshot) {
final level = levelSnapshot.data ?? 0;
return ListTile(
leading: Icon(
state == BatteryState.charging
? Icons.battery_charging_full
: Icons.battery_std,
color: level < 20 ? Colors.red : Colors.green,
),
title: Text('电量: $level%'),
subtitle: Text('状态: ${state.name}'),
);
},
);
},
);
}
}
📚 API 参考
Battery 类
| 属性/方法 | 返回值 | 说明 |
|---|---|---|
batteryLevel |
Future<int> |
电池电量百分比 |
batteryState |
Future<BatteryState> |
电池状态 |
isInBatterySaveMode |
Future<bool> |
是否节能模式 |
onBatteryStateChanged |
Stream<BatteryState> |
状态变化流 |
BatteryState 枚举
| 值 | 说明 |
|---|---|
full |
满电状态 |
charging |
充电中 |
discharging |
放电中 |
unknown |
未知状态 |
🎉 总结
本文详细介绍了 battery_plus 库在 OpenHarmony 平台上的使用方法,包括:
- 环境配置:添加依赖配置
- API 使用:获取电量、状态、节能模式等信息
- 完整示例:包含信息展示、状态监听的电池监测应用
- 问题解决:常见问题的排查和解决方案
通过电池状态监测功能,开发者可以:
- 根据电量优化应用行为
- 在充电时执行耗电任务
- 低电量时减少后台活动
- 提供更好的用户体验
battery_plus 提供了完整的电池信息获取能力,是 OpenHarmony 平台上实现电池状态监测的理想选择。
更多推荐

所有评论(0)