android: listen for battery in the connected popup window (fix #117)

This commit is contained in:
Kavish Devar
2025-05-09 09:47:54 +05:30
parent 295c49fdc6
commit 7ffcd68ad9

View File

@@ -24,8 +24,12 @@ import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder import android.animation.PropertyValuesHolder
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.PixelFormat import android.graphics.PixelFormat
import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Log import android.util.Log
@@ -51,6 +55,7 @@ class PopupWindow(
private var isClosing = false private var isClosing = false
private var autoCloseHandler = Handler(Looper.getMainLooper()) private var autoCloseHandler = Handler(Looper.getMainLooper())
private var autoCloseRunnable: Runnable? = null private var autoCloseRunnable: Runnable? = null
private var batteryUpdateReceiver: BroadcastReceiver? = null
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
private val mParams: WindowManager.LayoutParams = WindowManager.LayoutParams().apply { private val mParams: WindowManager.LayoutParams = WindowManager.LayoutParams().apply {
@@ -146,6 +151,8 @@ class PopupWindow(
start() start()
} }
registerBatteryUpdateReceiver()
autoCloseRunnable = Runnable { close() } autoCloseRunnable = Runnable { close() }
autoCloseHandler.postDelayed(autoCloseRunnable!!, 12000) autoCloseHandler.postDelayed(autoCloseRunnable!!, 12000)
} }
@@ -155,15 +162,43 @@ class PopupWindow(
} }
} }
@SuppressLint("SetTextI18n") private fun registerBatteryUpdateReceiver() {
fun updateBatteryStatus(batteryNotification: AirPodsNotifications.BatteryNotification) { batteryUpdateReceiver = object : BroadcastReceiver() {
val batteryStatus = batteryNotification.getBattery() override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == AirPodsNotifications.BATTERY_DATA) {
val batteryList = intent.getParcelableArrayListExtra<Battery>("data")
if (batteryList != null) {
updateBatteryStatusFromList(batteryList)
}
}
}
}
val filter = IntentFilter(AirPodsNotifications.BATTERY_DATA)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
context.registerReceiver(batteryUpdateReceiver, filter, Context.RECEIVER_EXPORTED)
} else {
context.registerReceiver(batteryUpdateReceiver, filter)
}
}
private fun unregisterBatteryUpdateReceiver() {
batteryUpdateReceiver?.let {
try {
context.unregisterReceiver(it)
batteryUpdateReceiver = null
} catch (e: Exception) {
Log.e("PopupWindow", "Error unregistering battery receiver: ${e.message}")
}
}
}
private fun updateBatteryStatusFromList(batteryList: List<Battery>) {
val batteryLeftText = mView.findViewById<TextView>(R.id.left_battery) val batteryLeftText = mView.findViewById<TextView>(R.id.left_battery)
val batteryRightText = mView.findViewById<TextView>(R.id.right_battery) val batteryRightText = mView.findViewById<TextView>(R.id.right_battery)
val batteryCaseText = mView.findViewById<TextView>(R.id.case_battery) val batteryCaseText = mView.findViewById<TextView>(R.id.case_battery)
batteryLeftText.text = batteryStatus.find { it.component == BatteryComponent.LEFT }?.let { batteryLeftText.text = batteryList.find { it.component == BatteryComponent.LEFT }?.let {
if (it.status != BatteryStatus.DISCONNECTED) { if (it.status != BatteryStatus.DISCONNECTED) {
"\uDBC3\uDC8E ${it.level}%" "\uDBC3\uDC8E ${it.level}%"
} else { } else {
@@ -171,7 +206,7 @@ class PopupWindow(
} }
} ?: "" } ?: ""
batteryRightText.text = batteryStatus.find { it.component == BatteryComponent.RIGHT }?.let { batteryRightText.text = batteryList.find { it.component == BatteryComponent.RIGHT }?.let {
if (it.status != BatteryStatus.DISCONNECTED) { if (it.status != BatteryStatus.DISCONNECTED) {
"\uDBC3\uDC8D ${it.level}%" "\uDBC3\uDC8D ${it.level}%"
} else { } else {
@@ -179,7 +214,7 @@ class PopupWindow(
} }
} ?: "" } ?: ""
batteryCaseText.text = batteryStatus.find { it.component == BatteryComponent.CASE }?.let { batteryCaseText.text = batteryList.find { it.component == BatteryComponent.CASE }?.let {
if (it.status != BatteryStatus.DISCONNECTED) { if (it.status != BatteryStatus.DISCONNECTED) {
"\uDBC3\uDE6C ${it.level}%" "\uDBC3\uDE6C ${it.level}%"
} else { } else {
@@ -188,12 +223,19 @@ class PopupWindow(
} ?: "" } ?: ""
} }
@SuppressLint("SetTextI18s")
fun updateBatteryStatus(batteryNotification: AirPodsNotifications.BatteryNotification) {
val batteryStatus = batteryNotification.getBattery()
updateBatteryStatusFromList(batteryStatus)
}
fun close() { fun close() {
try { try {
if (isClosing) return if (isClosing) return
isClosing = true isClosing = true
autoCloseRunnable?.let { autoCloseHandler.removeCallbacks(it) } autoCloseRunnable?.let { autoCloseHandler.removeCallbacks(it) }
unregisterBatteryUpdateReceiver()
val vid = mView.findViewById<VideoView>(R.id.video) val vid = mView.findViewById<VideoView>(R.id.video)
vid.stopPlayback() vid.stopPlayback()