1page.title=Monitoring the Battery Level and Charging State
2parent.title=Optimizing Battery Life
3parent.link=index.html
4
5trainingnavtop=true
6parent.link=index.html
7previous.title=Optimizing for Doze and App Standby
8previous.link=doze-standby.html
9next.title= Determining and Monitoring the Connectivity Status
10next.link=connectivity-monitoring.html
11@jd:body
12
13<div id="tb-wrapper">
14<div id="tb">
15
16<h2>This lesson teaches you to</h2>
17<ol>
18  <li><a href="#DetermineChargeState">Determine the Current Charging State</a></li>
19  <li><a href="#MonitorChargeState">Monitor Changes in Charging State</a></li>
20  <li><a href="#CurrentLevel">Determine the Current Battery Level</a></li>
21  <li><a href="#MonitorLevel">Monitor Significant Changes in Battery Level</a></li>
22</ol>
23
24<h2>You should also read</h2>
25<ul>
26  <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
27</ul>
28
29</div>
30</div>
31
32<p>When you're altering the frequency of your background updates to reduce the effect of those
33updates on battery life, checking the current battery level and charging state is a good place to
34start.</p>
35
36<p>The battery-life impact of performing application updates depends on the battery level and
37charging state of the device. The impact of performing updates while the device is charging over AC
38is negligible, so in most cases you can maximize your refresh rate whenever the device is connected
39to a wall charger. Conversely, if the device is discharging, reducing your update rate helps
40prolong the battery life.</p>
41
42<p>Similarly, you can check the battery charge level, potentially reducing the frequency of&mdash;or
43even stopping&mdash;your updates when the battery charge is nearly exhausted.</p>
44
45
46<h2 id="DetermineChargeState">Determine the Current Charging State</h2>
47
48<p>Start by determining the current charge status. The {@link android.os.BatteryManager}
49broadcasts all battery and charging details in a sticky {@link android.content.Intent} that includes
50the charging status.</p>
51
52<p>Because it's a sticky intent, you don't need to register a {@link
53android.content.BroadcastReceiver}&mdash;by simply calling {@code registerReceiver} passing in
54{@code null} as the receiver as shown in the next snippet, the current battery status intent is
55returned. You could pass in an actual {@link android.content.BroadcastReceiver} object here, but
56we'll be handling updates in a later section so it's not necessary.</p>
57
58<pre>IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
59Intent batteryStatus = context.registerReceiver(null, ifilter);</pre>
60
61<p>You can extract both the current charging status and, if the device is being charged, whether
62it's charging via USB or AC charger:<p>
63
64<pre>// Are we charging / charged?
65int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
66boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
67                     status == BatteryManager.BATTERY_STATUS_FULL;
68
69// How are we charging?
70int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
71boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
72boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;</pre>
73
74<p>Typically you should maximize the rate of your background updates in the case where the device is
75connected to an AC charger, reduce the rate if the charge is over USB, and lower it
76further if the battery is discharging.</p>
77
78
79<h2 id="MonitorChargeState">Monitor Changes in Charging State</h2>
80
81<p>The charging status can change as easily as a device can be plugged in, so it's important to
82monitor the charging state for changes and alter your refresh rate accordingly.</p>
83
84<p>The {@link android.os.BatteryManager} broadcasts an action whenever the device is connected or
85disconnected from power. It's important to receive these events even while your app isn't
86running&mdash;particularly as these events should impact how often you start your app in order to
87initiate a background update&mdash;so you should register a {@link
88android.content.BroadcastReceiver} in your manifest to listen for both events by defining the
89{@link android.content.Intent#ACTION_POWER_CONNECTED} and {@link
90android.content.Intent#ACTION_POWER_DISCONNECTED} within an intent filter.</p>
91
92<pre>&lt;receiver android:name=".PowerConnectionReceiver">
93  &lt;intent-filter>
94    &lt;action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
95    &lt;action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
96  &lt;/intent-filter>
97&lt;/receiver></pre>
98
99<p>Within the associated {@link android.content.BroadcastReceiver} implementation, you can extract
100the current charging state and method as described in the previous step.</p>
101
102<pre>public class PowerConnectionReceiver extends BroadcastReceiver {
103    &#64;Override
104    public void onReceive(Context context, Intent intent) {
105        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
106        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
107                            status == BatteryManager.BATTERY_STATUS_FULL;
108
109        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
110        boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
111        boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
112    }
113}</pre>
114
115
116<h2 id="CurrentLevel">Determine the Current Battery Level</h2>
117
118<p>In some cases it's also useful to determine the current battery level. You may choose to reduce
119the rate of your background updates if the battery charge is below a certain level.</p>
120
121<p>You can find the current battery charge by extracting the current battery level and scale from
122the battery status intent as shown here:</p>
123
124<pre>int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
125int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
126
127float batteryPct = level / (float)scale;</pre>
128
129
130<h2 id="MonitorLevel">Monitor Significant Changes in Battery Level</h2>
131
132<p>You can't easily continually monitor the battery state, but you don't need to.</p>
133
134<p>Generally speaking, the impact of constantly monitoring the battery level has a greater
135impact on the battery than your app's normal behavior, so it's good practice to only monitor
136significant changes in battery level&mdash;specifically when the device enters or exits a low
137battery state.</p>
138
139<p>The manifest snippet below is extracted from the intent filter element within a broadcast
140receiver. The receiver is triggered whenever the device battery becomes low or exits the low
141condition by listening for {@link android.content.Intent#ACTION_BATTERY_LOW} and {@link
142android.content.Intent#ACTION_BATTERY_OKAY}.</p>
143
144<pre>&lt;receiver android:name=".BatteryLevelReceiver">
145&lt;intent-filter>
146  &lt;action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
147  &lt;action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
148  &lt;/intent-filter>
149&lt;/receiver></pre>
150
151<p>It is generally good practice to disable all your background updates when the battery is
152critically low. It doesn't matter how fresh your data is if the phone turns itself off before you
153can make use of it.</p>
154
155<p>In many cases, the act of charging a device is coincident with putting it into a dock. The next
156lesson shows you how to determine the current dock state and monitor for changes in device
157docking.</p>
158
159
160
161
162