Контролируйте уровень заряда батареи и состояние зарядки

Когда вы меняете частоту фоновых обновлений, чтобы уменьшить влияние этих обновлений на срок службы батареи, хорошей отправной точкой будет проверка текущего уровня заряда батареи и состояния зарядки.

Влияние обновления приложений на срок службы батареи зависит от уровня заряда батареи и состояния зарядки устройства. Влияние выполнения обновлений во время зарядки устройства от сети переменного тока незначительно, поэтому в большинстве случаев вы можете максимизировать частоту обновления всякий раз, когда устройство подключено к настенному зарядному устройству. И наоборот, если устройство разряжается, снижение частоты обновления помогает продлить срок службы батареи.

Аналогичным образом вы можете проверить уровень заряда аккумулятора, потенциально снижая частоту обновлений или даже останавливая их, когда заряд аккумулятора почти разряжен.

Определите текущее состояние зарядки

Начните с определения текущего состояния заряда. BatteryManager передает все сведения о батарее и зарядке в виде прикрепленного Intent , которое включает состояние зарядки.

Поскольку это фиксированное намерение, вам не нужно регистрировать BroadcastReceiver — просто вызывая registerReceiver , передавая null в качестве получателя, как показано в следующем фрагменте, возвращается текущее намерение о состоянии батареи. Здесь вы можете передать реальный объект BroadcastReceiver , но мы будем обрабатывать обновления в следующем разделе, поэтому в этом нет необходимости.

Котлин

val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
    context.registerReceiver(null, ifilter)
}

Ява

IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);

Вы можете извлечь как текущий статус зарядки, так и, если устройство заряжается, то, заряжается ли оно через USB или зарядное устройство переменного тока:

Котлин

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

Ява

// 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>

Определить текущий уровень заряда батареи

В некоторых случаях также полезно определить текущий уровень заряда батареи. Вы можете уменьшить частоту фоновых обновлений, если заряд батареи ниже определенного уровня.

Вы можете узнать текущий заряд батареи, извлекая текущий уровень заряда батареи и шкалу из намерения о состоянии батареи, как показано здесь:

Котлин

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()
}

Ява

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 ).

Во многих случаях зарядка устройства совпадает с установкой его в док-станцию. На следующем уроке вы узнаете, как определить текущее состояние док-станции и отслеживать изменения в стыковке устройства.