监控电池电量和充电状态

当您更改后台更新频率以减少这些更新对电池寿命的影响时,检查当前电池电量和充电状态是一个良好的开端。

执行应用程序更新对电池寿命的影响取决于设备的电池电量和充电状态。在设备通过交流电充电时执行更新的影响可以忽略不计,因此在大多数情况下,您可以随时将刷新率最大化,只要设备连接到墙壁充电器即可。相反,如果设备正在放电,降低更新率有助于延长电池寿命。

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

确定当前充电状态

首先确定当前充电状态。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 以通过定义 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 约束条件)。

在许多情况下,为设备充电与将其放入底座是同时发生的。下一课将向您展示如何确定当前的底座状态并监视设备对接状态的变化。