用 Androidx + 蓝牙HC05 点灯(2): Handler 掌舵人 和 Thread 线人,逮着蓝牙老大说黑话:此灯为我开,101011...

本文介绍了使用Androidx通过Handler和Thread处理蓝牙HC05的连接,修复了密码输入漏洞,详细阐述了蓝牙的捆绑、连接、点灯操作,并探讨了异步点灯方法及UUID开关的实验,最终实现稳定的蓝牙控制。

🐉0、简介

  • 更新填补上一章的漏洞(😎:咱有始有终。)
  • 雇佣哥俩好:大哥是 Handler 掌舵人,(😃:瞧这名字开真威风!久仰久仰。)二哥是 Thread 线人。(😑:那里来的二五仔?)
  • 联络蓝牙大哥,因为还没有开灯嘛!(蓝牙🦄:叽里咕噜…😅:尽是黑话,跑龙套的初哥那去了?没办法,我来翻译翻译。)

🐰1、更新:密码无人输入的漏洞

有的朋友可能会发现,在发现蓝牙后,新蓝牙机要输入密码。但是无人输入密码的话,30 至 40 秒之间,页面就会自动关闭。这个 App 还会停留在 Bonding 阶段。
BleHc05Observer:

                ACTION_BOND_STATE_CHANGED -> {
                    lgd(tag + "Checking Bonded State...")
                    val device: BluetoothDevice =
                            intent.getParcelableExtra<Parcelable>(
                                    EXTRA_DEVICE
                            ) as BluetoothDevice

                    when (device.bondState) {
                        BOND_BONDED -> {
                            lgd("$tag Bonded to device")
                            devStatus.postValue(BONDED)
                        }
                        BOND_BONDING -> {
                            lgd("$tag Bonding to device")
                            // 什么都没有,卡!
                        }
                        BOND_NONE -> {
                            lge("$tag Nothing has bonded.")
                            devStatus.postValue(FAIL)
                        }
                    }
                }

结果:
在这里插入图片描述
🙄:在 bonding 加料。

                        BOND_BONDING -> {
                            lgd("$tag Bonding to device")
                            devStatus.postValue(BONDING)
                        }

设定是新机就加个时限,没人输入密码就跳到 FAIL。我还加了显示倒数功能。
countdown
MainActivity:瞧瞧,咱这个MVVM 好啊!现在指令一目了然,逻辑的事 ViewModel 都帮我干了。😭老子在 MVC 的那里可是乱啊,又当爹又当妈的、、、

    //region vars:
    ...
    private val counterTV: TextView by
        lazy { findViewById(R.id.counterTV) }
    ...

    private var newDevice = false
    private var counter = 0
    private var bonded = false
    //endregion
    ...
》》》在 **onCreate()** 里面:
        mainVM.deviceStatus.observe(
                this,
                { status ->
                    when (status) {
                        ...
                        PAIRING -> {
                            val info = "Searching Bonded List..."
                            infoTV.text = info
                            progressBar.visibility = View.VISIBLE
                            mainVM.checkBondedList()
                        }
                        DISCOVERING -> {
                            val info = "Discovering device in range..."
                            infoTV.text = info
                            progressBar.visibility = View.VISIBLE
                            newDevice = true
                            mainVM.discovering()
                        }
                        BONDING -> {
                            val info = "Device Found in Record!\nBonding..."
                            infoTV.text = info
                            if (newDevice)
                                mainVM.checkNewDevice()
                            else
                                mainVM.bonding()
                        }
                        DISCOVERED -> {
                            val pass = "Your Pass: ${ConfigHelper.getPass()}"
                            discoveryTV.text = pass
                            discoveryTV.visibility = View.VISIBLE
                        }
                        BONDED -> {
                            lgd("MainAct: Bonded successful!")
                            counterTV.visibility = View.GONE
                            counter = 0
                            bonded = true
                            discoveryTV.text = ""
                            discoveryTV.visibility = View.GONE
                            progressBar.visibility = View.GONE

                            val info = "Bonded to $DEVICE_NAME."
                            infoTV.text = info
                            msg(this, info, 1)
                            mainVM.connected()
                        }
                        CONNECTED -> {
                            val info = "Device connected..."
                            infoTV.text = info
                            onBT.visibility = View.VISIBLE
                            progressBar.visibility = View.GONE
                        }
                        FAIL -> {
                            counter = 0
                            counterTV.visibility = View.GONE
                            val info = "FAIL to create connection!" +
                                    "\nOr\nPassword is incorrect!"
                            infoTV.text = info
                            discoveryTV.visibility = View.GONE
                            progressBar.visibility = View.GONE
                            tryAgainBT.visibility = View.VISIBLE
                        }
                        NOT_FOUND -> {
                            lgd("MainAct: Device Not Found.")
                            progressBar.visibility = View.GONE
                            val info = "Device NOT Found!"
                            infoTV.setTextColor(Color.RED)
                            infoTV.text = info
                            msg(this, info, 1)
                        }
                        COUNT_DOWN -> {
                            if (!bonded) {
                                counterTV.visibility = View.VISIBLE
                                val down = 35 - counter
                                counter++
                                val timer = "35s to Enter Password: $down"
                                counterTV.text = timer
                            }
                        }
                        ...

➕ COUNT_DOWN 进 DeviceStatus

enum class DeviceStatus {
    PAIRING, BONDING, DISCOVERING, SWITCHING,
    DISCOVERED, BONDED, CONNECTED,
    FAIL, DISCONNECT, NOT_FOUND, COUNT_DOWN
}

那个 MainViewModel 当然要改啦:

    fun bonding() {
        val result = bleHelper.checkDeviceBonding()
        lgd("$tag Bonding...$result")

        if (result) {
            deviceStatus.postValue(CONNECTED)
            //bleHelper.discoverService()
        } else {
            deviceStatus.postValue(FAIL)
        }
    }
    ...
    fun checkNewDevice() {
        // new password entry timeout is 40s
        viewModelScope.launch {
            repeat(40) {
                deviceStatus.postValue(COUNT_DOWN)
                delay(SEC)
            }
            if (!bleHelper.checkBondedList()) {
                lgd("Check Bonded List.")
                deviceStatus.postValue(FAIL)
            }
        }
    }

这里 SEC = 1000L;方程用的是 Coroutines,异步程序。我设定 40秒 内去 COUNT_DOWN 跳数字;40 秒后,蓝牙没有上榜的话就跳去 FAIL。写完,Ctrl+K,上传。开始测。
test
不错不错,能够显示 FAIL 部分。


👨‍❤️‍👨2. 创建两兄弟:Handler 掌舵人 和 Thread 线人

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值