Android Development: Optimizing Battery Duration-Monitoring Power Volume and Charging State

Posted by tom100 on Sat, 25 May 2019 20:55:32 +0200

When you change the background update frequency to reduce the impact of these updates on battery life, it's a good start to check current power and charging status.

Battery life affects the execution of application updates by residual power and charging status. When charging with alternating current, the effect of updating operation on equipment is negligible, so in most cases, you can set the updating frequency to the fastest. If the device is not charging, reducing the update frequency can help prolong battery life.

Similarly, you can check the battery's residual power level, and when the power is low, you should reduce the update frequency or even stop the update.

Note: Updates here refer to actions like sending heartbeat packets or updating content regularly. It's not just about updating the application version. If it is user action, such as page flipping refresh, it does not need to be processed according to the amount of electricity and charging status.

Judging the Current Charging State

Start by judging the current charging status. Battery Manager broadcasts all battery and charging details through an intent, including charging status.

Because this is a sticky intent, you don't need to register a broadcast receiver. Simply by calling registerReceiver and passing in a null receiver like the code snippet below, intent of the current battery state returns. You can also pass in a real receiver object, but we won't operate updates for the time being, so it's unnecessary.

IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);
//You can read the charging state. If you charge, you can read usb or alternating current.

// Is it charging?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                     status == BatteryManager.BATTERY_STATUS_FULL;

// How to charge
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;

Usually you should maximize the background update frequency when using AC charging, reduce it when using usb charging and lower when not charging.

Monitor changes in charging status

Charging status is easy to change (plug in/pull out charger), so it is important to monitor charging status and change refresh frequency.

When the charging status changes, Battery Manager sends a broadcast. Receiving these events is important, even when the application is not running, because you may need to start the update service in the background. So, register the broadcast receiver in Androidmanifest.xml, and add two actions: ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED as filters.

<receiver android:name=".PowerConnectionReceiver">
  <intent-filter>
    <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
  </intent-filter>
</receiver>

In the associated broadcasting receiver implementation, you can read the current charging status in the same way as in the previous step:

public class PowerConnectionReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) { 
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                            status == BatteryManager.BATTERY_STATUS_FULL;
    
        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
        boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
    }
}

Judging the Current Residual Electricity

In some cases, it is also useful to judge the current remaining electricity. If the power level is below some level, you may choose to reduce the background update frequency.
You can read the power using the following code:

//Current Residual Electricity
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
//Maximum Electricity
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
//Battery Percentage
float batteryPct = level / (float)scale;

Note: I don't know why to do this for the time being. When I run on my own machine, scale is 100.

Monitoring significant changes in residual power

Continuous monitoring of battery status is not easy, but you don't have to.
In general, continuous monitoring of battery power has a greater impact on the battery than app's normal behavior. Therefore, it is a good practice to monitor only the change of the specified level of the remaining electricity (entering or leaving the low-power state).
The receiver declared in manifest triggers when it enters or leaves a low-power state.

<receiver android:name=".BatteryLevelReceiver">
<intent-filter>
  <action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
  <action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
  </intent-filter>
</receiver>

When the remaining power is seriously insufficient, it is better to disable all background updates. Turn off the phone before you can use it. In this case, it doesn't matter if you refresh the data.
In many cases, the device is plugged into the base for charging (well, I haven't seen a few people pay extra for the base anyway, maybe more abroad). The next section describes how to determine the current status of the base and monitor changes when inserted into the base.

Link to the original text: https://www.pocketdigi.com/20140608/1341.html

Topics: Android xml