Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with ACTION_POWER_CONNECTED

Tags:

android

I'm using the code from the below example page in my app to monitor when the device is connected / disconnected to a power adapter:

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

So I have in my manifest:

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

And my class looks like this:

public class StatusChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    boolean isActive = prefs.getBoolean("isActive", false);
    if (isActive){
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
        // Do somthing with isCharging here
    }

}

But isCharging is always false, regardless of whether the power was connected or disconnected. I'm obviously having problems debugging this as I have to keep (dis)connecting the USB cable to get the event to fire.

I presume when the power is connected the event is fired and the status isn't updated before my code runs, but I'm not sure of the best way to resolve it. Any ideas?

like image 865
user1341608 Avatar asked Apr 18 '12 14:04

user1341608


1 Answers

As suggested by @gnichola, referencing this post is the correct answer:

public class PowerReceiver extends BroadcastReceiver {

    @Override public void onReceive(Context context, Intent intent) {
        if(intent.getAction() == Intent.ACTION_POWER_CONNECTED) {
            //Handle power connected
        } else if(intent.getAction() == Intent.ACTION_POWER_DISCONNECTED){
            //Handle power disconnected
        }
    }
}

Below is an alternate (albeit incorrect) approach:

I had the same problem as noted by others. My solution is to call the ACTION_BATTERY_CHANGED blocking intent within the ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED Broadcast Receivers:

In onCreate() or some other appropriate initializer:

// register our power status receivers
IntentFilter powerConnectedFilter = new IntentFilter(Intent.ACTION_POWER_CONNECTED);
registerReceiver(PowerStatusReceiver, powerConnectedFilter);

IntentFilter powerDisconnectedFilter = new IntentFilter(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(PowerStatusReceiver, powerDisconnectedFilter);

Define our BroadcastReceiver and embed the BATTERY_STATUS request within it:

BroadcastReceiver PowerStatusReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        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);
        isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                     status == BatteryManager.BATTERY_STATUS_FULL;
    }
};  

Additionally, using this approach you do not have to define a receiver in your manifest... however that is ultimately entirely up to you depending on the needs of your use case.

like image 177
ShellDude Avatar answered Nov 06 '22 20:11

ShellDude