Register now for Android Dev Summit 2019!

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

バッテリー寿命への影響を抑えるためにバックグラウンド アップデートの頻度を変更する場合は、初めに現在のバッテリー レベルと充電状態を確認することをおすすめします。

アプリケーション アップデートの実行がバッテリー寿命に及ぼす影響は、デバイスのバッテリー レベルと充電状態によって異なります。デバイスが 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>

関連付けられた BroadcastReceiver 実装内で、前のステップで説明したように現在の充電状態および方法を抽出できます。

Kotlin

    class PowerConnectionReceiver : BroadcastReceiver() {

        override fun onReceive(context: Context, intent: Intent) {
            val status: Int = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
            val isCharging: Boolean = status == BatteryManager.BATTERY_STATUS_CHARGING
                    || status == BatteryManager.BATTERY_STATUS_FULL

            val chargePlug: Int = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
            val usbCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_USB
            val acCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_AC
        }
    }
    

Java

    public class PowerConnectionReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                                status == BatteryManager.BATTERY_STATUS_FULL;

            int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
            boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
            boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
        }
    }
    

現在のバッテリー レベルを特定する

現在のバッテリー レベルを特定すると役に立つ場合もあります。バッテリーの充電が一定のレベルを下回った場合にバックグラウンド アップデートのレートを下げることができます。

現在のバッテリーの充電を調べるには、次に示すように、現在のバッテリー レベルと段階をバッテリー ステータス インテントから抽出します。

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 / scale.toFloat()
    }
    

Java

    int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
    int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

    float batteryPct = level / (float)scale;
    

バッテリー レベルの大きな変化を監視する

バッテリーの状態を継続的に監視することは簡単ではなく、また監視する必要もありません。

一般的に、バッテリー レベルを絶えず監視することのバッテリーへの影響はアプリの通常の動作よりも大きいため、バッテリー レベルの大きな変化のみを監視することをおすすめします。特に、デバイスがバッテリー残量の低下状態になったときやその状態が解消されたときです。

次に示すマニフェストのスニペットは、ブロードキャスト レシーバー内のインテント フィルタ要素から抽出されたものです。レシーバーは、ACTION_BATTERY_LOWACTION_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>

一般的に、バッテリーが非常に低下しているときは、バックグラウンド アップデートをすべて無効にすることをおすすめします。スマートフォンの電源が切れて使用できなくなるような場合に、データの新しさは関係ありません。

多くの場合、デバイスの充電動作はデバイスをホルダーに置くのと同時に行われます。次のレッスンでは、現在のホルダー状態を特定し、デバイスの装着の変化を監視する方法について説明します。