電池残量と充電状態を監視する

バックグラウンド更新の頻度を変更して、それらの更新によるバッテリー駆動時間への影響を軽減する場合は、まず現在のバッテリー レベルと充電状態を確認することをおすすめします。

アプリケーション アップデートの実行がバッテリー寿命に及ぼす影響は、デバイスのバッテリー レベルと充電状態によって異なります。デバイスが AC 充電しているときにアップデートを実行することの影響はわずかであるため、ほとんどの場合、デバイスがウォール チャージャーに接続されているときはリフレッシュ レートを最大にすることができます。逆に、デバイスが放電している場合は、アップデート レートを下げるとバッテリーの寿命を延ばすことができます。

同様に、バッテリーの充電レベルを確認することもできます。バッテリーの残量がなくなりそうになった場合に、アップデートの頻度を減らす(または停止する)可能性があります。

現在の充電状態を特定する

初めに現在の充電状態を特定します。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 経由で充電しているか AC チャージャー経由で充電しているかを抽出できます。

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;

通常、デバイスが AC 充電器に接続されている場合はバックグラウンド更新のレートを最大にし、USB での充電の場合はレートを下げ、バッテリーが放電している場合はさらにレートを下げます。

充電状態の変化を監視する

充電状態はデバイスを電源に接続すれば簡単に変化するため、充電状態の変化を監視し、それに応じてリフレッシュ レートを変更することが重要です。

BatteryManager は、デバイスが電源に接続されるか切断されるたびに、アクションをブロードキャストします。アプリが実行されていない場合でも、これらのイベントを受信することが重要です。特に、これらのイベントはバックグラウンド アップデートを開始するためにアプリを起動する頻度に影響するため、マニフェストに BroadcastReceiver を登録して、インテント フィルタ内で ACTION_POWER_CONNECTEDACTION_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 以降では不可能です)。代わりに、処理の実行タイミングを記述する制約を処理に指定することで、アプリの起動に電力を消費することなく、システムが決定を下せるようにします。

一般的に、バッテリー残量が非常に低下しているときは、バックグラウンド アップデートを実行しないことをおすすめします。スマートフォンの電源がオフになってから使用できる場合、データの更新頻度は関係ありません。そのためには、BatteryNotLow 制約付きの WorkManager ライブラリを使用して、(関連する NetworkType 制約に加えて)バッテリー残量が少ない場合に処理を実行しないように指定します。

多くの場合、デバイスの充電動作はデバイスをホルダーに置くのと同時に行われます。詳しくは、装着状態とタイプを特定してモニタリングするをご覧ください。