Android Kotlin: How to get battery capacity programmatically

The code defines an extension property for the Context class that retrieves the battery capacity of the device. The property utilizes reflection to access the private PowerProfile class, which is part of the Android internal APIs. This class provides methods for retrieving information about the device's battery, such as its capacity.

Here's a step-by-step breakdown of the code:

  1. Import Statements:

    • The code starts by importing necessary classes like Context, Bundle, AppCompatActivity, and kotlinx.android.synthetic.main.activity_main
  2. MainActivity Class:

    • The MainActivity class inherits from AppCompatActivity, which is the base class for activities in Android applications.
    • The onCreate() method is the entry point of the activity. It's called when the activity is first created.
      • Inside the onCreate() method:
        • The setContentView(R.layout.activity_main) line sets the layout for the activity.
        • The applicationContext.batteryCapacity?.apply { ... } block retrieves the battery capacity using the extension property and displays it on the text view if the value is not null.
  3. Extension Property for Battery Capacity:

    • The val Context.batteryCapacity: Double? extension property is defined to get the battery capacity of the device.
    • It uses reflection to access the private PowerProfile class and its getAveragePower method to retrieve the battery capacity in mAh.
    • The code catches any exceptions that might occur during reflection.
  4. Layout File (activity_main.xml):

    • The activity_main.xml file defines the layout for the activity.
    • It includes a TextView control to display the battery capacity.

Summary

This code snippet demonstrates how to programmatically retrieve the battery capacity of an Android device using Kotlin. It leverages reflection to access the internal PowerProfile class. Be aware that using reflection can introduce potential security risks and issues with future compatibility, as internal classes are subject to change across Android versions. It's recommended to explore alternative approaches provided by the Android framework whenever possible.


MainActivity.kt

package com.example.jetpack

import android.content.Context
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // get battery capacity and show it on text view
        applicationContext.batteryCapacity?.apply {
            textView.text = "Battery Capacity\n${this.toInt()} mAh"
        }
    }
}


// extension property to get battery capacity
val Context.batteryCapacity:Double?
    get() {
        val powerProfileClass = "com.android.internal.os.PowerProfile"
        try {
            (Class.forName(powerProfileClass).getConstructor(Context::class.java)
                .newInstance(this)).apply {

                    return Class.forName(powerProfileClass)
                        .getMethod("getAveragePower", String::class.java)
                        .invoke(this, "battery.capacity") as Double
                }

        }catch (e: Exception){
            e.printStackTrace()
        }
        return null
    }
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:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#EDEAE0"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:fontFamily="sans-serif-condensed"
        android:gravity="center"
        android:padding="32dp"
        android:textColor="#0014A8"
        android:textSize="35sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.25"
        tools:text="TextView" />

</androidx.constraintlayout.widget.ConstraintLayout>
More android kotlin tutorials