編寫:kesenhoo - 原文:http://developer.android.com/training/monitoring-device-state/battery-monitoring.html
當你想通過改變后臺更新操作的頻率來減少對電池壽命的影響時,那么首先需要檢查當前電量與充電狀態(tài)。
執(zhí)行應(yīng)用更新對電池壽命的影響是與電量和充電狀態(tài)密切相關(guān)的。當使用交流電對設(shè)備充電時,更新操作的影響可以忽略不計,所以在大多數(shù)情況下,如果使用壁式充電器對設(shè)備進行充電,我們可以將刷新頻率設(shè)置到最大。相反的,如果設(shè)備沒有在充電狀態(tài),那么我們就需要盡量減少設(shè)備的更新操作來延長電池的續(xù)航能力。
同樣的,如果我們監(jiān)測到電量即將耗盡時,那么應(yīng)該盡可能降低甚至停止更新操作。
首先來看一下應(yīng)該如何確定當前的充電狀態(tài)。BatteryManager會廣播一個帶有電池與充電詳情的Sticky Intent
因為廣播的是一個sticky Intent,所以不需要注冊BroadcastReceiver。僅僅只需要調(diào)用一個以null
作為Receiver參數(shù)的registerReceiver()
方法就可以了。如下面的代碼片段中展示的那樣,它返回了保存當前電池信息的Intent。你也可以在這里傳入一個實際的BroadcastReceiver對象,但這并不是必須的。
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);
我們可以提取出當前的充電狀態(tài),以及設(shè)備處于充電時,是通過USB還是交流充電器充電的。
// Are we charging / charged?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
// How are we charging?
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
通常,我們可以在設(shè)備使用交流充電時最大化后臺更新頻率,在使用USB充電時降低更新頻率,在非充電狀態(tài)時,將更新頻率進一步降低。
充電狀態(tài)隨時可能改變,所以我們應(yīng)該檢查充電狀態(tài)的改變來調(diào)整更新頻率。
BatteryManager會在設(shè)備連接或者斷開充電器的時候廣播一個Action。即使應(yīng)用沒有運行,我們也應(yīng)該接收這些事件的廣播,主要原因是因為這些事件會影響到應(yīng)用啟動(從而進行更新)的頻率,因此我們應(yīng)該在Manifest文件里面注冊一個BroadcastReceiver來監(jiān)聽含有ACTION_POWER_CONNECTED 與 ACTION_POWER_DISCONNECTED的Intent。
<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>
我們可以在該BroadcastReceiver的實現(xiàn)中,提取出當前的充電狀態(tài),如下所示:
public class PowerConnectionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
}
}
在一些情況下,獲取到當前電池電量也很有幫助。我們可以在獲知電量少于某個級別的時候減少后臺的更新頻率。 我們可以通過電池狀態(tài)Intent獲取到電池電量與容量等信息,如下所示:
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float batteryPct = level / (float)scale;
我們不能不停地監(jiān)測電池狀態(tài),實際上這也是不必要的。通常來說,不間斷地監(jiān)測電量信息對電池的影響會遠大于應(yīng)用本身對電池的影響。所以我們應(yīng)該僅監(jiān)測電量的一些顯著性變化,特別是當設(shè)備進入或者離開低電量狀態(tài)時。
在下面的Manifest文件片段中,BroadcastReceiver僅僅監(jiān)聽ACTION_BATTERY_LOW
與ACTION_BATTERY_OKAY
,這樣它就只會在設(shè)備電量進入低電量或者離開低電量的時候被觸發(fā)。
<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>
通常我們都需要在進入低電量的情況下,關(guān)閉所有后臺更新來維持設(shè)備的續(xù)航,因為這個時候做任何更新等操作都極有可能是無用的,因為也許在你還沒來得及處理更新的數(shù)據(jù)時,設(shè)備就因電量耗盡而自動關(guān)機了。
在很多時候,用戶往往會將設(shè)備放入某種底座中充電(譯注:比如車載的底座式充電器),在下一節(jié)課程當中,我們將會學(xué)習(xí)如何確定當前的底座狀態(tài),以及如何監(jiān)聽設(shè)備底座的變化。