如何在Android中获取其他应用/进程的电池使用信息?
获取第三方应用电池与CPU使用数据的可行方案(适配Android 12-14)
一、第三方应用电池使用量获取
1. 官方API方案(Android 12+)
利用BatteryStatsManager结合UsageStatsManager可精准获取目标应用的电池消耗数据,步骤如下:
- 权限准备:
- 在Manifest中声明
android.permission.PACKAGE_USAGE_STATS和android.permission.QUERY_ALL_PACKAGES(Android 13+) - 引导用户手动开启「使用权限访问」(该权限无法通过代码动态申请,需跳转至系统设置页)
- 在Manifest中声明
- 代码实现:
// 获取目标应用UID val packageManager = packageManager val targetPkg = "com.google.android.youtube" val uid = packageManager.getApplicationInfo(targetPkg, 0).uid // 获取电池统计实例 val batteryStatsManager = getSystemService(Context.BATTERY_STATS_SERVICE) as BatteryStatsManager // 拉取过去1小时的电池使用数据 val stats = batteryStatsManager.getBatteryUsageStats( System.currentTimeMillis() - 3600000, System.currentTimeMillis(), BatteryStatsManager.STATS_FLAG_BATTERY_USAGE ) // 提取目标应用的总能耗(单位:mWh) val totalEnergy = stats.getUidBatteryStats(uid)?.totalEnergyConsumed // 转换为mAh(默认按电池电压3.7V计算) val mAhUsage = totalEnergy?.div(3.7) ?: 0.0 // 计算占总电池容量的百分比 val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager val totalCapacity = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) // 单位:mAh val usagePercent = if (totalCapacity > 0) (mAhUsage / totalCapacity) * 100 else 0.0
- 注意:部分设备可能无法返回准确的总电池容量,可尝试读取
/sys/class/power_supply/battery/capacity文件补充,但需处理文件读取失败的情况。
2. 低版本兼容(Android 11及以下)
Android 11及以下无BatteryStatsManager,可通过UsageStatsManager获取应用使用时长,结合系统总电池消耗做估算(精度较低):
val usageStatsManager = getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager val dailyStats = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_DAILY, System.currentTimeMillis() - 86400000, System.currentTimeMillis() ) val targetStats = dailyStats.find { it.packageName == targetPkg } // 结合系统电池总消耗(需自行获取)估算占比,仅作参考
二、第三方应用CPU使用率获取
1. 基于Linux内核文件读取
通过读取/proc文件系统的进程统计信息计算CPU使用率,适配全版本:
- 步骤:
- 获取目标应用的PID(可通过
ActivityManager或packageManager关联) - 读取
/proc/stat获取系统总CPU时间,读取/proc/[pid]/stat获取目标进程的CPU时间 - 间隔1秒后再次读取,通过两次数据的差值计算使用率
- 获取目标应用的PID(可通过
- 代码实现:
fun getTargetCpuUsage(pid: Int): Float { // 第一次读取系统与进程CPU时间 val systemTotal1 = readSystemCpuTotal() val procTotal1 = readProcCpuTotal(pid) if (systemTotal1 == 0L || procTotal1 == 0L) return 0f Thread.sleep(1000) // 第二次读取 val systemTotal2 = readSystemCpuTotal() val procTotal2 = readProcCpuTotal(pid) if (systemTotal2 == 0L || procTotal2 == 0L) return 0f // 计算使用率 val systemDiff = systemTotal2 - systemTotal1 val procDiff = procTotal2 - procTotal1 return if (systemDiff > 0) (procDiff.toFloat() / systemDiff) * 100 else 0f } private fun readSystemCpuTotal(): Long { return runCatching { File("/proc/stat").readLines()[0] .split(" ").filter { it.isNotEmpty() } .subList(1, 8).sumOf { it.toLong() } }.getOrDefault(0L) } private fun readProcCpuTotal(pid: Int): Long { return runCatching { File("/proc/$pid/stat").readLines()[0] .split(" ").filter { it.isNotEmpty() } .subList(13, 17).sumOf { it.toLong() } }.getOrDefault(0L) }
- 权限与适配:
- Android 12+需
QUERY_ALL_PACKAGES权限获取应用PID - 部分厂商可能限制
/proc文件访问,需针对不同品牌设备做兼容性测试
- Android 12+需
三、权限申请注意事项
PACKAGE_USAGE_STATS:必须引导用户跳转至系统设置页开启,跳转代码示例:
startActivity(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS))
QUERY_ALL_PACKAGES:Android 13+需在Manifest声明并动态申请(若targetSdkVersion >=33)
内容的提问来源于stack exchange,提问作者Alexi124
相关产品推荐
相关产品推荐

