33

I've searched on the web and couldn't find the answer to my question. My problem is to get the battery level information only once, eg. calling the function getBatteryLevel(). There are only solutions which are implemented using BroadcastReceiver, but as I know it will be called every time on battery level's change event. Please, tell me how can I get that information only once?

Karlen Kishmiryan
  • 7,322
  • 5
  • 35
  • 45

1 Answers1

100

The Intent.ACTION_BATTERY_CHANGED broadcast is what's known as a "sticky broadcast." Because this is sticky, you can register for the broadcast with a null receiver which will only get the battery level one time when you call registerReceiver.

A function to get the battery level without receiving updates would look something like this:

public float getBatteryLevel() {
    Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
    int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

    // Error checking that probably isn't needed but I added just in case.
    if(level == -1 || scale == -1) {
        return 50.0f;
    }

    return ((float)level / (float)scale) * 100.0f; 
}

More data can be pulled from this sticky broadcast. Using the returned batteryIntent you can access other extras as outlined in the BatteryManager class.

Michael Celey
  • 12,645
  • 6
  • 57
  • 62
  • This method cannot now be called from withing a Receiver (e.g. a Widget). Do you know of any other way to get the battery level that can be done from within a Widget's onUpdate() method? – Andrew Mackenzie Jul 29 '13 at 22:41
  • 1
    If you're doing this from a widget, you'll need to call `registerReceiver` like so: `getApplicationContext().registerReciever(...)` for it to work. – Michael Celey Jul 29 '13 at 22:47
  • I have a context and can call it, but the call is not permitted from within a receiver, passing this or null as the first parameter "receiver". Log message is very explicit that you cannot call from within a receiver. – Andrew Mackenzie Aug 01 '13 at 10:53
  • 2
    You can't use just any context, you need to use the context returned from `getApplicationContext()` to call `registerReceiver()` from within another receiver. I have tried this and it works. It is also the answer given in this question that is very similar to the one you're asking: http://stackoverflow.com/questions/3691579/getting-battery-level-at-android-widget – Michael Celey Aug 01 '13 at 15:57
  • 1
    With ApplicationContext that worked perfectly! Thanks! – Andrew Mackenzie Aug 07 '13 at 10:37
  • Any special permission required for achieving this? – Sid Jul 08 '16 at 11:21
  • No permissions required according to the Android documentation. – Michael Celey Jul 08 '16 at 19:41
  • This is the only way for a one-time power status query on startup. Using an arbitrary new intent won't work in that case. But subsequent power hotplug/unplug can be detected by a broadcast event. – kakyo Dec 26 '19 at 13:56