3

In my application I want to check if the phone is charged by socket or usb. For this I created a BroadcastReceiver with the following code:

Manifest:

<receiver
    android:name=".ChargingReceiver"
    android:enabled="true" android:exported="false">

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

ChargingReceiver

public void onReceive(Context context, Intent intent) {
    int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);

    boolean acCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_AC);
    boolean usbCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_USB);

    //...
}

My problem is, that the first line of the ChargingReceiver always return -1 which is the default value I have set. The BroadcastReceiver is called correctly when I plug or unplug my phone, so it looks to me that the intent does not contain the Extra I try to look up. I have the code from here so it should work.

I also found this answer but it does not help me, because I have to distinguish between USB Charging and socket charging. Any ideas what I have done wrong? BTW I have tested the code with Android Nougat. I think on Lollipop it has worked, but I'm not completely sure...

Community
  • 1
  • 1
Cilenco
  • 6,951
  • 17
  • 72
  • 152

3 Answers3

1

You registered ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED in your manifest. But these Broadcasts don't include information about the charging state.

In order to receive information about the charging state you need to register the ACTION_BATTERY_CHANGED broadcast. From the developer docs:

The BatteryManager broadcasts all battery and charging details in a sticky Intent that includes the charging status.

So you can try the following code snippet in onReceive:

Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean pluggedAC = (plugged == BatteryManager.BATTERY_PLUGGED_AC);
boolean pluggedUSB = (plugged == BatteryManager.BATTERY_PLUGGED_USB);

You can read more about this here

IIIIIIIIIIIIIIIIIIIIII
  • 3,958
  • 5
  • 45
  • 70
  • Wow this works thank you for this! I think it is not the best solution because I react with a `Broadcast`to a `Broadcast` but since I can't register this `Intent` through the manifest it is the only solution so far I can use or do you have any ideas to beautify this? Or am I a bit to petty with this? – Cilenco Nov 24 '16 at 08:31
  • I think doing this in your Broadcast receiver would be a good solution since you only want to receive the battery status information in case the power connection state changed – IIIIIIIIIIIIIIIIIIIIII Nov 24 '16 at 09:27
1

@MarkB approach is correct, it's the same one suggested in the developer docs. I would like to point out that you don't need to register any BroadcastReceiver because that's a Sticky Intent.

Basically all you need to do is to call registerReceiver passing in null as the receiver and of course the action (Intent.ACTION_BATTERY_CHANGED):

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

And then you can do it like this:

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

(These snippets are not mine, but from docs)

Notice that there's nothing wrong doing this as also the docs suggests it.

Now, getting back to your code you are actually listeting for ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED, which are used to monitor changes in charging state and could be useful to handle the amount of battery you can use.

Community
  • 1
  • 1
Sid
  • 14,176
  • 7
  • 40
  • 48
0

try this

        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;

As suggest by @MarkB you must explicitly register ACTION_BATTERY_CHANGED from your Java code refer

Community
  • 1
  • 1
Nas
  • 2,158
  • 1
  • 21
  • 38