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