解决全局蓝牙组件缺乏特征值和服务ID的问题
一个页面调用了另一个页面的蓝牙组件,蓝牙组件同时也设置为了全局变量,但是在发送蓝牙信息的时候,调用的全局变量却缺乏特征值、服务ID等数据,这该怎么办?
当你在微信小程序中使用全局蓝牙组件时,如果发现发送蓝牙信息时缺少特征值(characteristicId)和服务ID(serviceId)等关键数据,可以通过以下方案解决:
问题分析
-
常见原因:
-
蓝牙设备发现后未正确保存服务UUID和特征值
-
全局变量在不同页面间被意外修改或重置
-
异步操作未完成时就尝试使用这些值
-
解决方案
方案一:完善蓝牙发现流程
// 在蓝牙组件中完善发现流程
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
}
}
}
})
}
}
})
方案二:使用状态管理保存关键数据
// 在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' })
}
方案三:添加数据验证和自动恢复
// 在蓝牙组件中添加数据恢复逻辑
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()
}
}
})
})
}
}
})
方案四:使用本地缓存持久化存储
// 发现服务特征后保存到本地
wx.setStorage({
key: 'bluetoothConfig',
data: {
deviceId: '...',
serviceId: '...',
characteristicId: '...',
lastUpdate: Date.now()
}
})
// 使用时先从本地读取
const config = wx.getStorageSync('bluetoothConfig')
if (config && Date.now() - config.lastUpdate < 3600000) {
// 使用缓存配置
}
最佳实践建议
-
数据完整性检查:
function checkBluetoothConfig(config) { return config && config.deviceId && config.serviceId && config.characteristicId } -
错误处理流程:
async function safeBluetoothOperation(data) { const app = getApp() if (!checkBluetoothConfig(app.globalData.bluetooth)) { await rediscoverBluetooth() } // 执行操作 } -
页面间通信规范:
// 使用事件总线通知蓝牙状态变化 app.eventBus.emit('bluetooth-ready', { serviceId: '...', characteristicId: '...' }) -
调试建议:
-
在开发阶段添加详细的日志记录
-
使用
try-catch包装蓝牙操作 -
在UI上显示当前蓝牙连接状态
-
完整示例代码
// 在蓝牙组件中
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,从而避免发送数据时出现关键参数缺失的问题。

浙公网安备 33010602011771号