How is the Android battery health determined?
Solution 1
To be more specific: The battery health is determined by the driver (in the kernel). Said driver exports information via the sys file system (/sys/class/power_supply, to be exact). The Android daemon healthd (as of KK, 4.4.x) picks up this information, and implements an IBatteryPropertiesRegistrar interface on it. It polls continuously (using epoll_wait to run in a timeout loop for periodic updates, as well as netlink notifications for the POWER subsystem - say, for example, if you connect or disconnect a charger). The system's BatteryStatsService then registers a listener with healthd (via binder) and then gets the data that is published by healthd,
Check out /sys/class/power_supply, and you'll see:
lrwxrwxrwx root root 1970-02-05 14:20 ac -> ../../devices/f9923000.i2c/i2c-84/84-006b/power_supply/ac
lrwxrwxrwx root root 1970-02-05 14:20 batt_therm -> ../../devices/battery_tm_ctrl.78/power_supply/batt_therm
lrwxrwxrwx root root 1970-02-05 14:20 battery -> ../../devices/f9923000.i2c/i2c-84/84-0036/power_supply/battery
lrwxrwxrwx root root 1970-02-05 14:20 touch -> ../../devices/virtual/power_supply/touch
lrwxrwxrwx root root 1970-02-05 14:20 usb -> ../../devices/msm_dwc3/power_supply/usb
lrwxrwxrwx root root 1970-02-05 14:20 wireless -> ../../devices/bq51013b_wlc.77/power_supply/wireless
then check out "battery"
/sys/devices/f9923000.i2c/i2c-84/84-0036/power_supply/battery:
-r--r--r-- root root 4096 2014-02-26 13:26 capacity
-r--r--r-- root root 4096 2014-02-26 13:26 charge_full_design
-r--r--r-- root root 4096 2014-02-26 13:26 current_now
lrwxrwxrwx root root 2014-02-26 13:26 device -> ../../../84-0036
-r--r--r-- root root 4096 2014-02-26 13:26 health
drwxr-xr-x root root 2014-02-26 13:26 power
-r--r--r-- root root 4096 2014-02-26 13:26 present
-r--r--r-- root root 4096 2014-02-26 13:26 status
lrwxrwxrwx root root 2014-02-26 13:26 subsystem -> ../../../../../../class/power_supply
-r--r--r-- root root 4096 2014-02-26 13:26 technology
-r--r--r-- root root 4096 2014-02-26 13:26 temp
-r--r--r-- root root 4096 2014-02-26 13:26 type
-rw-r--r-- root root 4096 2014-02-26 13:26 uevent
-r--r--r-- root root 4096 2014-02-26 13:26 voltage_max_design
-r--r--r-- root root 4096 2014-02-26 13:26 voltage_min_design
-r--r--r-- root root 4096 2014-02-26 13:26 voltage_now
and by looking at the files, all details will be revealed.
Solution 2
By using this code you can get information regarding battery..
private BroadcastReceiver battery_receiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
boolean isPresent = intent.getBooleanExtra("present", false);
String technology = intent.getStringExtra("technology");
int plugged = intent.getIntExtra("plugged", -1);
int scale = intent.getIntExtra("scale", -1);
int health = intent.getIntExtra("health", 0);
int status = intent.getIntExtra("status", 0);
int rawlevel = intent.getIntExtra("level", -1);
int level = 0;
String temp=null;
Bundle bundle = intent.getExtras();
Log.i("BatteryLevel", bundle.toString());
if(isPresent)
{
if (rawlevel >= 0 && scale > 0) {
level = (rawlevel * 100) / scale;
}
String info = "Battery Level: " + level + "%\n";
info += ("Technology: " + technology + "\n");
info += ("Plugged: " + getPlugTypeString(plugged) + "\n");
info += ("Health: " + getHealthString(health) + "\n");
info += ("Status: " + getStatusString(status) + "\n");
info += ("Temp: "+getTempStatus(temp,intent)+"\n");
setBatteryLevelText(info + "\n\n" + bundle.toString());
}
else
{
setBatteryLevelText("Battery not present!!!");
}
}
};
private void registerBatteryLevelReceiver(){
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(battery_receiver, filter);
}
Solution 3
Lithium ion batteries have simple onboard computers that track and report the health; the state indicators are standardized but the conditions that trigger them to be reported by the battery are determined by the battery manufacturer.
simonso
Updated on August 13, 2022Comments
-
simonso over 1 year
I am not talking about how to read the value.
Rather, I am interested in how the value of BatteryManager.EXTRA_HEALTH is being set.
Does it come from the firmware? Manufacturer specific?
What determines these values?
int BATTERY_HEALTH_COLD int BATTERY_HEALTH_DEAD int BATTERY_HEALTH_GOOD int BATTERY_HEALTH_OVERHEAT int BATTERY_HEALTH_OVER_VOLTAGE int BATTERY_HEALTH_UNKNOWN int BATTERY_HEALTH_UNSPECIFIED_FAILURE
Thanks, Simon
-
simonso about 12 yearsThanks so much! I really appreciate your answer - this starts to make sense! A few more questions: 1) does android has some event listener code that would pick up the report from the on-board computer in the battery? Would you give me an example? 2) if not, is this done at the firmware level? 3) does the 3rd party battery manufacturer (the non-OEM one) has to conform a certain spec to mimick the reporting?
-
geekosaur about 12 yearsI don't know details with respect to Android; I was talking in general about Li-ion batteries, which are all pretty much the same (they need smart charger circuitry but that circuitry needs to be tuned for the battery, so it's part of the battery). Suggest you ask on android.stackexchange.com.
-
simonso about 12 yearsThanks, but my original question is, who determined the value returned by intent.getIntExtra("health", 0). The previous answer made sense, it's from the onboard computer of the li-ion battery. I am looking for how that part is being done.