I can't receive broadcast on battery state cha

2020-02-01 07:24发布

问题:

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.

回答1:

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.



回答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.)



回答3:

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