Получите точный уровень заряда батареи на 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;
}

Проблема в том, что это возвращает целое число от 0 до 100. Чтобы обеспечить точность одного из моих алгоритмов, мне нужно получить более точное измерение уровня заряда батареи. Я видел, как некоторые приложения для управления батареями показывают милливольтовое напряжение, которое отлично работает. Если кто-то знает, как получить это значение, любая помощь будет принята с благодарностью.

Чтобы уточнить: мне нужен ТЕКУЩИЙ уровень заряда батареи, а не общая емкость батареи.

Спасибо!

------------------------ОБНОВИТЬ------------------------- -

Сейчас я использую следующий код:

    // 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:

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

У меня Droid Ultra работает на Android 4.4.4, и этот код не работает, он возвращает 0.0, однако при запуске на эмуляторе с несколькими версиями Android он действительно работает. Мне любопытно узнать, есть ли у других пользователей, тестирующих Droid Ultra, такую ​​же проблему. Приведенный выше код должен работать на большинстве устройств.

На самом деле это НЕ точный уровень заряда батареи. Используя этот алгоритм, если процент заряда батареи был 97%, а общая емкость была 1000, точный уровень заряда батареи был бы 970. Теперь, если ФАКТИЧЕСКИЙ процент заряда батареи составляет 96,7%, мой getBatteryPercent вернет 97. Это приведет к ТАКОМУ ТОЧНОМУ ОТВЕТУ . Итак, этот алгоритм НЕ является ответом на этот вопрос. Я все еще ищу ответ на этот вопрос !!! Мне нужно измерить уровень заряда батареи, который будет более точным, чем + -1% ...

------------------------ОБНОВИТЬ------------------------- -

Я обнаружил, что если вы используете getIntExtra ("Voltage", -1) в широковещательном приемнике, прослушивающем ACTION_BATTERY_CHANGED. Это дает вам мВ. Интересно, достаточно ли это значение, чтобы использовать его для прогнозов времени автономной работы. Кто-нибудь знает, как я могу получить напряжение в любой момент времени, не полагаясь на самое последнее обновление с моего широковещательного приемника?

РЕДАКТИРОВАТЬ: Оказывается, это нежизнеспособно. этот график показывает, что напряжение аккумулятора является очень плохим индикатором емкости аккумулятора.


person JayB    schedule 20.01.2015    source источник
comment
Вероятно, дубликат stackoverflow.com/questions/23193388/   -  person Price    schedule 20.01.2015
comment
@ user87049 Я уже читал этот вопрос / ответ. Нигде четко не указано, предназначен ли код в ответе для получения общей емкости аккумулятора или текущего уровня заряда аккумулятора. Мне нужен текущий уровень   -  person JayB    schedule 20.01.2015
comment
Какое приложение это делает? Вы можете использовать dex2jar и jd-gui и выполнить поиск по ключевым словам, чтобы увидеть, помогает ли это понять, как они получают ценность.   -  person Jared Rummler    schedule 20.01.2015
comment
@JaredRummler Некоторое приложение для калибровки батареи. Не помню, но точно помню, что видел значение мАч   -  person JayB    schedule 20.01.2015
comment
@JaredRummler Ага. Приложение называется Battery Calibration в магазине приложений. Он дает показание текущего мВ   -  person JayB    schedule 20.01.2015


Ответы (3)


Получите емкость батареи по ссылке @ user87049 и используйте свою собственную функцию, чтобы получить текущий процент заряда батареи, и объедините эти два, чтобы получить текущую емкость.

int batteryPercentage = getBatteryPercentage() //Your function
double batteryCapacity = getBatteryCapacity() //code from link from user87049. Change it to return value
double currentCapacity = (batteryPercentage * batteryCapacity) / 100
person 0xDEADC0DE    schedule 20.01.2015
comment
Я не уверен. Если вы объедините это в одну функцию, зачем вам нужен более простой способ? - person 0xDEADC0DE; 20.01.2015
comment
Кажется, не работает. Код по ссылке дает мне возврат 0,0. Я опубликовал обновление своего вопроса с моим кодом - person JayB; 20.01.2015
comment
Не могли бы вы отладить функцию getBatteryCapacity()? Я думаю, что вы вводите одну из оговорок - person 0xDEADC0DE; 20.01.2015
comment
Я понимаю, но ваш battCapacity инициализируется 0,0 и устанавливается только в try. Вы уверены, что не попадете в ловушку этой попытки? Тем временем я также отлаживал ваш код и получил следующий результат: 01-20 12:36:16.961 23239-23239/hooff.nl.dummydroid D/Debug﹕ In getExactBattery() 01-20 12:36:36.754 23239-23239/hooff.nl.dummydroid D/Debug﹕ batteryPercentage = 100.0 01-20 12:37:21.368 23239-23239/hooff.nl.dummydroid D/Debug﹕ totalCapacity = 3260.0 01-20 12:38:09.294 23239-23239/hooff.nl.dummydroid D/Debug﹕ currLevel = 3260.0 Протестировано на Nexus7 2012 с Android 5.0.2 - person 0xDEADC0DE; 20.01.2015
comment
Слишком странно. Я добавил Log.d внутри попытки, он печатает и говорит, что после назначения battCapacity все еще равен 0,0. Запуск Droid Ultra на 4.4.4. Смотрите обновления сами - person JayB; 20.01.2015
comment
Позвольте нам продолжить это обсуждение в чате. - person 0xDEADC0DE; 20.01.2015
comment
Я обнаружил, что если вы используете getIntExtra (Voltage, -1) в широковещательном приемнике, прослушивающем ACTION_BATTERY_CHANGE. Это дает вам мВ. Интересно, надежно ли это значение для прогнозов времени автономной работы. Знаете ли вы, как я могу получить напряжение в любой момент времени, не полагаясь на самые последние обновления с моего радиоприемника? - person JayB; 20.01.2015
comment
хм ... Не могу найти где-нибудь в документации. Возможно, вы могли неправильно использовать поведение IntentFilter. Я думаю, что он срабатывает один раз сразу после регистрации, поэтому, если вы снова вызовете getBatteryPercentage(), вы получите это значение - person 0xDEADC0DE; 20.01.2015
comment
Ничего. согласно этому графику, напряжение не соответствует емкости аккумулятора, поэтому я могу не использую это. - person JayB; 20.01.2015

Эта функция вам поможет.

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;
}
person Abhishek    schedule 05.01.2016
comment
Совершенно не помогает, это возвращает значение от 0 до 100, ему нужно больше детализации. - person SMKS; 24.03.2017

Согласно этому ответу, вы можете получить значение мАч Batter следующим образом:

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;
}
person Muhammed Refaat    schedule 20.01.2015
comment
Проверьте обновление моего вопроса, этот код дает мне 0,0 - person JayB; 20.01.2015
comment
проверьте, улавливает ли он какие-либо исключения, посмотрите журнал, чтобы узнать, что-то пошло не так - person Muhammed Refaat; 20.01.2015