Reputation: 166
I'm using the following code to get the voltage of a battery at two different times (t1,t2). t1 is before the execution of a task and t2 is after the execution of a task. So by rule, t2 must be smaller than t1.
However, in execution it is not true. I am getting multiple values, that are greater, smaller and equal to t1. How could this be possible? Even in android battery monitoring tools, I have noticed that sometimes the total battery mAh value increases few points without plugging the charger.
public void onCreate() {
BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
int scale = -1;
int level = -1;
int voltage = -1;
int temp = -1;
@Override
public void onReceive(Context context, Intent intent) {
level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
Log.e("BatteryManager", "level is "+level+"/"+scale+", temp is "+temp+", voltage is "+voltage);
}
};
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryReceiver, filter);
}
Upvotes: 0
Views: 1359
Reputation: 2049
How could this be possible?
The battery mAh value is measured as voltage from the battery. But this voltage varies from time to time. It drops a little when there is a high current draw and goes back when, for example the processor is idle. Also it changes on temperature change. So overall it is very inaccurate.
Upvotes: 0
Reputation: 14271
Android framework continously get information from its power_supply subsystem. So after an update, it will send out an BATTERY_STATE_CHANGED intent.
private void updateLocked() {
if (!mUpdatesStopped) {
// Update the values of mAcOnline, et. all.
native_update();
// Process the new values. Sendout the intent
processValuesLocked();
}
}
But it just update the information after a period. So it might contains some extent of inaccuracy.
In the implementation of the native_update. Android simply reads out the content of some files under /sys/class/power_supply/battery
setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline);
setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline);
setBooleanField(env, obj, gPaths.wirelessOnlinePath, gFieldIds.mWirelessOnline);
setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);
setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage);
setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature);
So if you want the voltage information, you can simply:
$cat /sys/class/power_supply/battery/voltage_now
$cat /sys/class/power_supply/battery/batt_vol
Note that voltage_now is in microvolts, not millivolts.
You can also read it programatically if you want.
However, it may still not accurate enough since the content of these data is updated by the opearting system(might be something like a power driver), so for really accurate stats, you may have to try hardware approach.:)
Upvotes: 1