【Kotlin】バッテリーの残量や温度、電圧を取得

#はじめに
スマホのバッテリー情報を取得して残量、温度、電圧などを取得してみます。
バッテリー情報は**ブロードキャスト**による配信が行われていますので**IntentFilter**で受け取ります。

#開始
```sample.kt
var intentFilter : IntentFilter = IntentFilter()
        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED)
        context.registerReceiver(BatteryServiceReceiver, intentFilter)
```
#停止
```sample.kt
 context.unregisterReceiver(BatteryServiceReceiver)
```
#ブロードキャストの受け取り
**BroadcastReceiver**型のオブジェクトを使って**onReceive**メソッドを継承します。
intentのactionの値がバッテリー情報であれば処理します。

```sample.kt
    private val BatteryServiceReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == Intent.ACTION_BATTERY_CHANGED){
            }
        }
   }
```

実行すると自動的に値が更新されます。

|変数名|意味|
|:--:|:--:|
|level|バッテリーの残量を%で取得します|
|temperature|バッテリーの温度を0.1℃単位で取得します|
|voltage|バッテリー電圧を1mV単位で取得します|
|healthStr|バッテリーの健全性を返します。値を使う場合はhealthを使います。以下に同じ|
|plugStr|ACアダプタの接続状態を返します|
|statusStr|バッテリーの動作状態を返します|

#ソース
MainActivityのソースも追加しました。

```BatteryService.kt
class BatteryService(private val context: Context) {
    private var intentFilter : IntentFilter = IntentFilter()

    var level       : Int    = 0
    var temperature : Int    = 0
    var voltage     : Int    = 0
    var health      : Int    = 0
    var healthStr   : String = ""
    var plug        : Int    = 0
    var plugStr     : String = ""
    var status      : Int    = 0
    var statusStr   : String = ""

    private var listener: BatteryServiceInterface? = null
    interface Listener {}

    fun setListener(listener: Listener?) {
        if (listener is BatteryServiceInterface) this.listener = listener
    }

    fun start(){
        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED)
        context.registerReceiver(BatteryServiceReceiver, intentFilter)
    }

    fun stop(){
        context.unregisterReceiver(BatteryServiceReceiver)
    }

    private val BatteryServiceReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == Intent.ACTION_BATTERY_CHANGED){
                level       = intent.getIntExtra(BatteryManager.EXTRA_LEVEL,-1)
                temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,-1)
                voltage     = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE,-1)
                health      = intent.getIntExtra(BatteryManager.EXTRA_HEALTH,-1)
                plug        = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED,-1)
                status      = intent.getIntExtra(BatteryManager.EXTRA_STATUS,-1)
                statusToString()
            }
        }
    }

    private fun statusToString(){
        healthStr = when(health){
            BatteryManager.BATTERY_HEALTH_GOOD                -> "正常"
            BatteryManager.BATTERY_HEALTH_COLD                -> "低音異常"
            BatteryManager.BATTERY_HEALTH_DEAD                -> "故障"
            BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE        -> "電圧異常"
            BatteryManager.BATTERY_HEALTH_OVERHEAT            -> "温度異常"
            BatteryManager.BATTERY_HEALTH_UNKNOWN             -> "状態不明"
            BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE -> "未知の異常"
            else -> "不明"
        }
        plugStr = when(plug){
            BatteryManager.BATTERY_PLUGGED_AC       -> "AC接続"
            BatteryManager.BATTERY_PLUGGED_USB      -> "USB接続"
            BatteryManager.BATTERY_PLUGGED_WIRELESS -> "無線接続"
            else -> "未接続"
        }
        statusStr = when(status){
            BatteryManager.BATTERY_STATUS_CHARGING     -> "充電中"
            BatteryManager.BATTERY_STATUS_FULL         -> "充電完了"
            BatteryManager.BATTERY_STATUS_DISCHARGING  -> "消費中"
            BatteryManager.BATTERY_STATUS_NOT_CHARGING -> "未充電"
            BatteryManager.BATTERY_STATUS_UNKNOWN      -> "不明"
            else -> "不明"
        }
    }
}
```

```MainActivity.kt
class MainActivity : AppCompatActivity() {
    private val  battery = BatteryService(this)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        battery.setListener(batteryListener)
        battery.start()
    }

    private val batteryListener = object : BatteryServiceInterface{
        override fun onRead() {
            var s : String = ""
            val tv = findViewById<TextView>(R.id.tvMain)
            s += battery.level.toString() + "%\n\r"
            s += (battery.temperature / 10.0).toString() + "℃\n\r"
            s += (battery.voltage / 1000.0).toString() + "V\n\r"
            s += battery.healthStr + "\n\r"
            s += battery.plugStr + "\n\r"
            s += battery.statusStr + "\n\r"
            tv.text = s
        }
    }
}
```

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvMain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
```

#実行結果
手持ちの環境で実行したところ
100%
26.0℃
4.325V
正常
USB接続
充電完了
このように表示されました。

充電中しか処理しない、充電されていないときは警告するなどがアプリで必要になったときは役に立つと思います。