翻自:http://developer.android.com/training/monitoring-device-state/battery-monitoring.html
当你在更改后台更新频率来减少这些更新对电池寿命的影响时,检查当前电量和充电状态是一个好的开始。
电池寿命通过剩余电量和充电状态来影响应用更新的执行。当用交流电充电时,执行更新操作对设备的影响是微不足道的,所以在大多数案例里,你可以把更新频率调到最快。如果设备不在充电,降低更新频率可以帮助延长电池寿命。
类似的,你可以检查电池剩余电量级别,在电量低时,应该降低更新频率甚至停止更新。
注:此处的更新,指的是类似发送心跳包的动作,或者定时更新内容。并非仅仅指更新应用版本。如果是用户动作,比如翻页刷新,不需要根据电量和充电状态处理。
判断当前充电状态#
通过判断当前充电状态开始。BatteryManager会通过一个intent广播所有电池和充电详情,包含充电状态。
因为这是一个sticky intent,你不需要注册广播接收器。简单地通过调用 registerReceiver,像下面的代码段传入一个null的接收器,当前电池状态的intent就会返回。你也可以传入一个真实的接收器对象,但我们暂时不会操作更新,所以这是没必要的。
```
1
2
3
4
5
6
7
8
9
10
11
12
13 </td>
<td class="code">
```
IntentFilter ifilter <span style="color: #339933;">=</span> <span style="font-weight: bold;">new</span> IntentFilter<span style="color: #009900;">(</span>Intent.<span style="color: #006633;">ACTION_BATTERY_CHANGED</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
Intent batteryStatus <span style="color: #339933;">=</span> context.<span style="color: #006633;">registerReceiver</span><span style="color: #009900;">(</span><span style="font-weight: bold; color: #000066;">null</span>, ifilter<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="font-style: italic; color: #666666;">//你可以读到充电状态,如果在充电,可以读到是usb还是交流电</span>
<span style="font-style: italic; color: #666666;">// 是否在充电</span>
<span style="font-weight: bold; color: #000066;">int</span> status <span style="color: #339933;">=</span> batteryStatus.<span style="color: #006633;">getIntExtra</span><span style="color: #009900;">(</span>BatteryManager.<span style="color: #006633;">EXTRA_STATUS</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="font-weight: bold; color: #000066;">boolean</span> isCharging <span style="color: #339933;">=</span> status <span style="color: #339933;">==</span> BatteryManager.<span style="color: #006633;">BATTERY_STATUS_CHARGING</span> <span style="color: #339933;">||</span>
status <span style="color: #339933;">==</span> BatteryManager.<span style="color: #006633;">BATTERY_STATUS_FULL</span><span style="color: #339933;">;</span>
<span style="font-style: italic; color: #666666;">// 怎么充</span>
<span style="font-weight: bold; color: #000066;">int</span> chargePlug <span style="color: #339933;">=</span> batteryStatus.<span style="color: #006633;">getIntExtra</span><span style="color: #009900;">(</span>BatteryManager.<span style="color: #006633;">EXTRA_PLUGGED</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="font-weight: bold; color: #000066;">boolean</span> usbCharge <span style="color: #339933;">=</span> chargePlug <span style="color: #339933;">==</span> BatteryManager.<span style="color: #006633;">BATTERY_PLUGGED_USB</span><span style="color: #339933;">;</span>
<span style="font-weight: bold; color: #000066;">boolean</span> acCharge <span style="color: #339933;">=</span> chargePlug <span style="color: #339933;">==</span> BatteryManager.<span style="color: #006633;">BATTERY_PLUGGED_AC</span><span style="color: #339933;">;</span>
</td>
</tr>
|
通常你应该在使用交流电充电时最大化后台更新频率,在使用usb充电时降低,不充电时更低。
监听充电状态的改变#
充电状态很容易改变(插入/拔出充电器),所以监听充电状态,更改刷新频率很重要。
充电状态改变时,BatteryManager会发一个广播。接收这些事件很重要,甚至在应用没有运行的时候,因为可能你需要后台开启更新服务。所以,在Androidmanifest.xml里注册广播接收器,加上两个action:ACTION_POWER_CONNECTED 和ACTION_POWER_DISCONNECTED作为过滤。
```
1
2
3
4
5
6 </td>
<td class="code">
```
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"><receiver</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">".PowerConnectionReceiver"</span><span style="font-weight: bold; color: #000000;">></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"><intent-filter></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"><action</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">"android.intent.action.ACTION_POWER_CONNECTED"</span><span style="font-weight: bold; color: #000000;">/></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"><action</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">"android.intent.action.ACTION_POWER_DISCONNECTED"</span><span style="font-weight: bold; color: #000000;">/></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"></intent-filter></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"></receiver></span></span>
</td>
</tr>
|
在关联的广播接收器实现里,你可以读出当前充电状态,方法跟上一步说的相同:
```
1
2
3
4
5
6
7
8
9
10
11
12 </td>
<td class="code">
```
<span style="font-weight: bold;">public</span> <span style="font-weight: bold;">class</span> PowerConnectionReceiver <span style="font-weight: bold;">extends</span> BroadcastReceiver <span style="color: #009900;">{</span>
@Override
<span style="font-weight: bold;">public</span> <span style="font-weight: bold; color: #000066;">void</span> onReceive<span style="color: #009900;">(</span><span style="color: #003399;">Context</span> context, Intent intent<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="font-weight: bold; color: #000066;">int</span> status <span style="color: #339933;">=</span> intent.<span style="color: #006633;">getIntExtra</span><span style="color: #009900;">(</span>BatteryManager.<span style="color: #006633;">EXTRA_STATUS</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="font-weight: bold; color: #000066;">boolean</span> isCharging <span style="color: #339933;">=</span> status <span style="color: #339933;">==</span> BatteryManager.<span style="color: #006633;">BATTERY_STATUS_CHARGING</span> <span style="color: #339933;">||</span>
status <span style="color: #339933;">==</span> BatteryManager.<span style="color: #006633;">BATTERY_STATUS_FULL</span><span style="color: #339933;">;</span>
<span style="font-weight: bold; color: #000066;">int</span> chargePlug <span style="color: #339933;">=</span> intent.<span style="color: #006633;">getIntExtra</span><span style="color: #009900;">(</span>BatteryManager.<span style="color: #006633;">EXTRA_PLUGGED</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="font-weight: bold; color: #000066;">boolean</span> usbCharge <span style="color: #339933;">=</span> chargePlug <span style="color: #339933;">==</span> BatteryManager.<span style="color: #006633;">BATTERY_PLUGGED_USB</span><span style="color: #339933;">;</span>
<span style="font-weight: bold; color: #000066;">boolean</span> acCharge <span style="color: #339933;">=</span> chargePlug <span style="color: #339933;">==</span> BatteryManager.<span style="color: #006633;">BATTERY_PLUGGED_AC</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
</td>
</tr>
|
判断当前剩余电量#
在某些案例里,判断当前剩余电量同样很有用。如果电量在某些水平之下,你可能会选择降低后台更新频率。
你可以用下面的代码读到电量:
```
1
2
3
4
5
6 </td>
<td class="code">
```
<span style="font-style: italic; color: #666666;">//当前剩余电量</span>
<span style="font-weight: bold; color: #000066;">int</span> level <span style="color: #339933;">=</span> batteryStatus.<span style="color: #006633;">getIntExtra</span><span style="color: #009900;">(</span>BatteryManager.<span style="color: #006633;">EXTRA_LEVEL</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="font-style: italic; color: #666666;">//电量最大值</span>
<span style="font-weight: bold; color: #000066;">int</span> scale <span style="color: #339933;">=</span> batteryStatus.<span style="color: #006633;">getIntExtra</span><span style="color: #009900;">(</span>BatteryManager.<span style="color: #006633;">EXTRA_SCALE</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="font-style: italic; color: #666666;">//电量百分比</span>
<span style="font-weight: bold; color: #000066;">float</span> batteryPct <span style="color: #339933;">=</span> level <span style="color: #339933;">/</span> <span style="color: #009900;">(</span><span style="font-weight: bold; color: #000066;">float</span><span style="color: #009900;">)</span>scale<span style="color: #339933;">;</span>
</td>
</tr>
|
注:暂时不知道为什么要这样算,在我自己的机器上运行,scale就是100的。
监听剩余电量显著改变#
持续监听电池状态不容易,但你不必这么做。
一般来说,持续监听电池电量对电池的影响比app的正常行为还要大。所以,只监听剩余电量的指定级别的改变(进入或离开低电量状态)是一个很好的实践。
manifest里声明的接收器,会在进入或离开低电量状态时触发。
```
1
2
3
4
5
6 </td>
<td class="code">
```
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"><receiver</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">".BatteryLevelReceiver"</span><span style="font-weight: bold; color: #000000;">></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"><intent-filter></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"><action</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">"android.intent.action.ACTION_BATTERY_LOW"</span><span style="font-weight: bold; color: #000000;">/></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"><action</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">"android.intent.action.ACTION_BATTERY_OKAY"</span><span style="font-weight: bold; color: #000000;">/></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"></intent-filter></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: #000000;"></receiver></span></span>
</td>
</tr>
|
剩余电量严重不足时,最好禁用所有后台更新。在你可以使用手机之前就关机了,这种情况下,如果刷新数据并不重要。
在很多情况下,设备是是插入到底座里充电的(好吧,反正我没见几个人额外花钱买底座的,可能国外较多)。下节讲怎么判断当前底座状态和监听插入底座时改变。
💬 评论