Skip to content

Instantly share code, notes, and snippets.

@webserveis
Last active May 29, 2019 16:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save webserveis/4f0c0c80834dadc9b3e8801c63109622 to your computer and use it in GitHub Desktop.
Save webserveis/4f0c0c80834dadc9b3e8801c63109622 to your computer and use it in GitHub Desktop.
Ejemplo de cómo usar la batería en Android con Kotlin
package com.webserveis.batterycheck
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.content_main.*
import kotlin.math.roundToInt
/*
https://www.baeldung.com/java-to-kotlin
adb shell dumpsys battery set level 30
https://danielme.com/2016/01/23/android-tutorial-broadcast-receiver/
https://github.com/BharathVishal/AndroidBatteryStats/blob/master/app/src/main/java/androidbatterystats/bharathvishal/com/androidbatterystats/MainActivity.kt
21> ACTION_POWER_SAVE_MODE_CHANGED
*/
class MainActivity : AppCompatActivity() {
companion object {
val TAG: String = MainActivity::class.java.simpleName
}
//private lateinit var batteryPercent: WaveLoadingView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
Log.d(TAG, "onCreate")
//batteryPercent = findViewById<WaveLoadingView>(R.id.batteryPercent)
fab.setOnClickListener { view ->
if (isPlugged(this)) {
Toast.makeText(this@MainActivity, "plugged!", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this@MainActivity, "unplugged!", Toast.LENGTH_SHORT).show()
}
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
override fun onStart() {
super.onStart()
registerReceiver(batteryChangeReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
}
override fun onStop() {
super.onStop()
unregisterReceiver(batteryChangeReceiver)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_battery_settings -> {
val intentBatteryUsage = Intent(Intent.ACTION_POWER_USAGE_SUMMARY)
startActivity(intentBatteryUsage)
true
}
else -> super.onOptionsItemSelected(item)
}
}
fun isPlugged(context: Context): Boolean {
val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
context.registerReceiver(null, ifilter)
}
//original
val plugged: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1
return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS
}
private val batteryChangeReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.i(TAG, "onReceive $intent")
/*when (intent?.action) {
Intent.ACTION_POWER_CONNECTED -> handleSomethingHappened()
}*/
val level: Int = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val batteryPct: Float = level / scale.toFloat()
val batteryInfo: BatteryInfo = BatteryInfo()
batteryInfo.status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
batteryInfo.level = batteryPct
batteryInfo.chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
batteryInfo.health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN)
batteryInfo.voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1).toFloat()
batteryInfo.temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1)
batteryInfo.technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY)
Log.d(TAG, "batteryInfo $batteryInfo")
lblBatteryStatus.text = getBatteryStatusString(batteryInfo.status)
when (batteryInfo.chargePlug) {
BatteryManager.BATTERY_PLUGGED_WIRELESS -> lblBatteryCharge.text =
getText(R.string.battery_plugged_wireless)
BatteryManager.BATTERY_PLUGGED_AC -> lblBatteryCharge.text = getText(R.string.battery_plugged_ac)
BatteryManager.BATTERY_PLUGGED_USB -> lblBatteryCharge.text = getText(R.string.battery_plugged_usb)
else -> lblBatteryCharge.text = getText(R.string.battery_in_use)
}
lblBatteryHealth.text = getBatteryHealthString(batteryInfo.health)
batteryPercent.progressValue = (batteryPct * 100).roundToInt()
batteryPercent.centerTitle = (batteryPct * 100).roundToInt().toString() + " %"
batteryPercent.setAnimDuration(3000L)
when ((batteryPct * 100).toInt()) {
in 31..100 -> batteryPercent.waveColor = ContextCompat.getColor(context!!, R.color.md_green_600)
in 11..30 -> batteryPercent.waveColor = ContextCompat.getColor(context!!, R.color.md_yellow_500)
in 0..10 -> batteryPercent.waveColor = ContextCompat.getColor(context!!, R.color.md_red_500)
}
outputText.text = null
outputText.append(
String.format(
getText(R.string.battery_terminal_status_label).toString(),
getBatteryStatusString(batteryInfo.status)
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_plugged_label).toString(),
getBatteryPluggedString(batteryInfo.chargePlug)
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_level_label).toString(),
level
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_health_label).toString(),
getBatteryHealthString(batteryInfo.health)
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_voltage_label).toString(),
batteryInfo.voltage
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_temperature_label).toString(),
(batteryInfo.temperature / 10).toFloat()
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_technology_label).toString(),
batteryInfo.technology
) + System.getProperty("line.separator")
)
}
}
private fun getBatteryStatusString(status: Int?): String {
return when (status) {
BatteryManager.BATTERY_STATUS_CHARGING -> getText(R.string.battery_status_charging).toString()
BatteryManager.BATTERY_STATUS_DISCHARGING -> getText(R.string.battery_status_discharging).toString()
BatteryManager.BATTERY_STATUS_FULL -> getText(R.string.battery_status_full).toString()
BatteryManager.BATTERY_STATUS_NOT_CHARGING -> getText(R.string.battery_status_not_charging).toString()
BatteryManager.BATTERY_STATUS_UNKNOWN -> getText(R.string.battery_status_unknown).toString()
else -> ""
}
}
private fun getBatteryPluggedString(plugged: Int?): String {
return when (plugged) {
BatteryManager.BATTERY_PLUGGED_WIRELESS -> getText(R.string.battery_plugged_wireless).toString()
BatteryManager.BATTERY_PLUGGED_AC -> getText(R.string.battery_plugged_ac).toString()
BatteryManager.BATTERY_PLUGGED_USB -> getText(R.string.battery_plugged_usb).toString()
else -> getText(R.string.battery_plugged_not).toString()
}
}
private fun getBatteryHealthString(health: Int?): String {
return when (health) {
BatteryManager.BATTERY_HEALTH_GOOD -> getText(R.string.battery_health_good).toString()
BatteryManager.BATTERY_HEALTH_COLD -> getText(R.string.battery_health_cold).toString()
BatteryManager.BATTERY_HEALTH_DEAD -> getText(R.string.battery_health_dead).toString()
BatteryManager.BATTERY_HEALTH_OVERHEAT -> getText(R.string.battery_health_overheat).toString()
BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE -> getText(R.string.battery_health_over_voltage).toString()
BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE -> getText(R.string.battery_health_unspecified_failure).toString()
else -> getText(R.string.battery_health_unknown).toString()
}
}
private fun getBatteryCapacity(ctx: Context): Long {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val mBatteryManager = ctx.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val chargeCounter = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER)
val capacity = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
val currentAvg = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_AVERAGE)
val currentNow: Long =
(mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW) / 1000)
Log.d(TAG, "chargeCounter $chargeCounter")
Log.d(TAG, "capacity $capacity")
Log.d(TAG, "CurrentAvg $currentAvg mah")
Log.d(TAG, "currentNow $currentNow mah")
return (chargeCounter.toFloat() / capacity.toFloat() * 100f).toLong()
}
return 0
}
}

Recursos de los apuntes (Crear una app en Kotlin: Analizador de bateria)[ https://dev4phones.wordpress.com/2019/05/16/crear-una-app-paso-a-paso-usando-kotlin-en-android-studio-kotlin-battery-parte1/]

1 versión: valores directos

La primera versión es obteniendo los valores directos al detectar un cambio de la bateria

2 versión: Usando un objeto propio

La segunda versión es usando un objeto que almacene los valores al detectar un cambio de estado de la batería

  • MainActivity2.kt
  • BatteryInfo.kt

3 versió: Usando viewmodel (proximamente)

La tercer versión es implmentar el patrón viewmodel así al rotar el dispositivo no sea necesario desregistrar y registrar de nuevo la escucha del cambio de la batería, solo basta con suscribirse a la obtención de datos mediante un método del viewmodel

  • MainActivity3.kt
  • BatteryInfo.kt
  • BatteryViewModel.kt
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main"
tools:context=".MainActivity"
>
<androidx.cardview.widget.CardView
android:id="@+id/cardViewBatteryStatus"
android:layout_gravity="center"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<me.itangqi.waveloadingview.WaveLoadingView
android:id="@+id/batteryPercent"
android:layout_width="128dp"
android:layout_height="128dp"
app:wlv_borderColor="@color/colorAccent"
app:wlv_borderWidth="3dp"
app:wlv_progressValue="40"
app:wlv_shapeType="circle"
app:wlv_round_rectangle="true"
app:wlv_triangle_direction="north"
app:wlv_titleCenterStrokeColor="@android:color/holo_blue_dark"
app:wlv_titleCenterStrokeWidth="3dp"
app:wlv_titleCenter="30%"
app:wlv_titleCenterColor="@android:color/white"
app:wlv_titleCenterSize="24sp"
app:wlv_waveAmplitude="50"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
/>
<TextView
tools:text="Charging..."
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
android:id="@+id/lblBatteryStatus"
app:layout_constraintStart_toEndOf="@+id/batteryPercent"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintBottom_toTopOf="@+id/lblBatteryCharge"
/>
<TextView
tools:text="usb charging"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:id="@+id/lblBatteryCharge"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/lblBatteryStatus"
app:layout_constraintStart_toEndOf="@+id/batteryPercent"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintBottom_toTopOf="@+id/lblBatteryHealth"
/>
<TextView
tools:text="goood"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
android:id="@+id/lblBatteryHealth"
app:layout_constraintTop_toBottomOf="@+id/lblBatteryCharge"
app:layout_constraintStart_toEndOf="@+id/batteryPercent"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardViewBatteryInfo"
android:layout_gravity="center"
android:layout_width="0dp"
android:layout_height="0dp"
app:cardCornerRadius="4dp"
android:padding="8dp"
android:layout_marginStart="8dp"
app:layout_constraintTop_toBottomOf="@+id/cardViewBatteryStatus"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Battery info"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:id="@+id/textView2"
/>
<TextView
android:id="@+id/outputText"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
tools:text="output text"
android:padding="8dp"
android:fontFamily="monospace"
android:background="@color/cardview_dark_background"
android:textColor="@color/md_grey_400"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.batterycheck
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.content_main.*
import kotlin.math.roundToInt
class MainActivity : AppCompatActivity() {
companion object {
val TAG: String = MainActivity::class.java.simpleName
}
//private lateinit var batteryPercent: WaveLoadingView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
Log.d(TAG, "onCreate")
}
override fun onStart() {
super.onStart()
registerReceiver(batteryChangeReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
}
override fun onStop() {
super.onStop()
unregisterReceiver(batteryChangeReceiver)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> true
else -> super.onOptionsItemSelected(item)
}
}
fun isPlugged(context: Context): Boolean {
val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
context.registerReceiver(null, ifilter)
}
//original
val plugged: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1
return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS
}
private val batteryChangeReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.i(TAG, "onReceive $intent")
/*when (intent?.action) {
Intent.ACTION_POWER_CONNECTED -> handleSomethingHappened()
}*/
val status: Int? = intent?.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
val isCharging: Boolean = status == BatteryManager.BATTERY_STATUS_CHARGING
|| status == BatteryManager.BATTERY_STATUS_FULL
lblBatteryStatus.text = getBatteryStatusString(status)
Log.d(TAG, "isCharging $isCharging")
val chargePlug: Int? = intent?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
val isPlugged: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_USB
|| status == BatteryManager.BATTERY_PLUGGED_AC
|| status == BatteryManager.BATTERY_PLUGGED_WIRELESS
val usbCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_USB
val acCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_AC
val wirelessCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_WIRELESS
when (chargePlug) {
BatteryManager.BATTERY_PLUGGED_WIRELESS -> lblBatteryCharge.text =
getText(R.string.battery_plugged_wireless)
BatteryManager.BATTERY_PLUGGED_AC -> lblBatteryCharge.text = getText(R.string.battery_plugged_ac)
BatteryManager.BATTERY_PLUGGED_USB -> lblBatteryCharge.text = getText(R.string.battery_plugged_usb)
else -> lblBatteryCharge.text = getText(R.string.battery_in_use)
}
val health: Int? = intent?.getIntExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN)
lblBatteryHealth.text = getBatteryHealthString(health)
val level: Int = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val batteryPct: Float = level / scale.toFloat()
Log.d(TAG, "batteryPct $batteryPct")
batteryPercent.progressValue = (batteryPct * 100).roundToInt()
batteryPercent.centerTitle = (batteryPct * 100).roundToInt().toString() + " %"
batteryPercent.setAnimDuration(3000L)
when ((batteryPct * 100).toInt()) {
in 31..100 -> batteryPercent.waveColor = ContextCompat.getColor(context!!, R.color.md_green_600)
in 11..30 -> batteryPercent.waveColor = ContextCompat.getColor(context!!, R.color.md_yellow_500)
in 0..10 -> batteryPercent.waveColor = ContextCompat.getColor(context!!, R.color.md_red_500)
}
val batteryVoltage: Int = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1)
val batteryTemperature: Int = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1)
val batteryTechnology: String? = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY)
Log.d(TAG, "battery voltage $batteryVoltage")
Log.d(TAG, "battery temperature $batteryTemperature")
Log.d(TAG, "battery technology $batteryTechnology")
outputText.text = null
outputText.append(
String.format(
getText(R.string.battery_terminal_status_label).toString(),
getBatteryStatusString(status)
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_plugged_label).toString(),
getBatteryPluggedString(chargePlug)
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_level_label).toString(),
level
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_health_label).toString(),
getBatteryHealthString(health)
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_voltage_label).toString(),
batteryVoltage
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_temperature_label).toString(),
(batteryTemperature / 10).toFloat()
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_technology_label).toString(),
batteryTechnology
) + System.getProperty("line.separator")
)
}
}
private fun getBatteryStatusString(status: Int?): String {
return when (status) {
BatteryManager.BATTERY_STATUS_CHARGING -> getText(R.string.battery_status_charging).toString()
BatteryManager.BATTERY_STATUS_DISCHARGING -> getText(R.string.battery_status_discharging).toString()
BatteryManager.BATTERY_STATUS_FULL -> getText(R.string.battery_status_full).toString()
BatteryManager.BATTERY_STATUS_NOT_CHARGING -> getText(R.string.battery_status_not_charging).toString()
BatteryManager.BATTERY_STATUS_UNKNOWN -> getText(R.string.battery_status_unknown).toString()
else -> ""
}
}
private fun getBatteryPluggedString(plugged: Int?): String {
return when (plugged) {
BatteryManager.BATTERY_PLUGGED_WIRELESS -> getText(R.string.battery_plugged_wireless).toString()
BatteryManager.BATTERY_PLUGGED_AC -> getText(R.string.battery_plugged_ac).toString()
BatteryManager.BATTERY_PLUGGED_USB -> getText(R.string.battery_plugged_usb).toString()
else -> getText(R.string.battery_plugged_not).toString()
}
}
private fun getBatteryHealthString(health: Int?): String {
return when (health) {
BatteryManager.BATTERY_HEALTH_GOOD -> getText(R.string.battery_health_good).toString()
BatteryManager.BATTERY_HEALTH_COLD -> getText(R.string.battery_health_cold).toString()
BatteryManager.BATTERY_HEALTH_DEAD -> getText(R.string.battery_health_dead).toString()
BatteryManager.BATTERY_HEALTH_OVERHEAT -> getText(R.string.battery_health_overheat).toString()
BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE -> getText(R.string.battery_health_over_voltage).toString()
BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE -> getText(R.string.battery_health_unspecified_failure).toString()
else -> getText(R.string.battery_health_unknown).toString()
}
}
private fun getBatteryCapacity(ctx: Context): Long {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val mBatteryManager = ctx.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val chargeCounter = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER)
val capacity = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
val currentAvg = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_AVERAGE)
val currentNow: Long =
(mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW) / 1000)
Log.d(TAG, "chargeCounter $chargeCounter")
Log.d(TAG, "capacity $capacity")
Log.d(TAG, "CurrentAvg $currentAvg mah")
Log.d(TAG, "currentNow $currentNow mah")
return (chargeCounter.toFloat() / capacity.toFloat() * 100f).toLong()
}
return 0
}
}
package com.webserveis.batterycheck
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.content_main.*
import kotlin.math.roundToInt
/*
https://www.baeldung.com/java-to-kotlin
adb shell dumpsys battery set level 30
https://danielme.com/2016/01/23/android-tutorial-broadcast-receiver/
https://github.com/BharathVishal/AndroidBatteryStats/blob/master/app/src/main/java/androidbatterystats/bharathvishal/com/androidbatterystats/MainActivity.kt
21> ACTION_POWER_SAVE_MODE_CHANGED
*/
class MainActivity : AppCompatActivity() {
companion object {
val TAG: String = MainActivity::class.java.simpleName
}
//private lateinit var batteryPercent: WaveLoadingView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
Log.d(TAG, "onCreate")
//batteryPercent = findViewById<WaveLoadingView>(R.id.batteryPercent)
fab.setOnClickListener { view ->
if (isPlugged(this)) {
Toast.makeText(this@MainActivity, "plugged!", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this@MainActivity, "unplugged!", Toast.LENGTH_SHORT).show()
}
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
override fun onStart() {
super.onStart()
registerReceiver(batteryChangeReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
}
override fun onStop() {
super.onStop()
unregisterReceiver(batteryChangeReceiver)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_battery_settings -> {
val intentBatteryUsage = Intent(Intent.ACTION_POWER_USAGE_SUMMARY)
startActivity(intentBatteryUsage)
true
}
else -> super.onOptionsItemSelected(item)
}
}
fun isPlugged(context: Context): Boolean {
val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
context.registerReceiver(null, ifilter)
}
//original
val plugged: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1
return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS
}
private val batteryChangeReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.i(TAG, "onReceive $intent")
/*when (intent?.action) {
Intent.ACTION_POWER_CONNECTED -> handleSomethingHappened()
}*/
val level: Int = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val batteryPct: Float = level / scale.toFloat()
val batteryInfo: BatteryInfo = BatteryInfo()
batteryInfo.status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
batteryInfo.level = batteryPct
batteryInfo.chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
batteryInfo.health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN)
batteryInfo.voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1).toFloat()
batteryInfo.temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1)
batteryInfo.technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY)
Log.d(TAG, "batteryInfo $batteryInfo")
lblBatteryStatus.text = getBatteryStatusString(batteryInfo.status)
when (batteryInfo.chargePlug) {
BatteryManager.BATTERY_PLUGGED_WIRELESS -> lblBatteryCharge.text =
getText(R.string.battery_plugged_wireless)
BatteryManager.BATTERY_PLUGGED_AC -> lblBatteryCharge.text = getText(R.string.battery_plugged_ac)
BatteryManager.BATTERY_PLUGGED_USB -> lblBatteryCharge.text = getText(R.string.battery_plugged_usb)
else -> lblBatteryCharge.text = getText(R.string.battery_in_use)
}
lblBatteryHealth.text = getBatteryHealthString(batteryInfo.health)
batteryPercent.progressValue = (batteryPct * 100).roundToInt()
batteryPercent.centerTitle = (batteryPct * 100).roundToInt().toString() + " %"
batteryPercent.setAnimDuration(3000L)
when ((batteryPct * 100).toInt()) {
in 31..100 -> batteryPercent.waveColor = ContextCompat.getColor(context!!, R.color.md_green_600)
in 11..30 -> batteryPercent.waveColor = ContextCompat.getColor(context!!, R.color.md_yellow_500)
in 0..10 -> batteryPercent.waveColor = ContextCompat.getColor(context!!, R.color.md_red_500)
}
outputText.text = null
outputText.append(
String.format(
getText(R.string.battery_terminal_status_label).toString(),
getBatteryStatusString(batteryInfo.status)
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_plugged_label).toString(),
getBatteryPluggedString(batteryInfo.chargePlug)
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_level_label).toString(),
level
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_health_label).toString(),
getBatteryHealthString(batteryInfo.health)
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_voltage_label).toString(),
batteryInfo.voltage
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_temperature_label).toString(),
(batteryInfo.temperature / 10).toFloat()
) + System.getProperty("line.separator")
)
outputText.append(
String.format(
getText(R.string.battery_terminal_technology_label).toString(),
batteryInfo.technology
) + System.getProperty("line.separator")
)
}
}
private fun getBatteryStatusString(status: Int?): String {
return when (status) {
BatteryManager.BATTERY_STATUS_CHARGING -> getText(R.string.battery_status_charging).toString()
BatteryManager.BATTERY_STATUS_DISCHARGING -> getText(R.string.battery_status_discharging).toString()
BatteryManager.BATTERY_STATUS_FULL -> getText(R.string.battery_status_full).toString()
BatteryManager.BATTERY_STATUS_NOT_CHARGING -> getText(R.string.battery_status_not_charging).toString()
BatteryManager.BATTERY_STATUS_UNKNOWN -> getText(R.string.battery_status_unknown).toString()
else -> ""
}
}
private fun getBatteryPluggedString(plugged: Int?): String {
return when (plugged) {
BatteryManager.BATTERY_PLUGGED_WIRELESS -> getText(R.string.battery_plugged_wireless).toString()
BatteryManager.BATTERY_PLUGGED_AC -> getText(R.string.battery_plugged_ac).toString()
BatteryManager.BATTERY_PLUGGED_USB -> getText(R.string.battery_plugged_usb).toString()
else -> getText(R.string.battery_plugged_not).toString()
}
}
private fun getBatteryHealthString(health: Int?): String {
return when (health) {
BatteryManager.BATTERY_HEALTH_GOOD -> getText(R.string.battery_health_good).toString()
BatteryManager.BATTERY_HEALTH_COLD -> getText(R.string.battery_health_cold).toString()
BatteryManager.BATTERY_HEALTH_DEAD -> getText(R.string.battery_health_dead).toString()
BatteryManager.BATTERY_HEALTH_OVERHEAT -> getText(R.string.battery_health_overheat).toString()
BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE -> getText(R.string.battery_health_over_voltage).toString()
BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE -> getText(R.string.battery_health_unspecified_failure).toString()
else -> getText(R.string.battery_health_unknown).toString()
}
}
private fun getBatteryCapacity(ctx: Context): Long {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val mBatteryManager = ctx.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val chargeCounter = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER)
val capacity = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
val currentAvg = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_AVERAGE)
val currentNow: Long =
(mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW) / 1000)
Log.d(TAG, "chargeCounter $chargeCounter")
Log.d(TAG, "capacity $capacity")
Log.d(TAG, "CurrentAvg $currentAvg mah")
Log.d(TAG, "currentNow $currentNow mah")
return (chargeCounter.toFloat() / capacity.toFloat() * 100f).toLong()
}
return 0
}
}
<resources>
<string name="app_name">Battery Check</string>
<string name="action_settings">Settings</string>
<string name="battery_status_charging">Charging</string>
<string name="battery_status_discharging">Discharging</string>
<string name="battery_status_full">Full</string>
<string name="battery_status_not_charging">Not charging</string>
<string name="battery_status_unknown">Unknown</string>
<string name="battery_plugged_ac">Plugged AC</string>
<string name="battery_plugged_usb">USB charge</string>
<string name="battery_plugged_wireless">Wireless charge</string>
<string name="battery_plugged_not">Not plugged</string>
<string name="battery_in_use">Battery in use</string>
<string name="battery_health_cold">Cold</string>
<string name="battery_health_dead">Dead</string>
<string name="battery_health_good">Good</string>
<string name="battery_health_overheat">Overheat</string>
<string name="battery_health_over_voltage">Over voltage</string>
<string name="battery_health_unknown">Unknown</string>
<string name="battery_health_unspecified_failure">Unspecified failure</string>
<string name="battery_terminal_status_label">Status: %s</string>
<string name="battery_terminal_plugged_label">Power plug: %s</string>
<string name="battery_terminal_level_label">Level: %d%%</string>
<string name="battery_terminal_health_label">Health: %s</string>
<string name="battery_terminal_voltage_label">Current voltage: %d</string>
<string name="battery_terminal_temperature_label">Temperature: %.1fºC</string>
<string name="battery_terminal_technology_label">Technology: %s</string>
</resources>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment