13

I am having the exact same problem as this post: Battery broadcast receiver doesn't work. But it seems no one has answered that question.

Here is my BroadcastReceiver:

public class BatteryLevelReceiver extends BroadcastReceiver{


    @Override
    public void onReceive(Context context, Intent intent) {
    Log.v("plugg", "plug change fired");
    Toast.makeText(context, " plug change fired", Toast.LENGTH_LONG).show();
        }

And here is my AndroidManifest.xml:

<receiver android:name=".ReceversAndServices.BatteryLevelReceiver">
               <intent-filter android:priority="900">
               <action android:name="android.intent.action.BATTERY_LOW" />

               </intent-filter>
           </receiver>

           <receiver android:name=".ReceversAndServices.BatteryLevelReceiver">
               <intent-filter android:priority="900">
               <action android:name="android.intent.action.BATTERY_CHANGED" />
               </intent-filter>
           </receiver>

I have also added this line to the manifest:

<uses-permission android:name="android.permission.BATTERY_STATS"/>

But still no success!

I would really appreciate if someone could advise me what I am doing wrong.

Community
  • 1
  • 1
Zardaloop
  • 1,594
  • 5
  • 22
  • 43

3 Answers3

23

From the documentation for ACTION_BATTERY_CHANGED:

You can not receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver(). See ACTION_BATTERY_LOW, ACTION_BATTERY_OKAY, ACTION_POWER_CONNECTED, and ACTION_POWER_DISCONNECTED for distinct battery-related broadcasts that are sent and can be received through manifest receivers.

There you have it: you must explicitly register for it from your Java code.

Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109
  • thanks Darshan, but I want to run a service only when the battery is low or it is plugged in. Could you please tell me how should I do that? – Zardaloop Jun 30 '12 at 21:21
  • 2
    If those are the only two events you care about, then you don't need `ACTION_BATTERY_CHANGED` at all, and you'll be fine registering for them in the manifest. The broadcast for being plugged in is `ACTION_POWER_CONNECTED`. Both actions can be under the same `intent-filter`, you don't need to set a priority, and you don't need the `BATTERY_STATS` permission. – Darshan Rivka Whittle Jun 30 '12 at 21:45
2

I just followed the Android Developer Guide's on Monitoring the Battery Level and Charging State and had immediate success. If BatteryLevelReceiver is it's own class then I would recommend:

<receiver android:name=".BatteryLevelReceiver">
    <intent-filter android:priority="900">
       <action android:name="android.intent.action.BATTERY_LOW" />
       <action android:name="android.intent.action.BATTERY_CHANGED" />
    </intent-filter>
</receiver>

Addition

I'm willing to guess that you wrote BatteryLevelReceiver as a nested class in ReceversAndServices. According to Receiver as inner class in Android, you cannot do that with non-static classes. You could make BatteryLevelReceiver a static class and register the receiver in onResume(), but then your app will need to be running to catch the events... Move your receiver to a separate class and register these Intents:

<receiver android:name=".BatteryLevelReceiver">
    <intent-filter android:priority="900">
       <action android:name="android.intent.action.BATTERY_LOW" />
       <action android:name="android.intent.action.BATTERY_OKAY" />
       <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
       <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
    </intent-filter>
</receiver>

(Not BATTERY_CHANGED as Darshan Computing pointed out.)

Community
  • 1
  • 1
Sam
  • 86,580
  • 20
  • 181
  • 179
  • 4
    You had immediate success receiving `BATTERY_LOW`, but you'll never receive `BATTERY_CHANGED` that way. – Darshan Rivka Whittle Jun 30 '12 at 20:44
  • Thanks Sam, but as soon as I add static to it, I get error :( – Zardaloop Jun 30 '12 at 21:20
  • @Kevin_Dingo Yes, I took a guess at what you were trying to do. I realized my mistake and was writing an update. If you are still getting errors, please add more detail to your question and the logcat errors. – Sam Jun 30 '12 at 21:24
  • @Sam although this receiver will be fired automatically, is it registering that broadcast receiver automatically? If so, do we need to unregistered it? I am supposing, if we need to monitor the battery level we should not unregistered, so is there any downside if we don't unregistered? – OnePunchMan Sep 19 '14 at 05:15
  • @DarshanRivkaWhittle what is the best way to get my app to be started by android when the battery is fully charged? – user3760100 Jan 28 '17 at 15:13
  • @user3760100 There's no broadcast specifically for a fully charged battery, so you'll have to register for `ACTION_BATTERY_CHANGED` and decide yourself in that receiver if the battery is fully charged. (Note that there's often a difference between the status `BatteryManager.BATTERY_STATUS_FULL` and being at 100% charge.) – Darshan Rivka Whittle Jan 28 '17 at 21:30
0

Make sure you have the battery receiver class not as a subclass of another one but as a seperate class in your project.

Also try using Context.registerReceiver() method explicitly in your code and do not forget to unregister it: http://developer.android.com/reference/android/content/Context.html#registerReceiver%28android.content.BroadcastReceiver,%20android.content.IntentFilter%29

Erol
  • 6,478
  • 5
  • 41
  • 55