在 android 上获取准确的电池电量

Get the exact battery level on android

所以我目前在我的 android 应用程序中实现了以下常用的获取当前电池电量的方法。

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;
}

问题是这个 return 是一个 0-100 的整数。为了确保我的一种算法的准确性,我需要能够更精确地测量电池电量。我见过一些电池管理应用程序显示可以完美工作的 mV。如果有人知道如何获得此值,将不胜感激。

澄清一下:我需要当前电池电量,而不是电池的总容量。

谢谢!

------------------------更新-------------------- ------

我现在使用以下代码:

    // 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;
}

但是 getBatteryCapacity 方法给我一个 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

我在 Android 4.4.4 上有一个 Droid Ultra 运行ning 并且此代码不起作用,它 returns 0.0,但是当 运行 在具有多个 android 版本的模拟器实际上可以工作。我很想知道在 Droid Ultra 上测试的其他用户是否有同样的问题。上面的代码应该适用于大多数设备。

这实际上不是准确的电池电量。如果电池百分比为 97% 且总容量为 1000,则使用此算法,准确的电池电量将为 970。现在,如果实际电池百分比为 96.7%,我的 getBatteryPercent 将为 return 97。这将导致相同的确切答案。所以这个算法不是这个问题的答案。我还在寻找这个问题的答案!!!我需要比 +-1% 更精确的电池电量测量...

------------------------更新-------------------- ------

我发现,如果您在侦听 ACTION_BATTERY_CHANGED 的广播接收器中使用 getIntExtra("voltage", -1)。它给你mV。我想知道这个值是否足够可靠以用于电池寿命预测。有谁知道我可以在任何时间点获取电压而不依赖广播接收器的最新更新的方法吗?

编辑:事实证明它不可行。 this graph 表明电池电压是电池容量的一个非常差的指标。

根据@user87049 的 link 获取电池容量并使用您自己的函数获取当前电池百分比并将这两者结合起来以获得当前容量。

int batteryPercentage = getBatteryPercentage() //Your function
double batteryCapacity = getBatteryCapacity() //code from link from user87049. Change it to return value
double currentCapacity = (batteryPercentage * batteryCapacity) / 100

根据this answer,您可以通过以下方式获取Batter mAH值:

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;
}

这个功能可以帮到你。

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;
}