
Introduction
This article provides some tips on optimizing battery consumption by applications.
By disabling background update services when the connection is lost or by reducing the frequency of updates when the battery level is low, you can significantly minimize the impact of the application on the battery.
Some background services (downloading updates or application content from the network, complex calculations, etc.) are advisable to disable or reduce the frequency of their launch when the battery level is low. For such actions, it is important to take into account several factors, such as, for example, the current state of charging of the device, the presence of a connected docking station or the presence of a connection to the network. Below are ways to get these values and monitor their changes.
Current charging status
The
BatteryManager class sends out information about the level and state of charge of the battery in the appropriate intent. In this case, you can register a BroadcastReceiver and receive timely information about the battery status. And you can get this data one-time without registering the receiver:
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); Intent batteryIntent = context.registerReceiver(null, ifilter);
From the received intent information is taken about the current level of battery charge, the state of charge, and also about whether the charge is from an alternating current (AC) or usb network:
public void getBatteryStatus(Intent batteryIntent) {
Usually it is worthwhile to increase to the maximum the frequency of background updates of the application, if the device is charging from the AC mains, reduce if charging goes through usb and make minimum if the device is not in charge at all.
In the same case, when it is necessary to monitor the state of charging of the device, you should register in the manifest of the application BroadcastReceiver, which will receive messages about the connection / disconnection of the charger. In this case, you need to add
ACTION_POWER_CONNECTED and
ACTION_POWER_DISCONNECTED to intent-filter:
<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>
public class PowerConnectionReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { getBatteryStatus(intent); } }
Current battery charge
The current relative battery charge can be calculated from the values of current charge and maximum charge:
int level = battery.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = battery.getIntExtra(BatteryManager.EXTRA_SCALE, -1); float batteryPct = level / (float)scale;
It is worth mentioning that regular monitoring of battery status is resource-intensive for the battery itself. Therefore, it is recommended to monitor only certain changes in the charge level, namely the low charge level:
<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>
It is good practice to turn off all background updates or calculations when the battery level becomes low.
Dock status and type
There are a large number of docking stations for Android devices. For example, a docking station in the car or a docking keyboard on the Asus Transformer. However, most docking stations charge the device itself.
You can get information about the type and status of the docking station from
ACTION_DOCK_EVENT . You can get it one time:
IntentFilter ifilter = new IntentFilter(Intent.ACTION_DOCK_EVENT); Intent dockIntent = context.registerReceiver(null, ifilter);
either subscribe to alerts by adding a BroadcastReceiver in the manifest and specifying the action:
<action android:name="android.intent.action.ACTION_DOCK_EVENT"/>
Information about the docking station is obtained as follows:
public void getDockStatus(Intent dockIntent) {
Values
EXTRA_DOCK_STATE_HE_DESK and
EXTRA_DOCK_STATE_LE_DESK appeared only with API version 11.
')
Network connection status
Before performing background updates of the application or long downloads from the network, it is worth checking the connection and its approximate speed. For this, you can use the
ConnectivityManager class.
Internet Connection Definition:
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); boolean isConnected = activeNetwork.isConnectedOrConnecting();
It is also sometimes worthwhile to determine the type of current connection before downloading. This is important because The connection speed of the mobile Internet is usually lower than that of Wi-Fi, and the cost of traffic is higher.
boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
You can subscribe to alerts for changing the status of a connection by adding a corresponding action to the BroadcastReceiver manifest by specifying the appropriate action:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
Since such changes can occur quite often, it is good practice to monitor these alerts only when updates or downloads have been disabled previously. Usually, it is enough to check the availability of the connection before starting the updates and, in the case where the connection is not present, subscribe to alerts.
Enable / Disable Alerts
Notifications about the state of the battery, docking station and connection availability are not recommended to be constantly turned on, because they will wake up the device too often. The best solution would be to include alerts only when needed.
The
PackageManager class allows
you to change the state of elements declared in the manifest, including turning on / off BroadcastReceivers:
ComponentName receiver = new ComponentName(context, CustomReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
With the help of such a technique, for example, when a connection is broken, you can leave enabled only the notification of changes in the network state. When a connection appears, you can turn off notifications about network changes and only check if there is a connection at the moment.
Similar techniques can also be used to postpone downloading data from the network until there is a connection with higher bandwidth, such as Wi-Fi.
The article is a free translation of a set of tips from the
Android Training program on optimizing battery consumption by applications.