7

In my application, I want to do something when the battery is low. When battery is low android fires ACTION_BATTERY_LOW and when the battery again reaches to its good health it fires intent ACTION_BATTERY_OKAY. So, I have three questions regarding this:

1.At what battery percentage android actually fires ACTION_BATTERY_LOW?

2.Does it fire that same event repeatedly if the battery gets even lower?

3.Can we configure the battery percentage at which android will fire ACTION_BATTERY_LOW intent?

I am more concerned about the third point.

Rajkiran
  • 15,845
  • 24
  • 74
  • 114

3 Answers3

12

No, you cannot set when the ACTION_BATTERY_LOW threshold will be sent. That is a system level intent that is specified by the Android ROM. Here is the code where it sets the value in the Battery Service:

mLowBatteryWarningLevel = mContext.getResources().getInteger(
            com.android.internal.R.integer.config_lowBatteryWarningLevel);

See the code below which is cut from the Android system code in the update method of the Battery Service:

/* The ACTION_BATTERY_LOW broadcast is sent in these situations:
         * - is just un-plugged (previously was plugged) and battery level is
         *   less than or equal to WARNING, or
         * - is not plugged and battery level falls to WARNING boundary
         *   (becomes <= mLowBatteryWarningLevel).
         */
        final boolean sendBatteryLow = !plugged
            && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
            && mBatteryLevel <= mLowBatteryWarningLevel
            && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);

        sendIntent();

        // Separate broadcast is sent for power connected / not connected
        // since the standard intent will not wake any applications and some
        // applications may want to have smart behavior based on this.
        Intent statusIntent = new Intent();
        statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        if (mPlugType != 0 && mLastPlugType == 0) {
            statusIntent.setAction(Intent.ACTION_POWER_CONNECTED);
            mContext.sendBroadcast(statusIntent);
        }
        else if (mPlugType == 0 && mLastPlugType != 0) {
            statusIntent.setAction(Intent.ACTION_POWER_DISCONNECTED);
            mContext.sendBroadcast(statusIntent);
        }

        if (sendBatteryLow) {
            mSentLowBatteryBroadcast = true;
            statusIntent.setAction(Intent.ACTION_BATTERY_LOW);
            mContext.sendBroadcast(statusIntent);
Kaediil
  • 5,465
  • 2
  • 21
  • 20
8

That intent is fired from the BatteryService. You'll have to analyze the code a bit, but I'm pretty sure it does not fire repeatedly:

http://gitorious.org/android-eeepc/base/blobs/fda6fae156e31a287e3cfbf66e51ea1405cdf479/services/java/com/android/server/BatteryService.java

The actual values that it fires at are setup in the android resources, so it's configurable only during a system build. This is what we have for our hardware, but this will likely be different for each hardware platform that Android runs on:

<!-- Display low battery warning when battery level dips to this value -->
<integer name="config_lowBatteryWarningLevel">15</integer>

<!-- Close low battery warning when battery level reaches this value -->
<integer name="config_lowBatteryCloseWarningLevel">20</integer>

Unless you're developing a custom hardware platform, I wouldn't make any assumptions about what these values are set to.

jsmith
  • 4,847
  • 2
  • 32
  • 39
  • Just a coding standard question, where do you store your integers? Is it in a separate constants file? – Kala J Sep 18 '14 at 20:17
  • It's been a while since I looked at that, but I'm pretty sure those are already defined in the Battery Service resources. We simply adjusted them. – jsmith Sep 19 '14 at 12:43
  • 1
    @KalaJ if these integers are going to be used *only* in java files then store it say, `CONST.java` (for constants) or `CONFIG.java` (for configuration parameters). If they are for the UI, then you store it `values.xml`. Note: `values.xml` is like any other res file and you can have multiple versions based on localizations etc. – Dheeraj Bhaskar Dec 02 '14 at 18:08
0

There is another way that detect "config_lowBatteryWarningLevel" from "com.android.internal.R.integer" field.

enter code here

    try {
        Class clazz = Class.forName("com.android.internal.R$integer");
        Field field = clazz.getDeclaredField("config_lowBatteryWarningLevel");
        field.setAccessible(true);
        int LowBatteryLevel = _context.getResources().getInteger(field.getInt(null));

        Log.d("LowBattery","warninglevel " + LowBatteryLevel);
    } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();

    }
Y.Hoo
  • 1
  • Note that this uses reflection to get info from Android classes that are explicitly marked as `internal`, so there's no guarantee this will work in the future! – Jake Lee Sep 11 '18 at 13:01