監控電池電量和充電狀態

修改背景更新的頻率來降低這些更新對電池續航力的影響時,建議您檢查目前的電池電量和充電狀態。

執行應用程式更新後的電池續航力影響取決於裝置的電池電量和充電狀態。在裝置透過 AC 充電時執行更新,影響可忽略不大,因此在大多數情況下,只要裝置連上壁式充電器,就能大幅提高刷新率。相反地,如果裝置正在放電,降低更新率有助於延長電池續航力。

同樣地,當電池電力即將耗盡時,您可以檢查電池充電量,這樣可能會降低更新頻率,甚至停止更新。

判斷目前的充電狀態

首先,請確認目前的充電狀態。BatteryManager 會在包含充電狀態的固定式 Intent 中廣播所有電池和充電詳細資料。

由於這是固定式意圖,因此您不需要註冊 BroadcastReceiver,只要呼叫 registerReceiver 傳入 null 即可做為接收器,如下一個程式碼片段所示,系統會傳回目前的電池狀態意圖。您可以在這裡傳入實際的 BroadcastReceiver 物件,但會在後續章節中處理更新,因此並非必要。

Kotlin

val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
    context.registerReceiver(null, ifilter)
}

Java

IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);

您可以擷取目前的充電狀態,以及裝置充電時 (無論是透過 USB 還是 AC 充電器充電):

Kotlin

val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
val isCharging: Boolean = status == BatteryManager.BATTERY_STATUS_CHARGING
        || status == BatteryManager.BATTERY_STATUS_FULL

// How are we charging?
val chargePlug: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1
val usbCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_USB
val acCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_AC

Java

// 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;

一般而言,在裝置連接 AC 充電器的情況下,您應該最大程度地提高背景更新速率,如果充電是透過 USB 充電,請降低速率;如果電池正在充電,請降低背景更新頻率。

監控充電狀態變更

充電狀態很容易因為裝置接上電源而改變,因此請務必監控充電狀態是否有變化,並視情況調整刷新率。

BatteryManager 會在裝置連線或拔除電源時廣播動作。即使應用程式並未執行,您也必須接收這些事件 (尤其是這些事件會影響應用程式的啟動頻率),以便啟動背景更新。因此,您必須在資訊清單中註冊 BroadcastReceiver,透過在意圖篩選器內定義 ACTION_POWER_CONNECTEDACTION_POWER_DISCONNECTED 來監聽這兩個事件。

<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>

判斷目前的電池電量

在某些情況下,判斷目前的電池電量也很有幫助。如果電池充電到特定程度以下,您可以選擇降低背景更新速率。

您可以從電池狀態意圖中擷取目前的電池電量,並從電池狀態意圖擷取體重計,藉此找出目前的電池充電情況,如下所示:

Kotlin

val batteryPct: Float? = batteryStatus?.let { intent ->
    val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
    val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
    level * 100 / scale.toFloat()
}

Java

int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

float batteryPct = level * 100 / (float)scale;

因應電池電量的重大變化

您無法輕鬆持續監控電池狀態,但非必要。

一般來說,監控電池電量對電池的影響程度比應用程式的正常行為更嚴重。舉例來說,在資訊清單中註冊 BroadcastReceiver 以在電量較低時取消未完成的工作,系統會進一步消耗電池電力,因此自 Android 8.0 起就不行。相反地,您可以對工作限制說明應該執行的時間,讓系統在不啟動應用程式的情況下做出決定。

一般而言,建議在電池電量嚴重不足時,不要執行背景更新。只要將手機自行關機,才能使用資料,也不受資料更新時間影響。為此,請使用 WorkManager 程式庫搭配 BatteryNotLow 限制,以指定在電量過低時不應執行工作 (除了任何相關的 NetworkType 限制)。

在許多情況下,為裝置充電時,裝置插入座架時,會有很恰當的行為。下一堂課將說明如何判斷目前的座架狀態,以及監控裝置文件的變更。