F***@126.com
F***@126.com
  • 发布:2024-06-22 17:11
  • 更新:2024-07-08 18:34
  • 阅读:207

【报Bug】writeBLECharacteristicValue无回调,notifyBLECharacteristicValueChange监听也没有反应

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: 11

HBuilderX类型: 正式

HBuilderX版本号: 4.15

手机系统: iOS

手机系统版本号: iOS 17

手机厂商: 苹果

手机机型: iphone15Pro

页面类型: vue

vue版本: vue2

打包方式: 离线

项目创建方式: HBuilderX

操作步骤:

搜索完设备,点击连接之后,无法拿到writeBLECharacteristicValue的回调,也无法监听到设备返回的数据

预期结果:

发送完当前时间和个人信息后设备应返回数据

实际结果:

writeBLECharacteristicValue无回调,notifyBLECharacteristicValueChange监听也没有反应

bug描述:

    // 获取附近所有蓝牙设备  
    getBLEDevice() {  
      uni.openBluetoothAdapter({  
        success: (res) => {  
          console.log('蓝牙适配器初始化成功', res);  
          uni.startBluetoothDevicesDiscovery({  
            services: ["000012E8-0000-1000-8000-00805F9B34FB"],  
            success: (res) => {  
              console.log('蓝牙设备搜索成功', res);  
              setTimeout(() => {  
                uni.getBluetoothDevices({  
                  success: (res) => {  
                    if (res.devices.length > 0) {  
                      this.showList = true;  
                      this.faildSearch = false;  
                      this.devices = res.devices;  
                    } else {  
                      this.faildSearch = true;  
                    }  
                    console.log('获取设备列表成功', res);  
                  },  
                  fail: (err) => {  
                    console.error('获取设备列表失败', err);  
                  }  
                });  
              }, 2000); // 延迟2秒,确保设备列表获取成功  
            },  
            fail: (err) => {  
              console.error('蓝牙设备搜索失败', err);  
            }  
          });  
        },  
        fail: (err) => {  
          console.error('蓝牙适配器初始化失败', err);  
        }  
      });  
    },  

    // 链接设备  
    createConnection(data) {  
      let deviceId = data.deviceId;  
      uni.createBLEConnection({  
        deviceId: deviceId,  
        success: (res) => {  
          console.log('连接蓝牙设备成功', res);  
          uni.getBLEDeviceServices({  
            deviceId,  
            success: (res) => {  
              console.log('获取服务成功', res);  
              let serviceId = res.services[0].uuid; // 假设获取第一个服务的UUID  
              uni.getBLEDeviceCharacteristics({  
                deviceId: deviceId,  
                serviceId: serviceId,  
                success: (res) => {  
                  console.log('获取特征成功', res);  
                  // 使用正确的UUID  
                  const txCharacteristic = res.characteristics.find(characteristic => characteristic.uuid === 'D973F2E2-B19E-12E8-9E96-0800200C9A66');  
                  const rxCharacteristic = res.characteristics.find(characteristic => characteristic.uuid === 'D973F2E1-B19E-12E8-9E96-0800200C9A66');  

                  if (txCharacteristic && rxCharacteristic) {  
                    // 启用通知  
                    this.notifyBLECharacteristicValueChange(deviceId, serviceId, rxCharacteristic.uuid);  

                    setTimeout(() => {  
                      // 发送时间  
                      this.sendTime(deviceId, serviceId, txCharacteristic.uuid);  
                    }, 1000);  
                  } else {  
                    console.error('找不到所需的特征');  
                  }  
                },  
                fail: (err) => {  
                  console.error('获取特征失败', err);  
                }  
              });  
            },  
            fail: (err) => {  
              console.error('获取服务失败', err);  
            }  
          });  
        },  
        fail: (err) => {  
          console.error('连接蓝牙设备失败', err);  
        }  
      });  
    },  

    // 启用 notify 功能  
    notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) {  
      let that = this;  
      uni.onBLEConnectionStateChange(function (res) {  
        // 该方法回调中可以用于处理连接意外断开等异常情况  
        console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)  
      })  

      uni.notifyBLECharacteristicValueChange({  
        state: true, // 启用 notify 功能  
        deviceId: deviceId,  
        serviceId: serviceId,  
        characteristicId: characteristicId,  
        success: (res) => {  
          console.log("调用notify成功", characteristicId);  

          uni.onBLECharacteristicValueChange((res) => {  
            console.log("监听成功", res);  
            let str = that.ab2ascii(res.value);  
            console.log('接收到数据:', str);  
            that.data = str;  
          });  
          // 只需设置一次监听器  
          if (!that.listenerSet) {  
            that.listenerSet = true;  
          }  
        },  
        fail: (res) => {  
          console.log('启用 notify 功能失败', res);  
          uni.showToast({  
            icon: 'none',  
            title: '设备暂不支持接收数据',  
            duration: 3000  
          });  
        }  
      });  
    },  

    // 二进制流转ascii  
    ab2ascii(buffer) {  
      var str = Array.prototype.map.call(  
        new Uint8Array(buffer),  
        function (bit) {  
          return String.fromCharCode(bit);  
        }  
      );  
      return str.join('');  
    },  

    // 写入当前时间  
    sendTime(deviceId, serviceId, characteristicId) {  
      let buffer = new ArrayBuffer(20);  
      let dataView = new DataView(buffer);  

      // 设置命令字,假设使用 22  
      dataView.setUint8(0, 0x22);  

      // 设置时间数据,假设使用 Big Endian 顺序  
      let now = new Date();  
      dataView.setUint16(1, now.getFullYear() - 2000, false); // 年  
      dataView.setUint8(3, now.getMonth() + 1); // 月  
      dataView.setUint8(4, now.getDate()); // 日  
      dataView.setUint8(5, now.getHours()); // 时  
      dataView.setUint8(6, now.getMinutes()); // 分  
      dataView.setUint8(7, now.getSeconds()); // 秒  

      // 填充未定义字节,根据协议规范确定填充方式  
      for (let i = 8; i < 20; i++) {  
        dataView.setUint8(i, 0x00); // 例如填充为 0x00  
      }  

      // 将 ArrayBuffer 转换为 Uint8Array  
      let data = new Uint8Array(buffer);  
      console.log('发送时间数据包:', buffer);  
      uni.writeBLECharacteristicValue({  
        deviceId: deviceId,  
        serviceId: serviceId,  
        characteristicId: characteristicId,  
        value: data,  
        success: () => {  
          console.log('发送时间成功');  

        },  
        fail: (err) => {  
          console.error('发送时间失败', err);  
        }  
      });  
      this.sendPersonalInfo(deviceId, serviceId, characteristicId);  
    },  

    // 写入个人信息  
    sendPersonalInfo(deviceId, serviceId, characteristicId) {  
      let buffer = new ArrayBuffer(20);  
      let dataView = new DataView(buffer);  
      dataView.setUint8(0, 0x22); // 命令字  
      dataView.setUint8(1, 1); // 年  
      dataView.setUint8(2, 30); // 月  
      dataView.setUint8(3, 175); // 日  
      dataView.setUint8(4, 65);  

      // 填充未定义的字节为0  
      for (let i = 4; i < 20; i++) {  
        dataView.setUint8(i, 0x00);  
      }  

      console.log('发送个人信息数据包:', buffer);  
      uni.writeBLECharacteristicValue({  
        deviceId: deviceId,  
        serviceId: serviceId,  
        characteristicId: characteristicId,  
        value: buffer,  
        success: () => {  
          console.log('发送个人信息成功');  
        },  
        fail: (err) => {  
          console.error('发送个人信息失败', err);  
        }  
      });  
    },
2024-06-22 17:11 负责人:无 分享
已邀请:
F***@126.com

F***@126.com (作者)

求各位大哥,走过路过给点建议,非常急,非常感谢

1***@qq.com

1***@qq.com

我也遇到了,好像是最近的才出现的,我之前代码写的判断都失效了

  • F***@126.com (作者)

    我的是命令字不对,哈哈哈哈哈哈,蓝牙芯片厂那边给的文档不对

    2024-07-29 11:13

  • 7***@qq.com

    不是最近才出现,是ios会这样,不知道怎样解决

    2024-09-26 14:45

linda_虾米

linda_虾米 - 小虾米

一样一样的,,人都要炸了 ,请问怎么解决的。

  • F***@126.com (作者)

    我试命令字试出来的,然后有些地方的api要加点延迟

    2024-07-29 11:13

要回复问题请先登录注册