Surveiller l'état de charge et le niveau de la batterie

Lorsque vous modifiez la fréquence de vos mises à jour en arrière-plan pour réduire leur impact sur l'autonomie de la batterie, commencez par vérifier le niveau de batterie actuel et l'état de charge.

L'impact des mises à jour des applications sur l'autonomie de la batterie dépend du niveau de la batterie et l'état de charge de l'appareil. Impact des mises à jour effectuées lorsque l'appareil est en charge sur secteur est négligeable. Dans la plupart des cas, vous pouvez donc maximiser la fréquence d'actualisation lorsque l'appareil est connecté à un chargeur mural. À l'inverse, si l'appareil se décharge, réduire la fréquence de mise à jour de prolonger l'autonomie de la batterie.

De même, vous pouvez vérifier le niveau de charge de la batterie, ce qui peut réduire la fréquence des... vos mises à jour lorsque le niveau de charge de la batterie est presque épuisé.

Déterminer l'état de charge actuel

Commencez par déterminer l'état actuel des débits. BatteryManager diffuse tous les détails de la batterie et de la charge dans un élément Intent collant qui inclut l'état de charge.

Comme il s'agit d'un intent persistant, vous n'avez pas besoin d'enregistrer un BroadcastReceiver. Il vous suffit d'appeler registerReceiver en transmettant null comme récepteur, comme indiqué dans l'extrait de code suivant. L'intent d'état de la batterie actuel est alors renvoyé. Vous pouvez transmettre ici un objet BroadcastReceiver réel, mais ce n'est pas nécessaire, car nous allons gérer les mises à jour dans une section ultérieure.

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

Vous pouvez extraire l'état de charge actuel et, si l'appareil est en charge, déterminer si l'appareil est en charge via USB ou un chargeur:

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;

En règle générale, vous devez maximiser la fréquence de vos mises à jour en arrière-plan lorsque l'appareil est branché à un chargeur secteur, réduire la fréquence si la recharge se fait via USB et la réduire davantage si la batterie se décharge.

Surveiller les changements d'état de recharge

L'état de charge peut changer aussi facilement qu'un appareil peut être branché. Il est donc important de surveiller l'état de charge pour détecter les changements et d'ajuster votre fréquence d'actualisation en conséquence.

BatteryManager diffuse une action chaque fois que l'appareil est connecté ou déconnecté de l'alimentation. Il est important de recevoir ces événements même lorsque votre application n'est pas en cours d'exécution, d'autant plus que ces événements doivent avoir un impact sur la fréquence à laquelle vous lancez votre application lancer une mise à jour en arrière-plan. Vous devez donc enregistrer un BroadcastReceiver dans votre fichier manifeste pour écouter les deux événements en définissant ACTION_POWER_CONNECTED et ACTION_POWER_DISCONNECTED dans un filtre d'intent.

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

Déterminer le niveau actuel de la batterie

Dans certains cas, il est également utile de déterminer le niveau actuel de la batterie. Vous pouvez choisir de réduire la fréquence des mises à jour en arrière-plan si la charge de la batterie est inférieure à un certain niveau.

Vous pouvez déterminer la charge actuelle de la batterie en extrayant le niveau actuel de la batterie et la balance depuis l'intent d'état de la batterie, comme indiqué ici:

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;

Réagir aux variations importantes du niveau de la batterie

Vous ne pouvez pas surveiller facilement l'état de la batterie, mais ce n'est pas nécessaire.

De manière générale, la surveillance du niveau de la batterie a un impact plus important sur la batterie que le comportement normal de votre application. Par exemple, enregistrer un BroadcastReceiver dans le fichier manifeste pour annuler le travail en attente lorsque la batterie est faible sert principalement à décharger davantage la batterie (et est donc impossible depuis Android 8.0). Vous pouvez plutôt fournir des contraintes sur le travail qui décrivent quand il doit être exécuté, ce qui permet au système de prendre la décision sans dépenser d'énergie pour démarrer votre application.

Il est généralement recommandé de ne pas exécuter vos mises à jour en arrière-plan lorsque la batterie est à un niveau critique. Peu importe la fraîcheur de vos données si le téléphone s'éteint avant que vous puissiez les utiliser. Pour ce faire, utilisez la bibliothèque WorkManager avec une contrainte BatteryNotLow pour spécifier que la tâche ne doit pas s'exécuter si la batterie est faible (en plus des contraintes NetworkType pertinentes).

Dans de nombreux cas, le fait de charger un appareil coïncide avec le fait de le mettre sur une station d'accueil. Pour en savoir plus, consultez la section Déterminer et surveiller l'état et le type de la station d'accueil.