Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obtaining usb cable plugged IN/OUT event using EXTRA_PLUGGED does not work

My intention is to have saved in Preferences current status of Android device usb/power cable: connected/disconnected. From Developer site I see that there are two Intent for obtaining that status: ACTION_POWER_CONNECTED / DISCONNECTED. So I used same code as published at Developers:

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

in section Monitor Changes in Charging State.

Manifest

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

Java code

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

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

        Toast.makeText(context, "pvr = " + usbCharge + ", " + acCharge + "," + isCharging, Toast.LENGTH_SHORT).show();
    }
}

When I am plugging USB cable IN/OUT than broadcast is always correctly sent and caught in PowerConnectionReceiver but always with same result (=cable is plugged out).

I tested it with Galaxy Nexus 4.1.1 / 4.2.1 - I am always getting 2xFALSE in Toast (chargePlug = FALSE, usbCharge = FALSE).

Why intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) always return default value "-1" ?

Thank you.

ps. everything works fine if I register receiver in Java

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

...in Service or in Activity. But according to Android Developers site it is not prerequisity to make code above to return correct value;

like image 795
user1128166 Avatar asked Jan 08 '13 15:01

user1128166


1 Answers

I was dealing with the same problem, coming across your post. I think the issue is that the code, in the Android training page to which you provided a link, is wrong.

ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED aren't "carrying" the data that you're querying from the intent in your code. I couldn't get that same stuff to work on my devices either (1st gen Nexus 7 running Android 4.3 and Nexus One running Android 2.3.6) and, because it seems to not be working anywhere, I come to the "bad code" conclusion.

I fixed it with the following code. It's actually very close to what you've provided as a fix except that it's going into my BroadcastReceiver directly and not into an activity. In your code above, the snippet here would go just before the line beginning "int chargePlug". After that, change "intent" in that same line (your line), beginning "int chargePlug", to "mIntent".

final Intent mIntent = context.getApplicationContext().registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));

Be aware that your BroadcastReceiver will now have two intents. One passed to it, which will be the intent containing the action ACTION_POWER_CONNECTED (or ACTION_POWER_DISCONNECTED), and the other created within the BroadcastReceiver expressly to extract battery information.

The code snippet that I've supplied would not work if you placed it into an activity (it wouldn't connect to your BroadcastReceiver) because of the null in the parameter list. You're not actually registering a BroadcastReceiver with that null. Changing the null to your BroadcastReceiver wouldn't be ideal either since the ACTION_BATTERY_CHANGED notification can trigger A LOT. I'm quite confident that ACTION_BATTERY_CHANGED wasn't intended to be used as a trigger for a BroadcastReceiver. Instead, I think it's meant to be used in real time to get the last "sticky" broadcast with information about a change in battery info (look up "sticky broadcast" in the Android documentation).

Note also that the snippet I've given includes "getApplicationContext()" in the call chain. Take it out and Gingerbread devices will crash (thanks CommonsWare).

like image 106
UpLate Avatar answered Sep 20 '22 12:09

UpLate