Если вы хотите изменить частоту фоновых обновлений, чтобы снизить их влияние на время работы от батареи, сначала проверьте текущий уровень заряда батареи и состояние зарядки.
Влияние обновлений приложений на время работы от батареи зависит от уровня заряда батареи и состояния зарядки устройства. Обновления, выполняемые во время зарядки устройства от сети переменного тока, практически не влияют на его работу, поэтому в большинстве случаев вы можете максимально увеличить частоту обновления, когда устройство подключено к зарядному устройству. И наоборот, если устройство разряжается, снижение частоты обновления помогает продлить срок службы батареи.
Аналогичным образом можно проверять уровень заряда батареи и снижать частоту обновлений или даже полностью их отключать, когда батарея почти разряжена.
Определить текущий статус зарядки
Сначала определите текущий статус оплаты. 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 или зарядное устройство переменного тока):
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_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>
Как узнать текущий уровень заряда батареи
В некоторых случаях также полезно определить текущий уровень заряда батареи. Вы можете снизить частоту фоновых обновлений, если заряд батареи ниже определенного уровня.
Чтобы узнать текущий уровень заряда батареи, извлеките его из намерения, как показано ниже:
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).
Во многих случаях зарядка устройства совпадает с его установкой в док-станцию. Подробнее о том, как определить и отслеживать тип и состояние док-станции…