3

I know there are many questions like this, but I need a concrete answer whether it is possible or not.

I want to get the current available battery power in mAh for any android phone. It is crucial for my project. I tried BatteryManager.

batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER);

It exactly provides the information I need, but only for some devices.

I also tried using PowerProfile via Java Reflection.

public void 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");
        Toast.makeText(OffloadeeActivity.this, batteryCapacity + " mAh",
                Toast.LENGTH_LONG).show();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

But it provides the total battery capacity. What I need is the current remaining battery power. Is there any universal way to get that for every device? Any library would also do.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
OwnageByte
  • 94
  • 1
  • 7
  • Read official document https://developer.android.com/training/monitoring-device-state/battery-monitoring#MonitorLevel – Akash Patel Jan 04 '19 at 12:09
  • @AkashPatel I did, and it is working. But not for all devices, in most of the devices it returns 0. – OwnageByte Jan 04 '19 at 13:14
  • [BatteryManager#BATTERY_PROPERTY_CAPACITY](https://developer.android.com/reference/android/os/BatteryManager#BATTERY_PROPERTY_CAPACITY) – ecle Jan 04 '19 at 14:00
  • 5
    Does this answer your question? [Get battery level and state in Android](https://stackoverflow.com/questions/3291655/get-battery-level-and-state-in-android) – Andreas is moving to Codidact Jul 24 '20 at 17:46

2 Answers2

4

This can be achieved by getting the total battery capacity in milliamp hours, then finding the percentage of the battery level, and finally multiplying them together to get the current battery life in milliamp hours. The following block of code is a function for getting the total capacity of the battery in milliamp hours:

public double getBatteryCapacity(Context context) {
    Object mPowerProfile;
    double batteryCapacity = 0;
    final String POWER_PROFILE_CLASS = "com.android.internal.os.PowerProfile";

    try {
        mPowerProfile = Class.forName(POWER_PROFILE_CLASS)
            .getConstructor(Context.class)
            .newInstance(context);

    batteryCapacity = (double) Class
            .forName(POWER_PROFILE_CLASS)
            .getMethod("getBatteryCapacity")
            .invoke(mPowerProfile);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return batteryCapacity;
}

Now that you have the battery capacity, you can find the current percentage of battery life and then multiply it by the total capacity to get the charge in milliamp hours:

BatteryManager bm = (BatteryManager)getSystemService(BATTERY_SERVICE);
int batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);

If you want to get back the battery percentage level as a float, (Example 89.92%), you can use the following code:

IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);

int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

float batLevel = (float) level / (float) scale;

Now, you can do the following to get the milliamp hour battery life:

int batteryInMilliamps = getBatteryCapacity(getApplicationContext()) * batLevel;

If you receive any issues or have any questions, just comment below.

Ishaan Javali
  • 1,711
  • 3
  • 13
  • 23
  • Your method is correct. But I need the battery level more precisely, as I want to calculate the battery level before and after some particular tasks. Since BATTERY_PROPERTY_CAPACITY returns the battery percentage as an integer (no fractional part), it would be very hard to tell the difference. Some tasks just take about 20-50 mAh. – OwnageByte Jan 04 '19 at 15:21
  • So what you want is for the battery percentage level to be returned as a double? Like 89.982%? The battery capacity in milliamp hours is already being returned as a double. Is it the percentage level that you want as a double as well? – Ishaan Javali Jan 04 '19 at 16:41
  • @OwnageByte I updated my answer to get the battery percentage as a float, that way when you multiply it by the milliamp hours, it gives a more accurate result. – Ishaan Javali Jan 04 '19 at 16:47
  • What you are doing here is converting the division here into float. `level / (float) scale;` But the battery level is still an int, coming from android. `int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);` Suppose my battery percentage is 94 percent and with your calculation the `int batteryInMilliamps` will be x. After I perform a very little task on the device, the battery percentage won't drastically drop. So when I get the battery percentage again after the task, it is still 94. So again with your calculation the battery power will same as x. So x-x=0. Getting me? – OwnageByte Jan 05 '19 at 06:36
  • Yeah I understand. That's why I added the third block of code, to get the battery level as a float. Did it not work? – Ishaan Javali Jan 05 '19 at 13:38
  • Nope. Even if convert the `level / scale` into float, the `level` is always an int. I need a more precise calculation. – OwnageByte Jan 07 '19 at 12:31
1

You try this it will help for you

public static int getBatteryPercentage(Context context) {

    IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    Intent batteryStatus = context.registerReceiver(null, iFilter);

    int level = batteryStatus != null ? batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) : -1;
    int scale = batteryStatus != null ? batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1) : -1;

    float batteryPct = level / (float) scale;

    return (int) (batteryPct * 100);
}
Arjun Othayoth
  • 351
  • 3
  • 5
  • That returns the battery percentage. What I want is the remaining battery capacity in mAh. – OwnageByte Jan 04 '19 at 11:52
  • @ZiedRebhi That return the full battery capacity. I need the current remaining battery power in mAh. – OwnageByte Jan 04 '19 at 13:15
  • @OwnageByte I updated my answer to get the battery percentage as a float, that way when you multiply it by the milliamp hours, it gives a more accurate result. – Ishaan Javali Jan 04 '19 at 16:46