Home | History | Annotate | Download | only in monitoring-device-state
      1 page.title=Monitoring the Battery Level and Charging State
      2 parent.title=Optimizing Battery Life
      3 parent.link=index.html
      4 
      5 trainingnavtop=true
      6 parent.link=index.html
      7 previous.title=Optimizing for Doze and App Standby
      8 previous.link=doze-standby.html
      9 next.title= Determining and Monitoring the Connectivity Status
     10 next.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
     33 updates on battery life, checking the current battery level and charging state is a good place to
     34 start.</p>
     35 
     36 <p>The battery-life impact of performing application updates depends on the battery level and
     37 charging state of the device. The impact of performing updates while the device is charging over AC
     38 is negligible, so in most cases you can maximize your refresh rate whenever the device is connected
     39 to a wall charger. Conversely, if the device is discharging, reducing your update rate helps
     40 prolong the battery life.</p>
     41 
     42 <p>Similarly, you can check the battery charge level, potentially reducing the frequency of&mdash;or
     43 even 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}
     49 broadcasts all battery and charging details in a sticky {@link android.content.Intent} that includes
     50 the charging status.</p>
     51 
     52 <p>Because it's a sticky intent, you don't need to register a {@link
     53 android.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
     55 returned. You could pass in an actual {@link android.content.BroadcastReceiver} object here, but
     56 we'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);
     59 Intent 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
     62 it's charging via USB or AC charger:<p>
     63 
     64 <pre>// Are we charging / charged?
     65 int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
     66 boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
     67                      status == BatteryManager.BATTERY_STATUS_FULL;
     68 
     69 // How are we charging?
     70 int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
     71 boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
     72 boolean 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
     75 connected to an AC charger, reduce the rate if the charge is over USB, and lower it
     76 further 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
     82 monitor 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
     85 disconnected from power. It's important to receive these events even while your app isn't
     86 running&mdash;particularly as these events should impact how often you start your app in order to
     87 initiate a background update&mdash;so you should register a {@link
     88 android.content.BroadcastReceiver} in your manifest to listen for both events by defining the
     89 {@link android.content.Intent#ACTION_POWER_CONNECTED} and {@link
     90 android.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
    100 the 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
    119 the 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
    122 the battery status intent as shown here:</p>
    123 
    124 <pre>int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
    125 int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    126 
    127 float 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
    135 impact on the battery than your app's normal behavior, so it's good practice to only monitor
    136 significant changes in battery level&mdash;specifically when the device enters or exits a low
    137 battery state.</p>
    138 
    139 <p>The manifest snippet below is extracted from the intent filter element within a broadcast
    140 receiver. The receiver is triggered whenever the device battery becomes low or exits the low
    141 condition by listening for {@link android.content.Intent#ACTION_BATTERY_LOW} and {@link
    142 android.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
    152 critically low. It doesn't matter how fresh your data is if the phone turns itself off before you
    153 can 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
    156 lesson shows you how to determine the current dock state and monitor for changes in device
    157 docking.</p>
    158 
    159 
    160 
    161 
    162