I’m trying to get battery stats in my application for some benchmarking. The wonderful BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER lets me query the device’s micro-amps which is great. However, this was only introduced in API 21 so the number of devices this can reach is quite limited. Is there a compatible way to do something similar in lower versions of the APIs (down to 4.0)? I know BatteryManager.EXTRA_LEVEL will give me the percentage but that’s really not fine-grained.
As far as I know, you can’t do that with older public APIs. I worked on a system-level app that shows battery usage stats to a user. I based my code from Android Settings app and my users might need root access or the app has to be signed with platform key. You can look into PowerUsageDetail, BatteryInfo, and PowerUsageSummary classes. If you are lucky, you might get access to hidden APIs with JAVA reflection. Otherwise, you need platform key or root. The internal APIs change very often so it’s quite a pain to use.
There are also a couple tools that you might want to check out:
- adb shell dumpsys batterystats
- adb shell dumpsys batteryinfo
- battery historian
- adb shell bugreport
Earlier this year I ran into an interesting article about a method to locate smartphones based only on the power consumption of the device, called PowerSpy.
While I have never implemented/tested the method myself, the authors claim that:
On Android reading the phone’s aggregate power meter is done by repeatedly reading the following two files:
They also claim to have tested the method on Nexus 4, Nexus 5 and HTC. While this is not that specific about which exact versions of Android the devices were equipped with, Nexus 4 is supposed to come with API level 17 and Nexus 5 with API level 19, but both phones seem to be subject to OS upgrades.
However, this seems to be a radically different method when compared with the ones mentioned by the other posters, so probably worth mentioning. Unfortunately, it seems to be a low-level approach, so a lot of work might be required to get what you need, since power, as in Physics, does not really mean battery consumption. But maybe you need it this way.
Last, the article mentioned that access to the two files requires no special permissions (which kind of motivated the study they did in the first place).
Second thought, if you plot
P=U*I (getting U and I as mentioned above) and integrate over time (that would be a sum in this discrete case) you might just get a very good approximation of battery consumption. Maybe you also factor in a Kalman filter (to attenuate the noise on U and I, keeping in mind that your algorithms are not the only consumer) and you might just get what you want.
As Per the battery monitoring training http://developer.android.com/training/monitoring-device-state/battery-monitoring.html , you can get the current battery information by using:
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;
Note that you need to continue to call this repeatedly to get the updated battery level. As waking up your app and checking this does take battery itself, they suggest: