0

I don't know why, but my battery broadcast receiver doesn't work.

AndroidManifest.xml

<receiver android:name=".BatteryReceiver" android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.BATTERY_CHANGED" />
        <action android:name="android.intent.action.BATTERY_LOW" />
    </intent-filter>
</receiver>

BatteryReceiver.java

public class BatteryReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        int level = intent.getIntExtra( "level", 0 );
        Log.d("Battery", "level: "+level);
        Toast.makeText(context, "Battery low!", Toast.LENGTH_LONG).show();      
    }
}

What is wrong with my code? I'm using console (telnet) to change battery level (power capacity X).

jimmym715
  • 1,512
  • 1
  • 16
  • 25
Ziem
  • 6,579
  • 8
  • 53
  • 86

1 Answers1

8

There are several issues; I've ordered them roughly by decreasing severity:

  1. You can't register for ACTION_BATTERY_CHANGED from your Manifest; you must register for it programmatically.

  2. Don't use the BATTERY_STATS permission; it's completely unrelated.

  3. If you're receiving more than one Broadcast in the same BroadcastReceiver (and it's generally a good idea even if you're not) you should check to see which Broadcast you've just received. ACTION_BATTERY_LOW should not be treated in the same way as ACTION_BATTERY_CHANGED. (For one thing, it doesn't have the BatteryManager.EXTRA_LEVEL Extra attached to it, so trying to read it will give you your default value, 0.)

  4. You should use -1 as your default value, not a valid value like 0.

  5. You should check to see if you've received the default value and handle it appropriately.

  6. You should use BatteryManager.EXTRA_LEVEL rather than hard-coding "level".

Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109
  • Perfect answer! Go further, can I register BATTERY_CHANGED without start service(performance considerations), let's say use BOOT receiver or AlarmManager or something else? – thecr0w Jul 22 '12 at 10:18
  • @thecr0w No, you can't call `Context.registerReceiver()` from a BroadcastReceiver declared in your manifest (which a BOOT_COMPLETED receiver has to be). It doesn't make much sense to register for it from an AlarmManager receiver, as the registration is tied to the lifetime of the object that registered it. If you need to always be receiving BATTERY_CHANGED, you need a Service, otherwise just register when you application starts and unregister when it's destroyed. – Darshan Rivka Whittle Jul 22 '12 at 22:05