You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter实现:获取应用电池使用占比及安卓系统电池统计信息

Flutter 获取安卓应用电池使用百分比数据

核心前提:权限要求

安卓系统对电池统计数据的访问有严格限制,必须申请android.permission.BATTERY_STATS权限,而且这个权限无法通过代码直接申请,需要引导用户跳转到应用的权限设置页面手动开启「查看电池使用情况」权限。

实现步骤

1. 配置安卓Manifest权限

在android/app/src/main/AndroidManifest.xml里添加权限声明:

<uses-permission android:name="android.permission.BATTERY_STATS" />

2. 原生安卓端实现数据获取

在安卓的MainActivity里创建MethodChannel,编写获取电池统计的逻辑:

import android.app.AppOpsManager
import android.content.Context
import android.os.Build
import android.os.Process
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "battery_stats"

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getAppBatteryUsage") {
                if (hasBatteryStatsPermission()) {
                    val batteryUsage = getAppBatteryUsage()
                    result.success(batteryUsage)
                } else {
                    result.error("PERMISSION_DENIED", "需要开启电池统计权限", null)
                }
            } else {
                result.notImplemented()
            }
        }
    }

    private fun hasBatteryStatsPermission(): Boolean {
        val appOps = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
        val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            appOps.unsafeCheckOpNoThrow(AppOpsManager.OPSTR_BATTERY_STATS, Process.myUid(), packageName)
        } else {
            appOps.checkOpNoThrow(AppOpsManager.OPSTR_BATTERY_STATS, Process.myUid(), packageName)
        }
        return mode == AppOpsManager.MODE_ALLOWED
    }

    private fun getAppBatteryUsage(): Double? {
        val batteryStatsManager = getSystemService(Context.BATTERY_STATS_SERVICE) as android.os.BatteryStatsManager
        val uid = Process.myUid()
        // 获取当前应用的电池使用百分比(相对于总电池消耗)
        val usagePercent = batteryStatsManager.getBatteryUsagePercentage(
            setOf(uid),
            android.os.BatteryStatsManager.STATS_SINCE_CHARGED,
            System.currentTimeMillis()
        )
        return usagePercent
    }
}

3. Flutter端调用原生方法

在Flutter代码里,通过MethodChannel调用原生接口,同时处理权限引导:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';

class BatteryStatsPage extends StatefulWidget {
  const BatteryStatsPage({super.key});

  @override
  State<BatteryStatsPage> createState() => _BatteryStatsPageState();
}

class _BatteryStatsPageState extends State<BatteryStatsPage> {
  static const platform = MethodChannel('battery_stats');
  double? _batteryUsagePercent;
  String? _errorMessage;

  Future<void> _getBatteryUsage() async {
    try {
      final double result = await platform.invokeMethod('getAppBatteryUsage');
      setState(() {
        _batteryUsagePercent = result;
        _errorMessage = null;
      });
    } on PlatformException catch (e) {
      setState(() {
        _errorMessage = e.message;
        _batteryUsagePercent = null;
        // 引导用户去开启权限
        _openPermissionSettings();
      });
    }
  }

  Future<void> _openPermissionSettings() async {
    final Uri url = Uri.parse('package:${await platform.invokeMethod('getPackageName')}');
    if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
      throw Exception('无法打开设置页面');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('电池使用统计')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            if (_batteryUsagePercent != null)
              Text(
                '当前应用电池使用占比: ${_batteryUsagePercent!.toStringAsFixed(2)}%',
                style: const TextStyle(fontSize: 18),
              ),
            if (_errorMessage != null)
              Text(
                _errorMessage!,
                style: const TextStyle(color: Colors.red, fontSize: 16),
              ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _getBatteryUsage,
              child: const Text('获取电池使用数据'),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项

  • 上述代码仅适配安卓10及以上版本,低版本系统可能需要调整BatteryStatsManager的调用逻辑,或者使用旧的BatteryStats API。
  • 不同安卓厂商可能对权限页面有自定义,引导用户开启时可能需要适配不同品牌的路径。
  • 电池使用百分比是相对于设备自上次充电以来的总消耗占比,和系统设置里展示的数据逻辑一致。

内容的提问来源于stack exchange,提问作者Joel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 13:20:32