当您通过改变后台更新的频率来降低这些更新对电池续航时间的影响时,最好从检查当前电池电量和充电状态入手。
执行应用更新对电池续航时间的影响取决于设备的电池电量和充电状态。设备通过交流电源充电时执行更新的影响可以忽略不计,因此在大多数情况下,只要设备连接到壁式充电器,您都可以最大限度地提高刷新率。相反,如果设备正在放电,降低更新频率有助于延长电池续航时间。
同样,您可以查看电池电量,从而在电池电量近乎耗尽时降低更新频率,甚至停止更新。
确定当前充电状态
首先,确定当前充电状态。BatteryManager
会在一个包含充电状态的粘性 Intent
中广播所有电池和充电详情。
由于它是粘性 intent,因此您无需注册 BroadcastReceiver
。只需调用 registerReceiver
并传入 null
作为接收器(如下一个代码段所示),即可返回当前的电池状态 intent。您可以在此处传入实际的 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 还是交流电源充电器充电:
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;
通常情况下,如果设备连接到交流电源充电器,您应最大限度地提高后台更新的频率;如果是通过 USB 充电,则应降低后台更新的频率;如果电池正在放电,则应进一步降低更新的频率。
监控充电状态变化
就像设备可以轻松地接通电源一样,充电状态也很容易发生变化,因此请务必监控充电状态的变化,并相应地改变刷新频率。
每当设备连接或断开电源时,BatteryManager
都会广播一项操作。即使应用未运行,也接收这些事件很重要,尤其是因为这些事件会影响您启动应用以便启动后台更新的频率。因此,您应在清单中注册 BroadcastReceiver
,通过在 intent 过滤器中定义 ACTION_POWER_CONNECTED
和 ACTION_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>
确定当前电池电量
在某些情况下,确定当前电池电量也很有用处。您可以选择在电池电量低于特定水平时降低后台更新的频率。
您可以通过从电池状态 intent 提取当前电池电量和刻度来了解当前电池电量,如下所示:
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
约束条件)。
在许多情况下,为设备充电与将设备插入基座是同一操作。下一课将介绍如何确定当前基座状态以及如何监控设备插接状态的变化。