监控电池电量和充电状态
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
如果您要通过改变后台更新的频率来减少这些更新对电池续航时间的影响,最好先从检查当前电池电量和充电状态入手。
执行应用程序更新对电池续航时间的影响取决于电池电量和
设备的充电状态。设备通过交流电充电时执行更新的影响
可以忽略不计,因此在大多数情况下,您可以在连接设备时最大限度地提高刷新率
墙上的充电器。相反,如果设备正在放电,降低更新频率有助于延长电池续航时间。
同理,您也可以检查电池电量,可能降低充电频率或
甚至在电池电量几乎耗尽时更新您的更新。
确定当前充电状态
首先,确定当前充电状态。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
约束条件)。
在许多情况下,为设备充电与将设备插入基座是同一操作。如需了解详情,请参阅确定和监控插接状态和基座类型。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[null,null,["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Monitor the Battery Level and Charging State\n\nWhen you're altering the frequency of your background updates to reduce the effect of those\nupdates on battery life, checking the current battery level and charging state is a good place to\nstart.\n\nThe battery-life impact of performing application updates depends on the battery level and\ncharging state of the device. The impact of performing updates while the device is charging over AC\nis negligible, so in most cases you can maximize your refresh rate whenever the device is connected\nto a wall charger. Conversely, if the device is discharging, reducing your update rate helps\nprolong the battery life.\n\nSimilarly, you can check the battery charge level, potentially reducing the frequency of---or\neven stopping---your updates when the battery charge is nearly exhausted.\n\nDetermine the current charging state\n------------------------------------\n\nStart by determining the current charge status. The [BatteryManager](/reference/android/os/BatteryManager)\nbroadcasts all battery and charging details in a sticky [Intent](/reference/android/content/Intent) that includes\nthe charging status.\n\nBecause it's a sticky intent, you don't need to register a [BroadcastReceiver](/reference/android/content/BroadcastReceiver)---by simply calling `registerReceiver` passing in\n`null` as the receiver as shown in the next snippet, the current battery status intent is\nreturned. You could pass in an actual [BroadcastReceiver](/reference/android/content/BroadcastReceiver) object here, but\nwe'll be handling updates in a later section so it's not necessary. \n\n### Kotlin\n\n```kotlin\nval batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter -\u003e\n context.registerReceiver(null, ifilter)\n}\n```\n\n### Java\n\n```java\nIntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);\nIntent batteryStatus = context.registerReceiver(null, ifilter);\n```\n\nYou can extract both the current charging status and, if the device is being charged, whether\nit's charging via USB or AC charger:\n\n\n### Kotlin\n\n```kotlin\nval status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1\nval isCharging: Boolean = status == BatteryManager.BATTERY_STATUS_CHARGING\n || status == BatteryManager.BATTERY_STATUS_FULL\n\n// How are we charging?\nval chargePlug: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1\nval usbCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_USB\nval acCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_AC\n```\n\n### Java\n\n```java\n// Are we charging / charged?\nint status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);\nboolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||\n status == BatteryManager.BATTERY_STATUS_FULL;\n\n// How are we charging?\nint chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);\nboolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;\nboolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;\n```\n\nTypically you should maximize the rate of your background updates in the case where the device is\nconnected to an AC charger, reduce the rate if the charge is over USB, and lower it\nfurther if the battery is discharging.\n\nMonitor changes in charging state\n---------------------------------\n\nThe charging status can change as easily as a device can be plugged in, so it's important to\nmonitor the charging state for changes and alter your refresh rate accordingly.\n\nThe [BatteryManager](/reference/android/os/BatteryManager) broadcasts an action whenever the device is connected or\ndisconnected from power. It's important to receive these events even while your app isn't\nrunning---particularly as these events should impact how often you start your app in order to\ninitiate a background update---so you should register a [BroadcastReceiver](/reference/android/content/BroadcastReceiver) in your manifest to listen for both events by defining the\n[ACTION_POWER_CONNECTED](/reference/android/content/Intent#ACTION_POWER_CONNECTED) and [ACTION_POWER_DISCONNECTED](/reference/android/content/Intent#ACTION_POWER_DISCONNECTED) within an intent filter. \n\n```xml\n\u003creceiver android:name=\".PowerConnectionReceiver\"\u003e\n \u003cintent-filter\u003e\n \u003caction android:name=\"android.intent.action.ACTION_POWER_CONNECTED\"/\u003e\n \u003caction android:name=\"android.intent.action.ACTION_POWER_DISCONNECTED\"/\u003e\n \u003c/intent-filter\u003e\n\u003c/receiver\u003e\n```\n\nDetermine the current battery level\n-----------------------------------\n\nIn some cases it's also useful to determine the current battery level. You may choose to reduce\nthe rate of your background updates if the battery charge is below a certain level.\n\nYou can find the current battery charge by extracting the current battery level and scale from\nthe battery status intent as shown here: \n\n### Kotlin\n\n```kotlin\nval batteryPct: Float? = batteryStatus?.let { intent -\u003e\n val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)\n val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)\n level * 100 / scale.toFloat()\n}\n```\n\n### Java\n\n```java\nint level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);\nint scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);\n\nfloat batteryPct = level * 100 / (float)scale;\n```\n\nReact to significant changes in battery level\n---------------------------------------------\n\nYou can't easily continually monitor the battery state, but you don't need to.\n\nGenerally speaking, the impact of monitoring the battery level has a greater\nimpact on the battery than your app's normal behavior. For example, registering a\n`BroadcastReceiver` in the manifest to cancel pending work when the battery is low will\nmainly serve to drain the battery further (and is therefore\n[impossible since\nAndroid 8.0](/develop/background-work/background-tasks/broadcasts/broadcast-exceptions)). Instead, you can provide constraints on work that describe when it should be run,\nallowing the system to make the decision without spending power starting your app.\n\nIt is generally good practice to not run your background updates when the battery is\ncritically low. It doesn't matter how fresh your data is if the phone turns itself off before you\ncan make use of it. To do this,\n[use the WorkManager library](/develop/background-work/background-tasks/persistent/getting-started)\nwith a\n[`BatteryNotLow` constraint](/develop/background-work/background-tasks/persistent/getting-started/define-work#work-constraints)\nto specify that the work should not be run if the battery is low (in addition to any relevant\n`NetworkType` constraints).\n\nIn many cases, the act of charging a device is coincident with putting it\ninto a dock. To learn more, see\n[Determine and\nmonitor the docking state and type](/training/monitoring-device-state/docking-monitoring)."]]