解决全局蓝牙组件缺乏特征值和服务ID的问题

一个页面调用了另一个页面的蓝牙组件,蓝牙组件同时也设置为了全局变量,但是在发送蓝牙信息的时候,调用的全局变量却缺乏特征值、服务ID等数据,这该怎么办?

 

当你在微信小程序中使用全局蓝牙组件时,如果发现发送蓝牙信息时缺少特征值(characteristicId)和服务ID(serviceId)等关键数据,可以通过以下方案解决:

问题分析

  1. 常见原因

    • 蓝牙设备发现后未正确保存服务UUID和特征值

    • 全局变量在不同页面间被意外修改或重置

    • 异步操作未完成时就尝试使用这些值

解决方案

方案一:完善蓝牙发现流程

javascript
复制
// 在蓝牙组件中完善发现流程
Component({
  methods: {
    // 发现服务
    discoverServices(deviceId) {
      wx.getBLEDeviceServices({
        deviceId,
        success: (res) => {
          const targetService = res.services.find(s => s.uuid === '你的服务UUID')
          if (targetService) {
            this.setData({
              serviceId: targetService.uuid
            })
            this.discoverCharacteristics(deviceId, targetService.uuid)
          }
        }
      })
    },
    
    // 发现特征值
    discoverCharacteristics(deviceId, serviceId) {
      wx.getBLEDeviceCharacteristics({
        deviceId,
        serviceId,
        success: (res) => {
          const targetChar = res.characteristics.find(c => c.uuid === '你的特征UUID')
          if (targetChar) {
            this.setData({
              characteristicId: targetChar.uuid,
              properties: targetChar.properties
            })
            // 保存到全局
            getApp().globalData.bluetoothInfo = {
              deviceId,
              serviceId,
              characteristicId: targetChar.uuid
            }
          }
        }
      })
    }
  }
})

方案二:使用状态管理保存关键数据

javascript
复制
// 在app.js中建立完整的状态管理
App({
  globalData: {
    bluetooth: {
      device: null,
      serviceId: '',
      characteristicId: '',
      // 添加验证方法
      isReady() {
        return this.device && 
               this.serviceId && 
               this.characteristicId
      }
    }
  }
})

// 使用时检查
if (getApp().globalData.bluetooth.isReady()) {
  // 执行蓝牙操作
} else {
  wx.showToast({ title: '蓝牙未准备好', icon: 'none' })
}

方案三:添加数据验证和自动恢复

javascript
复制
// 在蓝牙组件中添加数据恢复逻辑
Component({
  methods: {
    sendData(data) {
      const app = getApp()
      
      // 检查必要参数
      if (!app.globalData.bluetooth?.serviceId || 
          !app.globalData.bluetooth?.characteristicId) {
        return this.recoverBluetoothInfo().then(() => {
          this.sendData(data) // 重试
        })
      }
      
      // 正常发送逻辑
      wx.writeBLECharacteristicValue({
        deviceId: app.globalData.bluetooth.deviceId,
        serviceId: app.globalData.bluetooth.serviceId,
        characteristicId: app.globalData.bluetooth.characteristicId,
        value: data,
        success: () => {
          // 发送成功
        }
      })
    },
    
    // 恢复蓝牙信息
    recoverBluetoothInfo() {
      return new Promise((resolve) => {
        wx.getConnectedBluetoothDevices({
          success: (res) => {
            if (res.devices.length) {
              this.discoverServices(res.devices[0].deviceId)
              resolve()
            }
          }
        })
      })
    }
  }
})

方案四:使用本地缓存持久化存储

javascript
复制
// 发现服务特征后保存到本地
wx.setStorage({
  key: 'bluetoothConfig',
  data: {
    deviceId: '...',
    serviceId: '...',
    characteristicId: '...',
    lastUpdate: Date.now()
  }
})

// 使用时先从本地读取
const config = wx.getStorageSync('bluetoothConfig')
if (config && Date.now() - config.lastUpdate < 3600000) {
  // 使用缓存配置
}

最佳实践建议

  1. 数据完整性检查

    javascript
    复制
    function checkBluetoothConfig(config) {
      return config && 
             config.deviceId && 
             config.serviceId && 
             config.characteristicId
    }
  2. 错误处理流程

    javascript
    复制
    async function safeBluetoothOperation(data) {
      const app = getApp()
      if (!checkBluetoothConfig(app.globalData.bluetooth)) {
        await rediscoverBluetooth()
      }
      // 执行操作
    }
  3. 页面间通信规范

    javascript
    复制
    // 使用事件总线通知蓝牙状态变化
    app.eventBus.emit('bluetooth-ready', {
      serviceId: '...',
      characteristicId: '...'
    })
  4. 调试建议

    • 在开发阶段添加详细的日志记录

    • 使用try-catch包装蓝牙操作

    • 在UI上显示当前蓝牙连接状态

完整示例代码

javascript
复制
// 在蓝牙组件中
Component({
  methods: {
    initBluetooth() {
      return new Promise((resolve, reject) => {
        // 检查全局数据
        const app = getApp()
        if (app.globalData.bluetooth?.isReady?.()) {
          return resolve()
        }
        
        // 重新发现流程
        wx.startBluetoothDevicesDiscovery({
          success: () => {
            wx.onBluetoothDeviceFound((res) => {
              const targetDevice = res.devices.find(d => d.name === '你的设备名')
              if (targetDevice) {
                this.connectDevice(targetDevice)
                  .then(resolve)
                  .catch(reject)
              }
            })
          }
        })
      })
    },
    
    connectDevice(device) {
      return new Promise((resolve, reject) => {
        wx.createBLEConnection({
          deviceId: device.deviceId,
          success: () => {
            this.discoverServices(device.deviceId)
              .then(resolve)
              .catch(reject)
          },
          fail: reject
        })
      })
    },
    
    discoverServices(deviceId) {
      return new Promise((resolve, reject) => {
        wx.getBLEDeviceServices({ deviceId })
          .then(res => {
            const service = res.services.find(s => /* 你的逻辑 */)
            if (service) {
              return this.discoverCharacteristics(deviceId, service.uuid)
            }
            reject(new Error('未找到目标服务'))
          })
          .then(resolve)
          .catch(reject)
      })
    }
  }
})

通过以上方法,你可以确保全局蓝牙组件始终包含必要的特征值和服务ID,从而避免发送数据时出现关键参数缺失的问题。

posted @ 2025-04-10 17:43  FBshark  阅读(99)  评论(0)    收藏  举报