问题
So I currently have the following commonly used method of acquiring the current battery level implemented in my android app.
int getBatteryPercent(){
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = this.registerReceiver(null, ifilter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
return level;
}
The problem is that this returns an integer 0-100. In order to ensure accuracy of one of my algorithms, I need to be able to get a more precise measure of the battery level. I've seen some battery management apps show the mV which would work perfectly. If anyone knows how to get this value, any help would greatly be appreciated.
To clarify: I need the CURRENT battery level, not the total capacity of the battery.
Thank you!
------------------------UPDATE---------------------------
I am now using the following code:
// Method for getting the current battery percentage
int getBatteryPercent(){
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = this.registerReceiver(null, ifilter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
return level;
}
// Method for getting the total battery capacity
double getBatteryCapacity() {
double battCapacity = 0.0d;
Object mPowerProfile_ = null;
Log.d("Debug", "in getBatteryCapacity()");
final String POWER_PROFILE_CLASS = "com.android.internal.os.PowerProfile";
try {
mPowerProfile_ = Class.forName(POWER_PROFILE_CLASS)
.getConstructor(Context.class).newInstance(this);
} catch (Exception e) {
e.printStackTrace();
Log.d("Debug", "Try 1 - Exception e: " + e.toString());
}
try {
battCapacity = (Double) Class
.forName(POWER_PROFILE_CLASS)
.getMethod("getAveragePower", java.lang.String.class)
.invoke(mPowerProfile_, "battery.capacity");
Log.d("Debug", "battCapacity is now: " + battCapacity);
} catch (Exception e) {
e.printStackTrace();
Log.d("Debug", "Try 2 - Exception e: " + e.toString());
}
Log.d("Debug", "Leaving getBatteryCapacity()");
return battCapacity;
}
// Method for getting the exact current battery level
double getExactBattery(){
Log.d("Debug", "In getExactBattery()");
float batteryPercentage = getBatteryPercent();
Log.d("Debug", "batteryPercentage = " + batteryPercentage);
double totalCapacity = getBatteryCapacity();
Log.d("Debug", "totalCapacity = " + totalCapacity);
double currLevel = (totalCapacity * (double)batteryPercentage) / 100.0d;
Log.d("Debug", "currLevel = " + currLevel);
return currLevel;
}
But the getBatteryCapacity method is giving me a 0.0 return:
01-20 06:37:27.314 7162-7162/com... D/Debug﹕ In getExactBattery()
01-20 06:37:27.324 7162-7162/com... D/Debug﹕ batteryPercentage = 47.0
01-20 06:37:27.329 7162-7162/com... D/Debug﹕ in getBatteryCapacity()
01-20 06:46:00.644 9207-9207/com... D/Debug﹕ battCapacity is now: 0.0
01-20 06:37:27.329 7162-7162/com... D/Debug﹕ Leaving getBatteryCapacity()
01-20 06:37:27.329 7162-7162/com... D/Debug﹕ totalCapacity = 0.0
01-20 06:37:27.329 7162-7162/com... D/Debug﹕ currLevel = 0.0
I have a Droid Ultra running on Android 4.4.4 and this code does not work, it returns 0.0, however when run on an emulator with multiple android versions it does in fact work. I'm curious to see if any other users testing on a Droid Ultra have the same problem. The above code should work on most devices.
This is actually NOT the exact battery level. Using this algorithm if the battery percent was 97% and the total capacity was 1000, the exact battery level would read 970. Now, if the ACTUAL battery percentage is 96.7%, my getBatteryPercent would return 97. This would result in the SAME EXACT ANSWER. So this algorithm is NOT the answer to this question. I am still looking for an answer to this question!!! I need a measure of the battery level that is more precise than +-1%...
------------------------UPDATE---------------------------
I found out that if you use getIntExtra("voltage", -1) in a broadcast receiver listening for ACTION_BATTERY_CHANGED. It gives you the mV. I wonder if this value is reliable enough to use for battery life predictions. Does anyone know of a way I can grab the voltage at any point in time without relying on the most recent update from my broadcast receiver?
EDIT: Turns out it's not viable. this graph shows that battery voltage is a very poor indicator of battery capacity.
回答1:
Get the battery capacity according @user87049's link and use your own function to get the current battery percentage and combine those two to get a current capacity.
int batteryPercentage = getBatteryPercentage() //Your function
double batteryCapacity = getBatteryCapacity() //code from link from user87049. Change it to return value
double currentCapacity = (batteryPercentage * batteryCapacity) / 100
回答2:
This function will help you.
public float getBatteryPCT()
{
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = this.registerReceiver(null, ifilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
//Check if charging.
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
//Check if charger plugged in.
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
//check if charging via USB.
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
//check if charging via AC.
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float batteryPct = level / (float)scale;
//Get the current battery percentage.
return batteryPct*100;
}
回答3:
According to this answer, you can get the Batter mAH value by the following:
public double getBatteryCapacity() {
Object mPowerProfile_ = null;
final String POWER_PROFILE_CLASS = "com.android.internal.os.PowerProfile";
try {
mPowerProfile_ = Class.forName(POWER_PROFILE_CLASS)
.getConstructor(Context.class).newInstance(this);
} catch (Exception e) {
e.printStackTrace();
}
try {
double batteryCapacity = (Double) Class
.forName(POWER_PROFILE_CLASS)
.getMethod("getAveragePower", java.lang.String.class)
.invoke(mPowerProfile_, "battery.capacity");
return batteryCapacity;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
来源:https://stackoverflow.com/questions/28043112/get-the-exact-battery-level-on-android