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 el efecto de las actualizaciones en la duración de la batería, te recomendamos que comiences por comprobar el estado de carga y el nivel actual de la batería.

El impacto en la duración de la batería de las actualizaciones de aplicaciones depende del nivel de batería y del estado de carga del dispositivo. Mientras el dispositivo se carga con CA, el impacto es insignificante. Por lo tanto, en la mayoría de los casos, puedes 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 ayuda a 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 (o incluso detenerlas) cuando la batería esté a punto de agotarse.

Cómo determinar el estado de carga actual

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

Como se trata de un intent persistente, no es necesario registrar un BroadcastReceiver; con solo llamar a registerReceiver y pasar null como el receptor, como se muestra en el siguiente fragmento, se muestra el intent de estado actual de la batería. Puedes pasar un objeto BroadcastReceiver real aquí, pero nos encargaremos de las actualizaciones en una sección posterior, 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, puedes ver si se está usando un cargador de CA o un 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, reducirla si se usa un USB y reducirla aún más 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 conectar un dispositivo, por lo que es importante supervisarlo en busca de cambios y modificar la frecuencia de actualización según corresponda.

El BatteryManager emite una acción siempre que el dispositivo se conecta o desconecta de la fuente de alimentación. Es importante recibir estos eventos incluso cuando no se está ejecutando tu app (especialmente porque estos eventos pueden afectar la frecuencia con la que inicias tu app para iniciar una actualización en segundo plano). Por lo tanto, debes registrar un BroadcastReceiver en tu manifiesto para escuchar ambos eventos definiendo ACTION_POWER_CONNECTED y ACTION_POWER_DISCONNECTED en 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 frecuencia de las actualizaciones en segundo plano si el nivel de carga de la batería es inferior a un valor determinado.

Para consultar la carga actual de la batería, extrae el nivel y la escala actuales de la batería desde 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;

Cómo supervisar cambios importantes en el nivel de la 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 constantemente el nivel de batería tiene un mayor impacto en la batería que el comportamiento normal de la app, por lo que se recomienda supervisar solo los cambios significativos en el nivel de batería, en especial cuando el dispositivo entra en un estado de batería baja o sale de él.

El fragmento de manifiesto que aparece a continuación se extrajo del elemento de filtro de intents de un receptor de emisión. El receptor se activa cada vez que la batería del dispositivo está baja o sale de un estado de carga baja mediante la escucha de ACTION_BATTERY_LOW y ACTION_BATTERY_OKAY.

<receiver android:name=".BatteryLevelReceiver">
  <intent-filter>
    <action android:name="android.intent.action.BATTERY_LOW"/>
    <action android:name="android.intent.action.BATTERY_OKAY"/>
  </intent-filter>
</receiver>

Cuando el nivel de batería esté muy bajo, es recomendable que inhabilites todas las actualizaciones en segundo plano. Si el teléfono se apaga antes de que puedas usarlos, no importa qué tan actualizados estén tus datos.

En muchos casos, el hecho de cargar un dispositivo coincide con la acción de utilizar un conector. En la siguiente lección, se muestra cómo determinar el estado actual del conector y cómo supervisar los cambios cuando se conecta el dispositivo.