搜索完设备,点击连接之后,无法拿到writeBLECharacteristicValue的回调,也无法监听到设备返回的数据
- 发布:2024-06-22 17:11
- 更新:2024-07-08 18:34
- 阅读:207
产品分类: uniapp/App
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: 11
HBuilderX类型: 正式
HBuilderX版本号: 4.15
手机系统: iOS
手机系统版本号: iOS 17
手机厂商: 苹果
手机机型: iphone15Pro
页面类型: vue
vue版本: vue2
打包方式: 离线
项目创建方式: HBuilderX
操作步骤:
预期结果:
发送完当前时间和个人信息后设备应返回数据
发送完当前时间和个人信息后设备应返回数据
实际结果:
writeBLECharacteristicValue无回调,notifyBLECharacteristicValueChange监听也没有反应
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);
}
});
},
3 个回复
F***@126.com (作者)
求各位大哥,走过路过给点建议,非常急,非常感谢
1***@qq.com
我也遇到了,好像是最近的才出现的,我之前代码写的判断都失效了
F***@126.com (作者)
我的是命令字不对,哈哈哈哈哈哈,蓝牙芯片厂那边给的文档不对
2024-07-29 11:13
7***@qq.com
不是最近才出现,是ios会这样,不知道怎样解决
2024-09-26 14:45
linda_虾米 - 小虾米
一样一样的,,人都要炸了 ,请问怎么解决的。
F***@126.com (作者)
我试命令字试出来的,然后有些地方的api要加点延迟
2024-07-29 11:13