uni-app H5+API【蓝牙】安卓机写入数据后监听不到特征值的变化

uni-app H5+API【蓝牙】安卓机写入数据后监听不到特征值的变化

开发环境 版本号 项目创建方式
HBuilderX 3.1.11
产品分类:HTML5+

手机系统:Android  
手机系统版本号:Android 10  
手机厂商:小米  
手机机型:mi8  
打包方式:云端  

### 示例代码:

```javascript
<script type="text/javascript" charset="utf-8">  
    function ab2hex(buffer) {  
      var hexArr = Array.prototype.map.call(  
        new Uint8Array(buffer),  
        function (bit) {  
          return ('00' + bit.toString(16)).slice(-2)  
        }  
      )  
      return hexArr.join('');  
    }  

    function str2ab(str){  
      var buffer = new ArrayBuffer(str.length)  
      var dataView = new DataView(buffer)  
      for (let i = 0; i < str.length; i++) {  
        dataView.setInt8(i, str.charCodeAt(i))  
      }  
      return buffer  
    }  

    mui.init();  
    mui.plusReady(function() {  
        characteristicValueChange();  

        var deviceId = '',serviceId = '', writeCharacteristic='0000FFF5-0000-1000-8000-00805F9B34FB';  

        // 点击初始化蓝牙模块  
        const initDom = document.getElementById('init')  
        initDom.onclick = function() {  
            plus.bluetooth.openBluetoothAdapter({  
                success(s) {  
                    console.log('初始化蓝牙模块成功')  
                },  
                fail(f) {  
                    console.log('初始化蓝牙模块失败' + JSON.stringify(f))  
                }  
            })  
        }  

        // 点击扫描设备  
        const searchDom = document.getElementById('search')  
        searchDom.onclick = function() {  
            plus.bluetooth.startBluetoothDevicesDiscovery({  
                services: ['FFF0'],  
                success(s) {  
                    console.log('开始扫描')  
                    onBluetoothFound()  
                },  
                fail(f) {  
                    console.log('开启扫描失败'+JSON.stringify(f))  
                }  
            })  
        }  

        // 点击连接设备  
        const ulDom = document.getElementById('devices-ul')  
        ulDom.addEventListener('click', ev => {  
            if(ev.target && ev.target.nodeName.toLowerCase() == 'li'){  
                deviceId = ev.target.getAttribute('id')  
                connectionBluetooth(deviceId)  
            }  
        })  

        // 点击写入数据  
        const sendDom = document.getElementById('sendValue')  
        sendDom.onclick = function (){  
            const value = document.getElementById('value').value  
            if(value){  
                const wValue = str2ab(value)  
                plus.bluetooth.writeBLECharacteristicValue({  
                    deviceId: deviceId,  
                    serviceId: serviceId,  
                    characteristicId: writeCharacteristic,  
                    value: wValue,  
                    success(s) {  
                        console.log('写入成功' + JSON.stringify(s))  
                    },  
                    fail(f) {  
                        console.log('写入失败' + JSON.stringify(f))  
                    }  
                })  
            }  
        }  

        // 监听/主动调用发现设备  
        function onBluetoothFound(){  
            plus.bluetooth.onBluetoothDeviceFound(res => {  
                res.devices.forEach(device => {  
                    if(!device.name || !device.localName){  
                        return  
                    }  
                    if(document.getElementById(device.deviceId) == null){  
                        console.log('发现设备' + JSON.stringify(device))  
                        var liDom = document.createElement('li')  
                        liDom.setAttribute('id', device.deviceId)  
                        liDom.innerHTML = device.name  
                        document.getElementById('devices-ul').appendChild(liDom)  
                    }  
                })  
            })  
        }  

        // 连接蓝牙  
        function connectionBluetooth(deviceId){  
            plus.bluetooth.createBLEConnection({  
                deviceId: deviceId,  
                success(s) {  
                    console.log('蓝牙设备连接成功')  
                    // 获取服务  
                    setTimeout(getService, 1500);  
                }  
            })  
            // 关闭搜索  
            stopSearch()  
        }  

        // 获取服务  
        function getService(){  
            console.log(deviceId)  
            plus.bluetooth.getBLEDeviceServices({  
                deviceId: deviceId,  
                success(s) {  
                    console.log('获取服务成功' + JSON.stringify(s))  
                    serviceId = '0000FFF0-0000-1000-8000-00805F9B34FB'  
                    getCharacteristics(deviceId, serviceId)  
                },  
                fail(f) {  
                    console.log('获取服务失败' + JSON.stringify(f))  
                }  
            })  
        }  

        // 获取特征值  
        function getCharacteristics(deviceId, serviceId){  
            plus.bluetooth.getBLEDeviceCharacteristics({  
                deviceId: deviceId,  
                serviceId: serviceId,  
                success(s){  
                    console.log('获取特征值成功' + JSON.stringify(s))  
                    // 订阅 notify 特征值  
                    s.characteristics.forEach(characteristic => {  
                        if(characteristic.properties.notify || characteristic.properties.indicate){  
                            if(characteristic.uuid != writeCharacteristic){  
                                plus.bluetooth.notifyBLECharacteristicValueChange({  
                                    state: true,  
                                    deviceId: deviceId,  
                                    serviceId: serviceId,  
                                    characteristicId: characteristic.uuid,  
                                    success(s) {  
                                        console.log('特征值订阅成功:' + characteristic.uuid)  
                                    },  
                                    fail(f) {  
                                        console.log('特征值订阅失败' + JSON.stringify(f))  
                                    }  
                                })  
                            }  
                        }  
                    })  
                },  
                fail(f) {  
                    console.log('获取特征值失败' + JSON.stringify(f))  
                }  
            })  
        }  

        // 特征值变化  
        function characteristicValueChange(){  
            console.log('监听特征值了哦')  
            plus.bluetooth.onBLECharacteristicValueChange(res => {  
                alert(JSON.stringify(res.value))  
                console.log('监听到特征值数据 16进制:'+ ab2hex(res.value))  
                const resValue = new Uint8Array(res.value, 0)  
                console.log('监听到特征值数据 二进制:'+ resValue)  
                const tmp = String.fromCharCode.apply(String, resValue)  
                console.log('监听到特征值数据 字符串:' + tmp)  
            })  
        }         

        // 停止搜索  
        function stopSearch(){  
            plus.bluetooth.stopBluetoothDevicesDiscovery({  
                success(s) {  
                    console.log('停止搜索蓝牙设备成功')  
                }  
            })  
        }         
    })  
</script>

操作步骤:

  1. onBLECharacteristicValueChange
  2. openBluetoothAdapter
  3. startBluetoothDevicesDiscovery
  4. onBluetoothDeviceFound
  5. createBLEConnection -> stopBluetoothDevicesDiscovery
  6. getBLEDeviceServices(延迟1.5s)
  7. getBLEDeviceCharacteristics
  8. notifyBLECharacteristicValueChange
  9. writeBLECharacteristicValue

预期结果:

写入后能监听到notify下的特征值返回信息

实际结果:

写入成功 ok, 没有监听到

bug描述:

低功耗蓝牙模块,无论是使用官方的demo还是自己写的,都是在先注册监听特征值变化后,再获取服务的特征值成功回调的方法里订阅了notify,主动的写入数据,无法监听


更多关于uni-app H5+API【蓝牙】安卓机写入数据后监听不到特征值的变化的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

已解决

更多关于uni-app H5+API【蓝牙】安卓机写入数据后监听不到特征值的变化的实战教程也可以访问 https://www.itying.com/category-93-b0.html


能告知怎么解决的吗,我也遇到这个问题了

你好,看你代码上【监听到特征值数据 二进制】和【监听到特征值数据 字符串】正常吗?我复制了你这几行代码,十六进制显示正常,但是二进制和字符串显示不出来。

这是一个典型的蓝牙通信时序问题。根据你的代码分析,主要问题可能出现在以下几个方面:

  1. 特征值订阅时机不当:在getCharacteristics成功回调中订阅notify特征值,但此时可能设备还未完全准备好接收订阅请求。建议在订阅notify后增加适当延迟再执行写入操作。

  2. UUID匹配问题:确保写入的特征值UUID(0000FFF5-0000-1000-8000-00805F9B34FB)与订阅notify的特征值UUID完全匹配。有些设备需要不同的特征值进行写入和通知。

  3. 设备响应延迟:在订阅notify后立即写入数据,设备可能来不及建立通知通道。建议在notify订阅成功的回调中再执行写入操作。

建议修改代码,在notify订阅成功后添加写入逻辑:

plus.bluetooth.notifyBLECharacteristicValueChange({
    state: true,
    deviceId: deviceId,
    serviceId: serviceId,
    characteristicId: characteristic.uuid,
    success(s) {
        console.log('特征值订阅成功:' + characteristic.uuid)
        // 在这里或稍后执行写入操作
    },
    fail(f) {
        console.log('特征值订阅失败' + JSON.stringify(f))
    }
})
回到顶部