Check if device is plugged in
Asked Answered
C

9

64

My app has a broadcast receiver to listen for changes to ACTION_POWER_CONNECTED, and in turn flag the screen to stay on.

What I am missing is the ability for the app to check the charging status when it first runs. Can anyone please help me with code to manually check charging status?

Convulsant answered 12/3, 2011 at 15:40 Comment(0)
F
163

Thanks to CommonsWare here is the code I wrote.

public class Power {
    public static boolean isConnected(Context context) {
        Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
    }
}

if (Power.isConnected(context)) {
    ...
}

or the Kotlin version

object Power {
    fun isConnected(context: Context): Boolean {
        val intent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
        val plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
        return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS
    }
}

http://developer.android.com/training/monitoring-device-state/battery-monitoring.html

Fretwell answered 23/8, 2011 at 4:24 Comment(6)
and don't forget to unregister the receiverMarcellamarcelle
@JeffreyBlattman that's not necessary because you're not really registering a receiver in the first placeSmiga
um, you are calling Context.registerReceiver(), how is that not registering the receiver?Marcellamarcelle
you don't need backward compatibility, because BATTERY_PLUGGED_WIRELESS is just a constant.Backgammon
IF there is no battery for the device how we will know the Device is plugged in or Not?Kellyekellyn
I wonder why this is still recommended by the Android docs, since it discourages to use sticky broadcasts at all for a long time now.Terramycin
H
33
public static boolean isPlugged(Context context) {
    boolean isPlugged= false;
    Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
    isPlugged = plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB;
    if (VERSION.SDK_INT > VERSION_CODES.JELLY_BEAN) {
        isPlugged = isPlugged || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
    }
    return isPlugged;
}

A minor update to support Wireless charging.

Hiragana answered 27/10, 2014 at 9:57 Comment(0)
M
29

Call registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)). This will return an Intent that has extras defined on BatteryManager to let you know if it is plugged in or not.

This works because Intent.ACTION_BATTERY_CHANGED is a sticky broadcast.

Molton answered 12/3, 2011 at 15:45 Comment(8)
So there's no way to query right at that moment? You have to keep the state of the battery somewhere in your app and then change it when you receive these broadcasts?Accumulative
@MattC: "So there's no way to query right at that moment?" -- yes. In fact, that is precisely what my answer tells you how to accomplish.Molton
I was thinking more like getting a manager of some sort and saying isPluggedIn(). Registering a broadcast receiver and then unregistering it after I get the info seems messy.Accumulative
@MattC: You are not reading my answer. Keep re-reading it until you notice that I am not telling you to register a BroadcastReceiver. I am telling you to call registerReceiver(), but with null as the first parameter. Now, it would be nice if this data were simply available on BatteryManager, but you definitely do not have to register a BroadcastReceiver, as my answer states.Molton
ah, you're right. Still seems less-than-intuitive from a design perspective. Note that I'm not calling you out, but rather whatever design decisions led to this being the only way to get this information.Accumulative
@MattC: "Still seems less-than-intuitive from a design perspective." -- no arguments there. I get chuckles from my students every time I teach this point. Methods on BatteryManager would seem to be a more logical approach. But, life goes on.Molton
@commonsware: agreed it's not intuitive. The probable point, however, is that if you want the battery state, you really should be registering a listener as well. Battery states do change.Revamp
@RobinDavies: However, using a listener is not always an appropriate way to handle that change. An app widget for battery level, for example, should be polling at a user-specified interval, to avoid needing to keep a process in memory all the time just to have a listener registered. It would be nice if there were a cleaner API for this out of the box, rather than having to roll our own register-a-listener-but-not-really code to get the current battery state.Molton
T
14

On Android M+ you can use the BatteryManager service via getSystemService(BATTERY_SERVICE). On devices running pre-M you can use a sticky broadcast as mentioned by others. Example:

public static boolean isCharging(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        BatteryManager batteryManager = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
        return batteryManager.isCharging();
    } else {
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent intent = context.registerReceiver(null, filter);
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        if (status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL) {
            return true;
        }
    }
    return false;
}
Triumphant answered 4/1, 2018 at 8:14 Comment(1)
I don't get it why when battery status full considered isCharging? What happens when it is full 100% then you unplugged it wouldn't it be wrong by still stating it is charging?Brigid
N
6

Your answer is in the android reference !

Here is the example code:

// 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;
Numberless answered 1/7, 2014 at 7:31 Comment(0)
S
5

Easy way is to use an intent filter ACTION_BATTERY_CHANGED

public void checkBatteryState(View sender) {
    IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    Intent batteryStatus = registerReceiver(null, filter);

    int chargeState = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
    String strState;

    switch (chargeState) {
        case BatteryManager.BATTERY_STATUS_CHARGING:
        case BatteryManager.BATTERY_STATUS_FULL:
            strState = "charging";
            break;
        default:
            strState = "not charging";
    }

    TextView tv = (TextView) findViewById(R.id.textView);
    tv.setText(strState);
}
Secession answered 6/6, 2015 at 19:3 Comment(1)
Unresolved reference: registerReceiver in kotlin or java what can i doMatriarchate
I
3

try this:

public class PowerConnectionReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

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


        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging =    status == BatteryManager.BATTERY_STATUS_CHARGING ||
                                status == BatteryManager.BATTERY_STATUS_FULL;

        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        boolean usbCharge   = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
        boolean acCharge    = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;


        if (batteryStatus != null) {
            int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
            float batteryPct = level / (float) scale;
        }


    }//end onReceive


}//end PowerConnectionReceiver
Intuitivism answered 24/5, 2016 at 6:42 Comment(0)
S
2
BroadcastReceiver receiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        String action = intent.getAction();
        if(action.equalsIgnoreCase(ACTION_POWER_CONNECTED))
        {


                if(chargerConnected != null )
                {
                    chargerConnected.setText("Cable Connected");
                }
                if(chargerImage != null )
                {
                    chargerImage.setImageDrawable(getResources().getDrawable(R.drawable.usb));
                }

        }else if(action.equalsIgnoreCase(ACTION_POWER_DISCONNECTED))
        {


                if(chargerConnected != null )
                {
                    chargerConnected.setText("NOT CHARGE");
                }
                if(chargerImage != null )
                {
                    chargerImage.setImageDrawable(getResources().getDrawable(R.drawable.battery_icon));
                }

            try {

                Toast.makeText(context, "Power Cable Disconnected", Toast.LENGTH_SHORT).show();
            }catch (Exception e){e.printStackTrace();}

        }
    }
};
Scornful answered 2/9, 2016 at 5:26 Comment(0)
F
1

It's a sticky intent, you don't need to register a BroadcastReceiver—by simply calling registerReceiver passing in null as the receiver as shown in the next snippet, the current battery status intent is returned. You could pass in an actual BroadcastReceiver object here, but we'll be handling updates in a later section so it's not necessary.

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

You can extract both the current charging status and, if the device is being charged, whether it's charging via USB or AC charger:

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

The BatteryManager broadcasts an action whenever the device is connected or disconnected from power. It's important to receive these events even while your app isn't running—particularly as these events should impact how often you start your app in order to initiate a background update—so you should register a BroadcastReceiver in your manifest to listen for both events by defining the ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED within an intent filter.

<receiver android:name=".PowerConnectionReceiver">
  <intent-filter>
    <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
  </intent-filter>
</receiver>

Within the associated BroadcastReceiver implementation, you can extract the current charging state and method as described in the previous step.

public class PowerConnectionReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                            status == BatteryManager.BATTERY_STATUS_FULL;

        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
        boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
    }
}
Fillbert answered 27/2, 2017 at 22:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.