Android BatteryManager替代方案

8

我正在尝试在我的应用程序中获取电池统计数据以进行一些基准测试。神奇的BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER让我查询设备的微安,这很棒。然而,这只是在API 21中引入的,因此可以使用此功能的设备数量非常有限。是否有一种兼容的方法可以在较低版本的API(至4.0)中执行类似的操作?我知道BatteryManager.EXTRA_LEVEL会给我百分比,但那真的不够精细。


我认为没有。据我所知,早期的Android API在这方面很草率。 - StoneBird
1
@StoneBird,你熟悉这个API吗?在一些API 22的设备上,BATTERY_PROPERTY_CHARGE_COUNTER会给我返回-9223372036854775808,也就是Long.MIN_VALUE。这绝对很奇怪。其他设备会给我一个实际的结果。 - David M
你需要关于电池的哪些信息? - TDG
@TDG 我正在寻找一种获取细粒度功耗的方法,例如比较不同算法的功耗。 - David M
你可以使用以下方法获取mAh的电池容量: https://dev59.com/KX7aa4cB1Zd3GeqPwepU - Mohit Rajput
3个回答

11
据我所知,您不能使用旧的公共API来完成这项任务。我曾经开发过一个系统级应用程序,向用户显示电池使用情况统计数据。我的代码是基于Android设置应用程序编写的,我的用户可能需要root访问权限或该应用程序必须使用平台密钥进行签名。您可以查看PowerUsageDetailBatteryInfoPowerUsageSummary类。如果您很幸运,可能会通过JAVA反射获得对隐藏API的访问权限。否则,您需要平台密钥或root权限。内部API经常更改,因此使用起来相当麻烦。

此外,还有一些工具可能会对您有帮助:

  • adb shell dumpsys batterystats
  • adb shell dumpsys batteryinfo
  • 电池历史记录
  • adb shell bugreport

Dumpsys源代码

祝你好运!

编辑:

我的旧项目可能对你有用。


我可以在我的测试设备上获得root访问权限,所以如果可能的话,那将是很好的。我只关心获取我的测试设备的功耗,而不是为了一般用户。 - David M
https://github.com/prt2121/BatUsage 可能有所帮助。不过我现在已经记不清当时具体做了什么了... - pt2121
我会将这个标记为答案,因为它包含了很多有用的信息,但是不幸的是,并非所有设备都记录了监测实际功率使用所需的所有必要信息,因此似乎不可能覆盖每个设备。至少,不是没有付出巨大努力的情况下。 - David M
你的AIDL文件在哪里可以获取? - IshRoid

4
今年早些时候,我读到了一篇有趣的文章,介绍了一种仅基于设备功耗定位智能手机的方法,称为PowerSpy
虽然我自己从未实现/测试过这种方法,但作者声称:
在Android上,通过反复读取以下两个文件来读取手机的总功率表:/sys/class/power_supply/battery/voltage_now和/sys/class/power_supply/battery/current_now。
他们还声称已经在Nexus 4、Nexus 5和HTC上测试了该方法。虽然这并没有具体说明这些设备配备了哪个版本的Android,但是Nexus 4应该带有API级别17,而Nexus 5则带有API级别19,但这两款手机似乎都可以进行操作系统升级。
然而,与其他帖子中提到的方法相比,这似乎是一种根本不同的方法,因此可能值得一提。不幸的是,这似乎是一种低级别的方法,所以可能需要大量的工作才能得到您所需的内容,因为功率(如物理学中的功率)并不真正意味着电池消耗。但也许您需要这种方法。
最后,文章提到访问这两个文件不需要特殊权限(这也是他们进行研究的动力之一)。
编辑:经过思考,如果你绘制P=U*I(如上所述获取U和I),并随时间积分(在这种离散情况下将是求和),你可能会得到一个非常好的电池消耗近似值。也许你还可以考虑加入卡尔曼滤波器(以减弱U和I上的噪声,记住你的算法不是唯一的消费者),那么你可能会得到你想要的结果。

当时这篇论文出来的时候,我确实自己读过。有趣的是,调用 Runtime.getRuntime().exec("cat /sys/class/power_supply/battery/voltage_now") 在某些设备上不起作用,尝试将它们作为文件打开也不行,即使我运行 adb shell cat /sys/class/power_supply/battery/voltage_now 它也可以正常工作。 - David M
看起来这些设备不监测电流,所以这种方法实际上对它们无效。 - David M

0
根据电池监控培训http://developer.android.com/training/monitoring-device-state/battery-monitoring.html,您可以使用以下方法获取当前电池信息:
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float batteryPct = level / (float)scale;

请注意,您需要继续重复调用此函数以获取更新的电池电量。由于唤醒您的应用程序并检查电池电量本身会消耗电量,因此建议:

4
如果您阅读我的帖子,您会发现在 21 级以下的 API 兼容的 BatteryManager 方法并不提供我所需的细节粒度。 - David M
我编辑了上面的答案,代码将适用于API级别21并提供电池统计信息。在实施答案之前,请查看Android开发人员中的电池监视主题,因为我在我的编辑答案中提到了开发者网站的链接。 - kuljeet singh
4
如果你读了我的帖子,就会发现我非常清楚这些API。我正在寻找替代方案,因为它们不能满足我的需求。 - David M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接