You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin实现低电量弹窗、插电自动关闭弹窗的开发问题咨询

功能需求
  • 设备电量低于20%时弹出低电量提示对话框
  • 设备连接充电器时展示对应提示对话框,无需用户点击操作即可自动关闭
  • 设备断开充电器时若电量低于20%重新弹出低电量提示
现有代码问题
  1. 每次调用对话框方法都会重新 inflate 布局、创建新的 Dialog 实例,全局持有 dialog 引用失效,无法正常关闭已弹出的对话框
  2. 仅监听了充电插拔广播,未监听电量变化广播,电量自然掉到20%以下时无法触发提示
  3. 连接充电器时的自动关闭逻辑未实现
  4. 对话框 show 判断逻辑错误,原代码写的是if(d.isShowing) d.show(),刚好写反了
完整修正实现

1. BaseActivity.kt 代码修正

open class BaseActivity : AppCompatActivity() {
    // 全局复用Dialog实例
    private var batteryDialog: AlertDialog? = null
    private val autoDismissDelay = 3000L // 充电提示自动关闭时长3秒

    /**
     * 展示电量相关对话框
     * @param show 是否展示
     * @param message 对话框提示文案
     * @param autoDismiss 是否需要自动关闭
     */
    fun showBatteryDialog(show: Boolean, message: String, autoDismiss: Boolean = false) {
        if (show) {
            // 已显示的话只更新文案即可
            if (batteryDialog?.isShowing == true) {
                batteryDialog?.findViewById<TextView>(R.id.txtViewDescription)?.text = message
            } else {
                // 首次创建
                val dialogView = layoutInflater.inflate(R.layout.dialog_battery_low, null)
                batteryDialog = AlertDialog.Builder(this@BaseActivity)
                    .setView(dialogView)
                    .setCancelable(false)
                    .create()
                batteryDialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
                dialogView.txtViewDescription.text = message
                dialogView.txtViewOk.setOnClickListener {
                    finishAffinity()
                }
                batteryDialog?.show()
            }
            // 需要自动关闭的话发延迟任务
            if (autoDismiss) {
                batteryDialog?.window?.decorView?.postDelayed({
                    dismissBatteryDialog()
                }, autoDismissDelay)
            }
        } else {
            dismissBatteryDialog()
        }
    }

    /**
     * 关闭电量对话框
     */
    fun dismissBatteryDialog() {
        batteryDialog?.takeIf { it.isShowing }?.dismiss()
        batteryDialog = null
    }

    override fun onDestroy() {
        super.onDestroy()
        // 页面销毁时关闭对话框避免内存泄漏
        dismissBatteryDialog()
    }
}

2. MainActivity.kt 广播相关代码修正

class MainActivity : BaseActivity() {
    private val mBatteryReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val bm = context.getSystemService(Application.BATTERY_SERVICE) as BatteryManager
            val batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)

            when (intent.action) {
                // 充电连接
                Intent.ACTION_POWER_CONNECTED -> {
                    Toast.makeText(context, "Power connected", Toast.LENGTH_SHORT).show()
                    showBatteryDialog(
                        show = true,
                        message = "充电器已连接",
                        autoDismiss = true
                    )
                }
                // 充电断开
                Intent.ACTION_POWER_DISCONNECTED -> {
                    Toast.makeText(context, "Power disconnected", Toast.LENGTH_SHORT).show()
                    if (batLevel < 20) {
                        showBatteryDialog(
                            show = true,
                            message = "您的手机电量过低"
                        )
                    } else {
                        dismissBatteryDialog()
                    }
                }
                // 电量变化
                Intent.ACTION_BATTERY_CHANGED -> {
                    // 未充电且电量低于20%才弹低电量提示
                    val isCharging = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1) == 
                        BatteryManager.BATTERY_STATUS_CHARGING
                    if (!isCharging && batLevel < 20) {
                        showBatteryDialog(
                            show = true,
                            message = "您的手机电量过低"
                        )
                    } else if (batLevel >= 20) {
                        dismissBatteryDialog()
                    }
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 动态注册广播
        val filter = IntentFilter().apply {
            addAction(Intent.ACTION_POWER_CONNECTED)
            addAction(Intent.ACTION_POWER_DISCONNECTED)
            addAction(Intent.ACTION_BATTERY_CHANGED)
        }
        registerReceiver(mBatteryReceiver, filter)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 解绑广播避免内存泄漏
        unregisterReceiver(mBatteryReceiver)
    }
}
关键优化点
  • 全局复用同一个Dialog实例,避免创建多个实例导致无法正常关闭
  • 新增电量变化广播监听,覆盖电量自然耗到阈值的场景
  • 新增自动关闭逻辑,充电连接的提示3秒后自动消失
  • 修复原代码对话框显示判断逻辑错误的问题
  • 增加页面销毁时的资源回收逻辑,避免内存泄漏

内容的提问来源于stack exchange,提问作者Piyush Savalia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 11:27:05