Cómo supervisar el nivel de batería y el estado de carga

Cuando modifiques la frecuencia de las actualizaciones en segundo plano para reducir su efecto actualizaciones sobre la duración de la batería, comprobar el nivel actual de la batería y el estado de carga es un buen lugar para comenzar.

El impacto que tienen las actualizaciones de aplicaciones en la duración de la batería depende del nivel de batería. estado de carga del dispositivo. El impacto de realizar actualizaciones mientras el dispositivo se está cargando con CA es insignificante, por lo que, en la mayoría de los casos, se puede maximizar la frecuencia de actualización cuando el dispositivo está conectado a un cargador de pared. Por el contrario, si el dispositivo está en proceso de descarga, reducir la frecuencia de actualización prolongar la duración de la batería.

Del mismo modo, puedes comprobar el nivel de carga de la batería y reducir la frecuencia de las actualizaciones cuando la batería está por agotarse.

Cómo determinar el estado de carga actual

En primer lugar, determina el estado de carga actual. El BatteryManager transmite todos los detalles de la batería y la carga en un Intent fijo que incluye el estado de carga.

Como se trata de un intent persistente, no necesitas registrar un BroadcastReceiver; solo debes llamar a registerReceiver y pasarlo. null como receptor, como se muestra en el siguiente fragmento, el intent del estado actual de la batería es que se devuelven. Puedes pasar un objeto BroadcastReceiver real, pero Nos encargaremos de las actualizaciones más adelante, por lo que no es necesario.

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

Puedes extraer el estado de carga actual y, si el dispositivo se está cargando, si se Se está cargando a través de un cargador de CA o 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;

Por lo general, debes maximizar la frecuencia de las actualizaciones en segundo plano si el dispositivo está conectado a un cargador de CA, reducir la velocidad si la carga se realiza a través de USB y disminuirla si la batería se está descargando.

Cómo supervisar los cambios en el estado de carga

El estado de carga puede cambiar tan fácilmente como se puede enchufar un dispositivo. Por eso, es importante supervisar el estado de carga para detectar cambios y modificar la frecuencia de actualización según corresponda.

BatteryManager transmite una acción cada vez que el dispositivo está conectado o desconectado de la fuente de alimentación. Es importante recibir estos eventos incluso cuando la app no esté activa. especialmente porque estos eventos deberían afectar la frecuencia con la que inicias tu app para iniciar una actualización en segundo plano, por lo que debes registrar un BroadcastReceiver en tu manifiesto para escuchar ambos eventos definiendo el ACTION_POWER_CONNECTED y ACTION_POWER_DISCONNECTED dentro de un filtro de intents.

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

Cómo determinar el nivel de batería actual

En algunos casos, también es útil determinar el nivel de batería actual. Puedes reducir la velocidad de las actualizaciones en segundo plano si el nivel de carga de la batería es inferior a un valor determinado.

Puedes ver la carga actual de la batería al extraer el nivel actual de la batería y la escala de el intent de estado de la batería, como se muestra a continuación:

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;

Reacciona a cambios significativos en el nivel de batería

No es fácil controlar continuamente el estado de la batería, pero tampoco es necesario.

En términos generales, el impacto de supervisar el nivel de batería tiene un mayor impacto en la batería que el comportamiento normal de tu app. Por ejemplo, si registras un BroadcastReceiver en el manifiesto para cancelar el trabajo pendiente cuando la batería esté baja sirven principalmente para agotar más la batería (y, por lo tanto, imposible desde Android 8.0). En su lugar, puedes proporcionar restricciones sobre el trabajo que describan cuándo se debe ejecutar, lo que permite que el sistema tome la decisión sin tener que iniciar la app.

Una práctica recomendada es no ejecutar actualizaciones en segundo plano cuando el nivel de batería está bajo a niveles críticamente bajos. Si el teléfono se apaga antes de que lo hagas, no importa qué tan actualizados estén los datos puede aprovechar sus beneficios. Para ello, Usa la biblioteca de WorkManager con un Restricción de BatteryNotLow para especificar que el trabajo no se debe ejecutar si el nivel de batería es bajo (además de cualquier NetworkType).

En muchos casos, el hecho de cargar un dispositivo coincide con la acción de utilizar un conector. Los siguientes en la que se muestra cómo determinar el estado actual del conector y cómo supervisar los cambios en el dispositivo de la estación de carga.