Flutter电池充电提醒器:智能保护电池健康

项目简介

电池充电提醒器是一款帮助用户保护电池健康的智能应用。通过监控电池充电状态,在达到设定电量时及时提醒用户拔掉充电器,避免过度充电,延长电池使用寿命。支持自定义目标电量、充电记录查看等功能。
运行效果图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

核心功能

  • 实时监控:实时显示电池电量和状态
  • 智能提醒:达到目标电量自动提醒
  • 电池可视化:直观的电池图形显示
  • 状态监测:温度、电压、健康度监测
  • 充电记录:记录每次充电详情
  • 保养建议:提供电池保养小贴士

应用特色

特色 说明
智能提醒 自定义目标电量,智能提醒
可视化 CustomPainter绘制电池图形
实时监控 每2秒更新电池状态
详细记录 记录充电时长、增量
健康建议 提供专业保养建议

功能架构

电池充电提醒器

主监控页

充电记录

设置

电池显示

状态监测

充电详情

保养建议

电量百分比

充电状态

目标电量

温度监测

电压监测

健康度

充电时长

充电增量

提醒状态

充电建议

保养技巧

历史记录

充电统计

目标电量

提醒开关

核心功能详解

1. 电池状态监控

实时监控电池电量和充电状态。

状态枚举:

enum BatteryState {
  charging,      // 充电中
  discharging,   // 放电中
  full,          // 已充满
  unknown,       // 未知
}

监控实现:

void _startMonitoring() {
  _timer = Timer.periodic(const Duration(seconds: 2), (timer) {
    setState(() {
      _updateBatteryStatus();
      _checkReminder();
    });
  });
}

void _checkReminder() {
  if (_reminderEnabled && 
      _batteryState == BatteryState.charging &&
      _batteryLevel >= _targetLevel &&
      !_hasReminded) {
    _hasReminded = true;
    _showReminderDialog();
  }
  
  if (_batteryLevel < _targetLevel) {
    _hasReminded = false;
  }
}

监控特点:

  • 每2秒更新一次状态
  • 检查是否达到目标电量
  • 避免重复提醒
  • 电量下降后重置提醒状态

2. 智能提醒功能

达到目标电量时弹出提醒对话框。

提醒对话框:

void _showReminderDialog() {
  if (!mounted) return;
  
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (context) => AlertDialog(
      title: Row(
        children: [
          Icon(Icons.battery_charging_full, 
            color: Colors.green[700]),
          const SizedBox(width: 8),
          const Text('充电提醒'),
        ],
      ),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Text(
            '电池已充至 $_batteryLevel%',
            style: const TextStyle(
              fontSize: 18, 
              fontWeight: FontWeight.bold
            ),
          ),
          const SizedBox(height: 8),
          const Text('建议拔掉充电器,保护电池健康'),
        ],
      ),
      actions: [
        TextButton(
          onPressed: () {
            Navigator.pop(context);
            setState(() => _reminderEnabled = false);
          },
          child: const Text('关闭提醒'),
        ),
        FilledButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('知道了'),
        ),
      ],
    ),
  );
}

提醒逻辑:

  1. 检查提醒是否启用
  2. 检查是否正在充电
  3. 检查电量是否达到目标
  4. 检查是否已经提醒过
  5. 弹出提醒对话框

3. 电池可视化

使用CustomPainter绘制电池图形。

电池绘制:

class BatteryPainter extends CustomPainter {
  final int level;
  final bool isCharging;

  BatteryPainter({required this.level, required this.isCharging});

  
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 3
      ..color = Colors.white;

    // 绘制电池外壳
    final bodyRect = RRect.fromRectAndRadius(
      Rect.fromLTWH(10, 20, size.width - 20, size.height - 40),
      const Radius.circular(8),
    );
    canvas.drawRRect(bodyRect, paint);

    // 绘制电池头部
    final headRect = RRect.fromRectAndRadius(
      Rect.fromLTWH(
        size.width * 0.35,
        0,
        size.width * 0.3,
        20,
      ),
      const Radius.circular(4),
    );
    canvas.drawRRect(headRect, paint);

    // 绘制电量
    final fillPaint = Paint()
      ..style = PaintingStyle.fill
      ..color = Colors.white;

    final fillHeight = (size.height - 50) * (level / 100);
    final fillRect = RRect.fromRectAndRadius(
      Rect.fromLTWH(
        15,
        size.height - 25 - fillHeight,
        size.width - 30,
        fillHeight,
      ),
      const Radius.circular(4),
    );
    canvas.drawRRect(fillRect, fillPaint);

    // 绘制充电图标
    if (isCharging) {
      final boltPaint = Paint()
        ..style = PaintingStyle.fill
        ..color = Colors.yellow[700]!;

      final boltPath = Path()
        ..moveTo(size.width * 0.5, size.height * 0.3)
        ..lineTo(size.width * 0.4, size.height * 0.5)
        ..lineTo(size.width * 0.5, size.height * 0.5)
        ..lineTo(size.width * 0.4, size.height * 0.7)
        ..lineTo(size.width * 0.6, size.height * 0.5)
        ..lineTo(size.width * 0.5, size.height * 0.5)
        ..close();

      canvas.drawPath(boltPath, boltPaint);
    }
  }

  
  bool shouldRepaint(BatteryPainter oldDelegate) =>
      level != oldDelegate.level || isCharging != oldDelegate.isCharging;
}

绘制组成:

  • 电池外壳:圆角矩形
  • 电池头部:小矩形
  • 电量填充:根据电量百分比填充
  • 充电图标:闪电形状

使用方式:

CustomPaint(
  size: const Size(120, 180),
  painter: BatteryPainter(
    level: _batteryLevel,
    isCharging: _batteryState == BatteryState.charging,
  ),
)

4. 状态监测

监测温度、电压、健康度。

状态显示:

Widget _buildStatusItem(
  IconData icon,
  String label,
  String value,
  Color color,
) {
  return Column(
    children: [
      Icon(icon, size: 32, color: color),
      const SizedBox(height: 8),
      Text(
        label,
        style: TextStyle(fontSize: 14, color: Colors.grey[600]),
      ),
      const SizedBox(height: 4),
      Text(
        value,
        style: const TextStyle(
          fontSize: 16,
          fontWeight: FontWeight.bold,
        ),
      ),
    ],
  );
}

温度颜色:

Color _getTemperatureColor() {
  if (_temperature > 40) return Colors.red;
  if (_temperature > 35) return Colors.orange;
  return Colors.green;
}

监测项目:

  • 温度:正常 < 35°C,警告 35-40°C,危险 > 40°C
  • 电压:3200-4000mV
  • 健康度:良好/一般/较差

5. 充电记录

记录每次充电的详细信息。

记录模型:

class ChargingRecord {
  final DateTime startTime;    // 开始时间
  final DateTime? endTime;     // 结束时间
  final int startLevel;        // 开始电量
  final int? endLevel;         // 结束电量
  final Duration? duration;    // 充电时长

  ChargingRecord({
    required this.startTime,
    this.endTime,
    required this.startLevel,
    this.endLevel,
    this.duration,
  });
}

记录保存:

void _toggleCharging() {
  setState(() {
    if (_batteryState == BatteryState.charging || 
        _batteryState == BatteryState.full) {
      // 停止充电,保存记录
      _batteryState = BatteryState.discharging;
      if (_chargingStartTime != null && 
          _chargingStartLevel != null) {
        _chargingHistory.insert(
          0,
          ChargingRecord(
            startTime: _chargingStartTime!,
            endTime: DateTime.now(),
            startLevel: _chargingStartLevel!,
            endLevel: _batteryLevel,
            duration: DateTime.now()
              .difference(_chargingStartTime!),
          ),
        );
      }
      _chargingStartTime = null;
      _chargingStartLevel = null;
    } else {
      // 开始充电
      _batteryState = BatteryState.charging;
      _chargingStartTime = DateTime.now();
      _chargingStartLevel = _batteryLevel;
      _hasReminded = false;
    }
  });
}

6. 设置功能

自定义目标电量和提醒开关。

设置对话框:

void _showSettings() {
  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: const Text('充电设置'),
      content: StatefulBuilder(
        builder: (context, setState) => Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            SwitchListTile(
              title: const Text('启用充电提醒'),
              value: _reminderEnabled,
              onChanged: (value) {
                setState(() => _reminderEnabled = value);
                this.setState(() {});
              },
            ),
            const SizedBox(height: 16),
            Text('目标电量:$_targetLevel%'),
            Slider(
              value: _targetLevel.toDouble(),
              min: 50,
              max: 100,
              divisions: 10,
              label: '$_targetLevel%',
              onChanged: (value) {
                setState(() => _targetLevel = value.toInt());
                this.setState(() {});
              },
            ),
            const SizedBox(height: 8),
            Text(
              '建议设置为 80% 以延长电池寿命',
              style: TextStyle(
                fontSize: 12, 
                color: Colors.grey[600]
              ),
            ),
          ],
        ),
      ),
      actions: [
        FilledButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('确定'),
        ),
      ],
    ),
  );
}

界面设计要点

1. 电池显示卡片

渐变背景根据电量变化:

List<Color> _getBatteryGradient() {
  if (_batteryLevel >= 80) {
    return [Colors.green[400]!, Colors.green[700]!];
  } else if (_batteryLevel >= 50) {
    return [Colors.blue[400]!, Colors.blue[700]!];
  } else if (_batteryLevel >= 20) {
    return [Colors.orange[400]!, Colors.orange[700]!];
  } else {
    return [Colors.red[400]!, Colors.red[700]!];
  }
}

2. 状态卡片布局

统一的信息展示样式:

Widget _buildDetailRow(String label, String value) {
  return Padding(
    padding: const EdgeInsets.symmetric(vertical: 8),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Text(
          label,
          style: TextStyle(color: Colors.grey[600]),
        ),
        Text(
          value,
          style: const TextStyle(fontWeight: FontWeight.bold),
        ),
      ],
    ),
  );
}

3. 颜色方案

电量范围 颜色 说明
80-100% Green 电量充足
50-79% Blue 电量正常
20-49% Orange 电量偏低
0-19% Red 电量不足

数据模型设计

充电记录模型

class ChargingRecord {
  final DateTime startTime;    // 开始时间
  final DateTime? endTime;     // 结束时间
  final int startLevel;        // 开始电量
  final int? endLevel;         // 结束电量
  final Duration? duration;    // 充电时长
}

核心技术要点

1. Timer定时器

定期更新电池状态:

Timer? _timer;

void _startMonitoring() {
  _timer = Timer.periodic(
    const Duration(seconds: 2), 
    (timer) {
      setState(() {
        _updateBatteryStatus();
        _checkReminder();
      });
    }
  );
}


void dispose() {
  _timer?.cancel();
  super.dispose();
}

2. CustomPainter

自定义电池图形绘制:

class BatteryPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    // 绘制逻辑
  }

  
  bool shouldRepaint(BatteryPainter oldDelegate) =>
      level != oldDelegate.level || 
      isCharging != oldDelegate.isCharging;
}

3. StatefulBuilder

对话框内部状态管理:

StatefulBuilder(
  builder: (context, setState) => Column(
    children: [
      Slider(
        value: _targetLevel.toDouble(),
        onChanged: (value) {
          setState(() => _targetLevel = value.toInt());
          this.setState(() {});  // 更新外部状态
        },
      ),
    ],
  ),
)

功能扩展建议

1. 真实电池API集成

使用battery_plus插件获取真实电池信息:

import 'package:battery_plus/battery_plus.dart';

class BatteryService {
  final Battery _battery = Battery();
  
  Stream<BatteryState> get batteryStateStream => 
    _battery.onBatteryStateChanged;
  
  Future<int> getBatteryLevel() async {
    return await _battery.batteryLevel;
  }
  
  Future<BatteryState> getBatteryState() async {
    return await _battery.batteryState;
  }
}

// 使用
class _BatteryPageState extends State<BatteryPage> {
  final BatteryService _batteryService = BatteryService();
  StreamSubscription? _subscription;
  
  
  void initState() {
    super.initState();
    _initBattery();
  }
  
  void _initBattery() async {
    // 获取初始电量
    _batteryLevel = await _batteryService.getBatteryLevel();
    
    // 监听状态变化
    _subscription = _batteryService.batteryStateStream
      .listen((state) {
        setState(() {
          _batteryState = state;
        });
      });
  }
  
  
  void dispose() {
    _subscription?.cancel();
    super.dispose();
  }
}

2. 本地通知

使用flutter_local_notifications发送通知:

import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class NotificationService {
  final FlutterLocalNotificationsPlugin _notifications =
    FlutterLocalNotificationsPlugin();
  
  Future<void> initialize() async {
    const androidSettings = AndroidInitializationSettings(
      '@mipmap/ic_launcher'
    );
    const iosSettings = DarwinInitializationSettings();
    
    const settings = InitializationSettings(
      android: androidSettings,
      iOS: iosSettings,
    );
    
    await _notifications.initialize(settings);
  }
  
  Future<void> showChargingReminder(int level) async {
    const androidDetails = AndroidNotificationDetails(
      'charging_reminder',
      '充电提醒',
      channelDescription: '电池充电提醒通知',
      importance: Importance.high,
      priority: Priority.high,
    );
    
    const iosDetails = DarwinNotificationDetails();
    
    const details = NotificationDetails(
      android: androidDetails,
      iOS: iosDetails,
    );
    
    await _notifications.show(
      0,
      '充电提醒',
      '电池已充至 $level%,建议拔掉充电器',
      details,
    );
  }
}

3. 数据持久化

使用SharedPreferences保存设置和记录:

import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

class StorageService {
  Future<void> saveSettings({
    required int targetLevel,
    required bool reminderEnabled,
  }) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setInt('target_level', targetLevel);
    await prefs.setBool('reminder_enabled', reminderEnabled);
  }
  
  Future<Map<String, dynamic>> loadSettings() async {
    final prefs = await SharedPreferences.getInstance();
    return {
      'targetLevel': prefs.getInt('target_level') ?? 80,
      'reminderEnabled': prefs.getBool('reminder_enabled') ?? true,
    };
  }
  
  Future<void> saveChargingHistory(
    List<ChargingRecord> records
  ) async {
    final prefs = await SharedPreferences.getInstance();
    final jsonList = records.map((r) => {
      'startTime': r.startTime.toIso8601String(),
      'endTime': r.endTime?.toIso8601String(),
      'startLevel': r.startLevel,
      'endLevel': r.endLevel,
      'duration': r.duration?.inSeconds,
    }).toList();
    await prefs.setString(
      'charging_history', 
      jsonEncode(jsonList)
    );
  }
  
  Future<List<ChargingRecord>> loadChargingHistory() async {
    final prefs = await SharedPreferences.getInstance();
    final jsonStr = prefs.getString('charging_history');
    if (jsonStr == null) return [];
    
    final jsonList = jsonDecode(jsonStr) as List;
    return jsonList.map((json) => ChargingRecord(
      startTime: DateTime.parse(json['startTime']),
      endTime: json['endTime'] != null 
        ? DateTime.parse(json['endTime']) 
        : null,
      startLevel: json['startLevel'],
      endLevel: json['endLevel'],
      duration: json['duration'] != null 
        ? Duration(seconds: json['duration']) 
        : null,
    )).toList();
  }
}

4. 充电统计

统计充电数据和趋势:

class ChargingStatistics {
  final List<ChargingRecord> records;
  
  ChargingStatistics(this.records);
  
  int get totalChargingCount => records.length;
  
  Duration get totalChargingTime {
    return records.fold(
      Duration.zero,
      (sum, record) => sum + (record.duration ?? Duration.zero),
    );
  }
  
  double get averageChargingTime {
    if (records.isEmpty) return 0;
    final total = totalChargingTime.inMinutes;
    return total / records.length;
  }
  
  int get averageChargingIncrease {
    if (records.isEmpty) return 0;
    final total = records.fold(0, (sum, record) {
      if (record.endLevel != null) {
        return sum + (record.endLevel! - record.startLevel);
      }
      return sum;
    });
    return total ~/ records.length;
  }
  
  Map<String, int> getChargingByDay() {
    final Map<String, int> result = {};
    for (var record in records) {
      final date = DateFormat('yyyy-MM-dd')
        .format(record.startTime);
      result[date] = (result[date] ?? 0) + 1;
    }
    return result;
  }
}

// 统计页面
class StatisticsPage extends StatelessWidget {
  final ChargingStatistics statistics;
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('充电统计')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          _buildStatCard(
            '总充电次数',
            '${statistics.totalChargingCount}次',
            Icons.battery_charging_full,
          ),
          _buildStatCard(
            '总充电时长',
            _formatDuration(statistics.totalChargingTime),
            Icons.access_time,
          ),
          _buildStatCard(
            '平均充电时长',
            '${statistics.averageChargingTime.toStringAsFixed(1)}分钟',
            Icons.timer,
          ),
          _buildStatCard(
            '平均充电增量',
            '${statistics.averageChargingIncrease}%',
            Icons.trending_up,
          ),
        ],
      ),
    );
  }
}

5. 充电提醒音

添加提醒音效:

import 'package:audioplayers/audioplayers.dart';

class SoundService {
  final AudioPlayer _player = AudioPlayer();
  
  Future<void> playReminderSound() async {
    await _player.play(
      AssetSource('sounds/reminder.mp3')
    );
  }
  
  Future<void> playChargingSound() async {
    await _player.play(
      AssetSource('sounds/charging.mp3')
    );
  }
  
  void dispose() {
    _player.dispose();
  }
}

6. 桌面小部件

使用home_widget创建桌面小部件:

import 'package:home_widget/home_widget.dart';

class WidgetService {
  Future<void> updateWidget({
    required int batteryLevel,
    required String batteryState,
  }) async {
    await HomeWidget.saveWidgetData(
      'battery_level',
      batteryLevel,
    );
    await HomeWidget.saveWidgetData(
      'battery_state',
      batteryState,
    );
    await HomeWidget.updateWidget(
      name: 'BatteryWidgetProvider',
      iOSName: 'BatteryWidget',
    );
  }
}

7. 充电优化建议

基于充电数据提供优化建议:

class ChargingAdvisor {
  String getAdvice(ChargingRecord record) {
    if (record.endLevel != null) {
      final increase = record.endLevel! - record.startLevel;
      final duration = record.duration?.inMinutes ?? 0;
      
      if (record.endLevel! > 90) {
        return '建议充电至80-85%即可,避免过度充电';
      }
      
      if (record.startLevel < 20) {
        return '建议在电量20%以上时充电,避免深度放电';
      }
      
      if (duration > 180) {
        return '充电时间较长,建议检查充电器和数据线';
      }
      
      if (increase < 20 && duration > 60) {
        return '充电效率较低,建议更换充电器';
      }
    }
    
    return '充电正常,继续保持良好习惯';
  }
  
  List<String> getHealthTips() {
    return [
      '建议充电至80%即可,避免过度充电',
      '避免电量低于20%再充电',
      '充电时避免使用高耗电应用',
      '定期进行完整充放电循环(每月1次)',
      '避免在高温环境下充电',
      '使用原装或认证充电器',
      '不要边充电边玩游戏',
      '夜间充电建议使用慢充',
    ];
  }
}

8. 充电曲线图

使用fl_chart绘制充电曲线:

import 'package:fl_chart/fl_chart.dart';

class ChargingChart extends StatelessWidget {
  final List<ChargingRecord> records;
  
  
  Widget build(BuildContext context) {
    return LineChart(
      LineChartData(
        lineBarsData: [
          LineChartBarData(
            spots: _getSpots(),
            isCurved: true,
            color: Colors.green,
            barWidth: 3,
            dotData: FlDotData(show: true),
          ),
        ],
        titlesData: FlTitlesData(
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 40,
              getTitlesWidget: (value, meta) {
                return Text('${value.toInt()}%');
              },
            ),
          ),
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              getTitlesWidget: (value, meta) {
                final index = value.toInt();
                if (index >= 0 && index < records.length) {
                  return Text(
                    DateFormat('HH:mm')
                      .format(records[index].startTime),
                  );
                }
                return const Text('');
              },
            ),
          ),
        ),
      ),
    );
  }
  
  List<FlSpot> _getSpots() {
    return records.asMap().entries.map((entry) {
      return FlSpot(
        entry.key.toDouble(),
        entry.value.endLevel?.toDouble() ?? 0,
      );
    }).toList();
  }
}

项目结构

lib/
├── main.dart                        # 应用入口
├── models/                          # 数据模型
│   ├── battery_state.dart          # 电池状态
│   ├── charging_record.dart        # 充电记录
│   └── charging_statistics.dart    # 充电统计
├── pages/                           # 页面
│   ├── battery_page.dart           # 主监控页面
│   ├── charging_history_page.dart  # 充电记录
│   └── statistics_page.dart        # 统计页面
├── widgets/                         # 组件
│   ├── battery_painter.dart        # 电池绘制
│   ├── status_card.dart            # 状态卡片
│   └── charging_chart.dart         # 充电曲线
├── services/                        # 服务
│   ├── battery_service.dart        # 电池服务
│   ├── notification_service.dart   # 通知服务
│   ├── storage_service.dart        # 存储服务
│   ├── sound_service.dart          # 音效服务
│   └── widget_service.dart         # 小部件服务
└── utils/                           # 工具
    ├── charging_advisor.dart       # 充电建议
    └── formatters.dart             # 格式化工具

使用指南

基本操作

  1. 查看电池状态

    • 打开应用查看当前电量
    • 查看充电状态和温度
  2. 设置目标电量

    • 点击设置图标
    • 调节目标电量滑块
    • 建议设置为80%
  3. 启用提醒

    • 在设置中开启提醒
    • 充电达到目标时自动提醒
  4. 查看充电记录

    • 点击历史图标
    • 查看每次充电详情

电池保养建议

  1. 充电习惯

    • 充至80%即可
    • 避免充满100%
    • 避免低于20%充电
  2. 充电环境

    • 避免高温环境
    • 使用原装充电器
    • 保持通风良好
  3. 使用习惯

    • 充电时避免玩游戏
    • 定期完整充放电
    • 避免边充边用

常见问题

Q1: 为什么建议充至80%?

锂电池特性:

  • 充至100%会增加电池压力
  • 80%是最佳平衡点
  • 可延长电池寿命30%以上

Q2: 如何获取真实电池信息?

使用battery_plus插件:

dependencies:
  battery_plus: ^4.0.0

// 使用
final battery = Battery();
final level = await battery.batteryLevel;
final state = await battery.batteryState;

Q3: 如何实现后台监控?

使用workmanager实现后台任务:

import 'package:workmanager/workmanager.dart';

void callbackDispatcher() {
  Workmanager().executeTask((task, inputData) async {
    // 检查电池状态
    final battery = Battery();
    final level = await battery.batteryLevel;
    
    if (level >= 80) {
      // 发送通知
      await NotificationService().showChargingReminder(level);
    }
    
    return Future.value(true);
  });
}

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Workmanager().initialize(callbackDispatcher);
  
  // 注册周期性任务
  Workmanager().registerPeriodicTask(
    'battery_check',
    'batteryCheckTask',
    frequency: const Duration(minutes: 15),
  );
  
  runApp(const BatteryReminderApp());
}

Q4: 如何优化电池监控性能?

  1. 合理的更新频率
// 不要太频繁
Timer.periodic(const Duration(seconds: 2), (timer) {
  // 更新状态
});
  1. 及时取消定时器

void dispose() {
  _timer?.cancel();
  _subscription?.cancel();
  super.dispose();
}
  1. 使用Stream监听
// 只在状态变化时更新
_subscription = battery.onBatteryStateChanged.listen((state) {
  setState(() => _batteryState = state);
});

Q5: 如何添加充电音效?

import 'package:audioplayers/audioplayers.dart';

class SoundService {
  final AudioPlayer _player = AudioPlayer();
  
  Future<void> playSound(String sound) async {
    await _player.play(AssetSource('sounds/$sound.mp3'));
  }
}

// 在pubspec.yaml中添加音频文件
flutter:
  assets:
    - assets/sounds/reminder.mp3
    - assets/sounds/charging.mp3

性能优化

1. 定时器优化

// 使用合适的更新频率
Timer.periodic(const Duration(seconds: 2), (timer) {
  if (mounted) {
    setState(() {
      _updateBatteryStatus();
    });
  }
});

2. 内存优化

// 限制历史记录数量
if (_chargingHistory.length > 100) {
  _chargingHistory.removeLast();
}

// 及时释放资源

void dispose() {
  _timer?.cancel();
  _subscription?.cancel();
  _player?.dispose();
  super.dispose();
}

3. 绘制优化

// 使用RepaintBoundary
RepaintBoundary(
  child: CustomPaint(
    painter: BatteryPainter(
      level: _batteryLevel,
      isCharging: _batteryState == BatteryState.charging,
    ),
  ),
)

// 优化shouldRepaint

bool shouldRepaint(BatteryPainter oldDelegate) {
  return level != oldDelegate.level || 
         isCharging != oldDelegate.isCharging;
}

总结

电池充电提醒器是一款实用的电池健康管理工具,具有以下特点:

核心优势

  1. 智能提醒:自定义目标电量,及时提醒
  2. 实时监控:电量、温度、电压全面监测
  3. 可视化:直观的电池图形显示
  4. 详细记录:完整的充电历史记录

技术亮点

  1. CustomPainter:自定义电池图形绘制
  2. Timer:定时监控电池状态
  3. StatefulBuilder:对话框状态管理
  4. 渐变背景:根据电量动态变化

应用价值

  • 延长电池使用寿命
  • 养成良好充电习惯
  • 实时监控电池健康
  • 提供专业保养建议

通过集成真实电池API、本地通知、后台监控等功能,这款应用可以成为专业的电池健康管理工具,帮助用户更好地保护设备电池。


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐