监控电池电量和充电状态

当您通过更改后台更新的频率来减少这些更新对电池续航时间的影响时,最好先从检查当前电池电量和充电状态入手。

正在运行的应用对电池续航时间的影响取决于设备的电池电量和充电状态。设备通过交流电充电时执行更新的影响可以忽略不计,因此在大多数情况下,只要设备连接到壁式充电器,您就可以最大限度地提高刷新率。相反,如果设备正在放电,降低更新频率有助于延长电池续航时间。

同样,您可以检查电池充电电量,并在电池电量即将耗尽时降低更新频率,甚至停止更新。

确定当前充电状态

首先,确定当前充电状态。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_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>

确定当前电池电量

在某些情况下,确定当前电池电量也很有用处。您可以选择在电池电量低于特定水平时降低后台更新的频率。

您可以通过从电池状态 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;

监控显著的电池电量变化

您无法轻松地持续监控电池状态,您也不必如此。

一般来说,持续监控电池电量对电池的影响大于对应用正常行为的影响,因此最好仅监控显著的电池电量变化 - 特别是在设备进入或退出电量不足状态时。

以下清单代码段提取自广播接收器内的 intent 过滤器元素。通过监听 ACTION_BATTERY_LOWACTION_BATTERY_OKAY,每当设备电池电量不足或退出不足状态时,就会触发接收器。

<receiver android:name=".BatteryLevelReceiver">
  <intent-filter>
    <action android:name="android.intent.action.BATTERY_LOW"/>
    <action android:name="android.intent.action.BATTERY_OKAY"/>
  </intent-filter>
</receiver>

一般而言,最好在电池电量极低时停用所有后台更新。如果手机在您利用数据之前就已自行关机,数据的新鲜度则无关紧要。

在许多情况下,为设备充电与将设备插入基座是同一操作。下一课将介绍如何确定当前基座状态并监控设备插接状态的变化。