Get battery level and state in Android

161,048

Solution 1

Here is a code sample that explains how to get battery information.

To sum it up, a broadcast receiver for the ACTION_BATTERY_CHANGED intent is set up dynamically, because it can not be received through components declared in manifests, only by explicitly registering for it with Context.registerReceiver().

public class Main extends Activity {
  private TextView batteryTxt;
  private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
    @Override
    public void onReceive(Context ctxt, Intent intent) {
      int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
      int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
      float batteryPct = level * 100 / (float)scale;
      batteryTxt.setText(String.valueOf(batteryPct) + "%");
    }
  };

  @Override
  public void onCreate(Bundle b) {
    super.onCreate(b);
    setContentView(R.layout.main);
    batteryTxt = (TextView) this.findViewById(R.id.batteryTxt);
    this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
  }
}

Solution 2

Since SDK 21 LOLLIPOP it is possible to use the following to get current battery level as a percentage:

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

Read BatteryManager  |  Android Developers - BATTERY_PROPERTY_CAPACITY

Solution 3

Based on official android docs, you can use this method in a Helper or Util class to get current battery percentage:

Java version:

public static int getBatteryPercentage(Context context) {

    if (Build.VERSION.SDK_INT >= 21) {

         BatteryManager bm = (BatteryManager) context.getSystemService(BATTERY_SERVICE);
         return bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);

    } else {

         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;

         double batteryPct = level / (double) scale;

         return (int) (batteryPct * 100);
   }
}

Kotlin version:

fun getBatteryPercentage(context: Context): Int {
    return if (Build.VERSION.SDK_INT >= 21) {
        val bm = context.getSystemService(BATTERY_SERVICE) as BatteryManager
        bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
    
    } else {
        val iFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
        val batteryStatus: Intent = context.registerReceiver(null, iFilter)
        val level = batteryStatus?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
        val scale = batteryStatus?.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
        val batteryPct = level / scale.toDouble()
        (batteryPct * 100).toInt()
    }
}

Solution 4

You don't have to register an actual BroadcastReceiver as Android's BatteryManager is using a sticky Intent:

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

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

float batteryPct = level / (float)scale;

return (int)(batteryPct*100);

This is from the official docs over at https://developer.android.com/training/monitoring-device-state/battery-monitoring.html.

Solution 5

Other answers didn't mention how to access battery status (chraging or not).

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

// Are we charging / charged?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                     status == BatteryManager.BATTERY_STATUS_FULL;

// How are we charging?
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
Share:
161,048
Mohit Deshpande
Author by

Mohit Deshpande

I am a researcher at The Ohio State University in the field of computer vision and machine learning. I have worked as a mobile apps instructor for Zenva and current work as a writer for Zenva in machine learning.

Updated on July 30, 2022

Comments

  • Mohit Deshpande
    Mohit Deshpande almost 2 years

    How can I get battery level and state (plugged in, discharging, charging, etc)? I researched the developer docs and I found a BatteryManager class. But it doesn't contain any methods, just constants. How do I even use it?

    • Mohit Deshpande
      Mohit Deshpande almost 14 years
      After some MORE researching, I found BatteryManager.EXTRA_LEVEL.
  • class Android
    class Android almost 9 years
    About Intent.ACTION_BATTERY_CHANGED: This is a sticky broadcast containing the charging state, level, and other information about the battery. You can not receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver().
  • SirDarius
    SirDarius almost 9 years
    @classAndroid well, yes, that's explicitely stated in the answer.
  • class Android
    class Android almost 9 years
    Yes @SirDarius, just letting others know about it. I upvoted your answer first and put this comment when I found it out. :)
  • Dave Doga Oz
    Dave Doga Oz almost 9 years
    don't forget to unRegisterReceiver onPause or onDestroy.
  • user2212515
    user2212515 over 5 years
    one mistake in official docs, you must use double instead float int level = batteryStatus != null ? batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) : -1; int scale = batteryStatus != null ? batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1) : -1; double batteryPct = (double) level / (double) scale; int percent = (int) (batteryPct * 100D);
  • blueware
    blueware over 5 years
    @user2212515, would you mind edit my answer based on the official docs?
  • Robyer
    Robyer over 5 years
    Isn't that 0.53F -> 52F mistake caused by casting final value to int (thus stripping any decimal 0.x value from it), instead of using Math.round()?
  • Pemba Tamang
    Pemba Tamang over 4 years
    hey I used this and sometimes the result is is 89 sometimes its 00.89 its moving the decimals whats happening
  • blueware
    blueware over 4 years
    @Ryan, I edited my answer to support android v21 and later. Please check it out.
  • subhashchandru
    subhashchandru over 4 years
    Cannot able to instaialise battery manager with new Keywork , Why sir ?
  • Robin Hsu
    Robin Hsu about 3 years
    EXTRA_LEVEL is not exact. You need to scale it. See this link for detail.
  • user924
    user924 about 3 years
    there is no state, only level, why it was accept if it's not a full answer?
  • user924
    user924 about 3 years
    Finally, someone who answered about battery status
  • SirDarius
    SirDarius about 3 years
    @user924 if you think you can improve this answer, please feel free to do so. If the Original Poster accepted this answer, I believe they were satisfied with the contents.
  • user924
    user924 about 3 years
    from author question Get battery level and *state* in Android. Is there any code to get state in your code? no :) Check here stackoverflow.com/a/59025376/7767664
  • Sambhav Khandelwal
    Sambhav Khandelwal almost 2 years
    Dont we need any permissions for it?