起因是写了一个升级程序,通过蓝牙向设备写入,在安卓端一切正常,但在ios系统,就有一些问题。
现像:ios端,第一次连接上蓝牙以后,可以正常升级写入,第二次以及之后的连接,就不调用writeBLECharacteristicValue()函数写入了,过一会之后,会自动断开蓝牙连接,如下图:
代码:
// 1.打开蓝牙适配器
openBle() {
var that = this;
uni.openBluetoothAdapter({
success() {
console.log('打开蓝牙适配器成功!');
that.discoveryBle();
},
fail(err) {
console.error('打开蓝牙适配器失败', err);
uni.showToast({
title: '请打开蓝牙!',
icon: 'none'
});
}
});
},
// 2.搜索蓝牙设备
discoveryBle() {
var that = this;
uni.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false,
success() {
console.log('开始扫描蓝牙设备');
that.listenBle();
},
fail(err) {
console.error('扫描蓝牙设备失败', err);
}
});
},
// 3.监听扫描到的蓝牙设备
listenBle() {
var that = this;
uni.onBluetoothDeviceFound((res) => {
var devices = res.devices;
for (var i in devices) {
// console.log("蓝牙设备:",devices);
if (that.isMyDevice(devices[i])) {
uni.showToast({
title: "找到" + that.ourDevice.length + "个设备",
icon: 'none'
});
}
}
// 发送可连接的蓝牙列表给服务器
if (that.isOurDevice) {
that.isOurDevice = false;
var data = JSON.stringify(that.ourDevice);
var obj = {
DataType: "BLE",
Key: "Msg",
Data: data,
Msg: "显示信息"
};
var jsonString = JSON.stringify(obj);
uni.sendSocketMessage({
data: jsonString, // 发送 JSON 字符串
success(res) {
// console.log("发送蓝牙信息列表 " + jsonString + " 成功!");
},
fail(err) {
console.error("发送数据失败", err);
}
});
}
});
},
// 4. 连接蓝牙设备
connectToDevice(deviceId) {
var that = this;
if (targetDeviceID != deviceId) {
targetDeviceID = deviceId;
uni.createBLEConnection({
deviceId: targetDeviceID,
success(res) {
that.isConnected = true;
console.log(`设备 ${targetDeviceID} 连接成功`, res);
uni.stopBluetoothDevicesDiscovery({
success(res) {
if (plateForm == 'ios') {
console.log("当前平台是IOS");
that.getService(); // 跳过设置MTU,直接获取服务UUID
} else {
console.log("当前平台是安卓");
that.setMTU(); // 设置最大传输单元
}
}
});
uni.showToast({
title: '蓝牙连接成功!',
icon: 'success'
});
},
fail(err) {
console.error("连接错误信息:", err);
if (err.errCode == -1) {
// uni.showToast({
// title: '已连接,请勿重复连接',
// icon: 'none'
// });
} else if (err.errCode == 10003) {
uni.showToast({
title: '无法连接,请检查设备',
icon: 'none'
});
} else {
uni.showToast({
title: '连接设备失败',
icon: 'none'
});
}
}
});
}
},
// 获取服务的UUID
getService() {
var that = this;
uni.getBLEDeviceServices({
deviceId: targetDeviceID,
success(res) {
console.log("获取服务UUID成功:", res);
if (plateForm == 'ios') { // 设置IOS端的服务UUID
if (res.services.length == 1) {
serviceUUID = res.services[0].uuid; // 设置ESP32蓝牙服务的UUID
} else {
serviceUUID = res.services[1].uuid; // 设置蓝牙芯片服务的UUID
}
} else { // 设置Android端的服务UUID
if (res.services.length == 3) {
serviceUUID = res.services[0].uuid; // 设置ESP32蓝牙服务的UUID
} else {
serviceUUID = res.services[1].uuid; // 设置蓝牙芯片服务的UUID
}
}
that.getCharacteris();
},
fail(err) {
console.error("获取服务UUID失败:", err);
}
});
},
// 获取特征值的UUID
getCharacteris() {
var that = this;
uni.getBLEDeviceCharacteristics({
deviceId: targetDeviceID,
serviceId: serviceUUID,
success(res) {
console.log("获取特征值UUID成功:", res);
if (res.characteristics.length == 1) { // 设置ESP32蓝牙特征值的UUID
characteristicIdUUID = res.characteristics[0].uuid;
writeUUID = res.characteristics[0].uuid;
} else { // 设置蓝牙芯片特征值的UUID
characteristicIdUUID = res.characteristics[0].uuid;
writeUUID = res.characteristics[1].uuid;
}
that.checkNotify();
},
fail(err) {
console.error("读取特征值UUID失败:", err);
}
})
},
// 5.设置最大传输单元
setMTU() {
var that = this;
uni.setBLEMTU({
deviceId: targetDeviceID,
mtu: 200,
success() {
uni.showToast({
title: '参数设置成功!',
icon: 'success'
});
that.getService(); // 获取服务UUID
},
fail(err) {
console.error("设置最大传输单元失败:", err);
}
})
},
// 6.检查订阅
checkNotify() {
var that = this;
// 6 . 订阅特征值
console.log("服务:" + serviceUUID + "特征值:" + characteristicIdUUID);
uni.notifyBLECharacteristicValueChange({
deviceId: targetDeviceID,
serviceId: serviceUUID,
characteristicId: characteristicIdUUID,
state: true,
success() {
uni.showToast({
title: '设备连接正常!',
icon: 'success'
});
setTimeout(function() {
that.getValueChange();
}, 1500);
},
fail(err) {
console.error("无法读取设备数据:", err)
uni.showToast({
title: '无法读取设备数据',
icon: 'fail'
});
}
});
},
// 7. 监听低功耗蓝牙设备的特征值变化事件
getValueChange() {
var that = this;
uni.onBLECharacteristicValueChange((res) => {
var value = this.ab2hex(res.value);
if (characteristicIdUUID == res.characteristicId) {
this.sendDataToServer(value);
}
console.log("特征值变化:", value);
});
},
// 8.断开连接
disconnectDevice() {
uni.closeBLEConnection({
deviceId: targetDeviceID,
success() {
console.log('设备 ' + targetDeviceID + ' 断开连接');
this.isConnected = false;
},
fail(err) {
console.error('断开连接失败', err);
}
});
},
// 9.向蓝牙设备写入数据
sendDataToBle(data) {
// try {
var that = this;
const buffer = this.hex2buffer(data);
uni.writeBLECharacteristicValue({
deviceId: targetDeviceID,
serviceId: serviceUUID,
characteristicId: writeUUID,
value: buffer,
writeType: "write",
success() {
console.log(data + "已写入蓝牙设备!")
},
fail(err) {
console.error('写入数据失败' + that.targetDeviceID, err);
uni.showToast({
title: '写入参数失败!',
icon: 'none'
});
}
});
// } catch (error) {
// console.error('蓝牙发送数据过程中发生错误:', error);
// }
},
// 10.关闭蓝牙适配器
closeBle() {
uni.closeBluetoothAdapter({
success(res) {
console.log(res)
}
})
}
},
onUnload() {
var that = this;
uni.stopBluetoothDevicesDiscovery({
success(res) {
console.log("停止搜索蓝牙");
}
});
this.disconnectDevice();
this.closeBle(); // 关闭蓝牙
uni.closeSocket({
success(res) {
console.log("关闭Wbsocket连接成功!", res);
}
});
this.cleanData(); //清除缓存数据
},
writeType:'writeNoResponse',改成这个试试