Taro.openBluetoothAdapter({
success: (res) => {
// 取消之前监听低功耗蓝牙连接状态的改变事件, 不传callback默认取消所有监听
Taro.offBLEConnectionStateChange()
// 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等
Taro.onBLEConnectionStateChange(connectListener)
},
fail: (err) => {
if (err.errMsg !== "openBluetoothAdapter:fail already opened") {
console.error(err.errMsg)
Taro.showToast({
title: "蓝牙初始化失败",
icon: 'error',
duration: 3000
})
}
}
})
const startBluetoothDevicesDiscovery = async () => {
if (_discoveryStarted) {
return
}
_discoveryStarted = true
// 清除上一次的计时器
if (scanTimer) {
clearTimeout(scanTimer)
scanTimer = null
}
// 停止扫描
scanTimer = setTimeout(() => {
stopBluetoothDevicesDiscovery()
}, scanTime)
try {
const res = await new Promise((resolve, reject) => {
Taro.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false,
success: (res) => {
console.log('开始搜寻附近的蓝牙外围设备', res);
// 监听寻找到新设备的事件
onBluetoothDeviceFound();
resolve(res);
},
fail: (err) => {
console.error(err.errMsg);
Taro.showToast({
title: '查找设备失败',
icon: 'error',
duration: 3000
});
reject(err);
}
});
});
_discoveryStarted = false;
return res;
} catch (error) {
_discoveryStarted = false;
if (scanTimer) {
clearTimeout(scanTimer)
scanTimer = null
}
throw error;
}
}
const onBluetoothDeviceFound = async () => {
return new Promise((resolve, reject) => {
devicesList.value = [];
const handler = (res) => {
const {devices} = res;
devices.forEach(device => {
//
if (!device.name && device.localName) {
return;
}
// 过滤掉已经添加的设备
const findIndex = devicesList.value.findIndex(item => item.deviceId === device.deviceId);
if (findIndex === -1) {
devicesList.value.push(device);
}
});
// 在这里可以根据需要决定resolve或reject
resolve(devicesList.value); // 这里假设你希望返回devicesList.value
};
Taro.onBluetoothDeviceFound(handler);
});
}
// 停止搜寻附近的蓝牙外围设备
const stopBluetoothDevicesDiscovery = async () => {
return new Promise((resolve, reject) => {
Taro.stopBluetoothDevicesDiscovery({
success: (res) => {
console.log('停止搜寻附近的蓝牙外围设备', res);
if (scanTimer) {
clearTimeout(scanTimer);
scanTimer = null;
}
_discoveryStarted = false;
resolve(res);
},
fail: (err) => {
console.error('停止搜寻附近的蓝牙外围设备 失败', err);
reject(err);
}
});
});
}
const handleClickDevice = async (bleDevice) => {
try {
Taro.showLoading({title: '正在连接设备'})
// 停止设备扫描
await stopBluetoothDevicesDiscovery()
if (!bleDevice.deviceId) {
Taro.hideLoading()
return;
}
if (activeBleDevice.value && activeBleDevice.value.connected) {
await closeBLEConnection(activeBleDevice.value.deviceId)
}
const isCreateBLEConnection = await createBLEConnection(bleDevice.deviceId)
if (!isCreateBLEConnection) {
Taro.hideLoading()
return;
}
Taro.hideLoading()
} catch (error) {
console.error(error)
}
}
// 连接设备
async function createBLEConnection(deviceId: string) {
console.log("【连接设备】", deviceId);
return new Promise((resolve) => {
Taro.createBLEConnection({
deviceId,
success: (res) => {
console.log("连接设备 成功", res);
resolve(true);
},
fail: (err) => {
console.error("连接设备 失败", err);
resolve(false); // 连接失败时返回 false
},
});
});
}
// 断开设备连接
async function closeBLEConnection(deviceId: string) {
return new Promise((resolve) => {
Taro.closeBLEConnection({
deviceId,
success: (res) => {
console.log("断开设备连接 成功", res);
resolve(true); // 成功时返回 true
},
fail: (err) => {
console.error("断开设备连接 失败", err);
resolve(false); // 断开失败时返回 false
},
});
});
}
// 判断帧头和帧尾拼接完整的数据
function waitForDesiredValue() {
return new Promise((resolve, reject) => {
let characteristicValue = ""; // 用于拼接特征值
const listener = function (res: any) {
try {
const resHexValue = arrayBufferToHex(res.value);
console.log("特征值 resHexValue:", resHexValue);
// 拼接特征值
characteristicValue += resHexValue;
// 在此处添加条件判断,例如,假设帧头帧尾分别是81828384,84838281就解决Promise并返回结果
if (characteristicValue.startsWith("81828384") && characteristicValue.endsWith("84838281")) {
Taro.offBLECharacteristicValueChange(listener); // 停止监听
resolve(characteristicValue); // 解决 Promise 并返回特征值数据
}
} catch (e) {
console.error("特征值解析失败", e);
Taro.offBLECharacteristicValueChange(listener); // 停止监听
reject(e.errMsg); // 拒绝 Promise 并传递错误消息给调用者
}
};
// 开始监听特征值变化
Taro.onBLECharacteristicValueChange(listener);
});
}
// 发送数据 !!!发送指令之前需要监听特征值的变化,从机响应的数据需要从监听特征值的变化的函数回调中获取
async function writeCharacter(deviceId: string, commandId: string, count: any = undefined) {
return new Promise((resolve, reject) => {
try {
const base64 = Buffer.from(commandId, "hex").toString("base64");
const arrayBuffer = Taro.base64ToArrayBuffer(base64);
// 调用waitForDesiredValue函数来等待满足条件的特征值, 这个函数需要根据自己业务和蓝牙协议实现
waitForDesiredValue()
.then((result) => {
// 在这里处理满足条件的特征值
resolve(result); // 解决 Promise 并将特征值传递给调用者
})
.catch((error) => {
console.error("等待特征值失败", error);
reject(error.errMsg); // 拒绝 Promise 并传递错误消息给调用者
});
Taro.getBLEDeviceServices({
deviceId: deviceId,
success: function (res) {
const service = res.services.find(
item => item.uuid.toUpperCase() === writeServiceUUID);
if (!service) {
console.log("没有找到该服务", res);
reject("没有找到该服务"); // 拒绝 Promise 并传递错误消息给调用者
return;
}
const servicesUUID = service.uuid;
// 获取蓝牙设备某个服务中所有特征值(characteristic)
Taro.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: servicesUUID,
success: function () {
Taro.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: writeServiceUUID,
characteristicId: writeCharacteristicUUID,
value: arrayBuffer,
success: function (res) {
console.log("发送数据成功", res.errMsg);
// 不要在这里解决 Promise,因为特征值变化时才应该解决
},
fail: function (res) {
console.log("发送数据失败", res.errMsg);
reject(res.errMsg); // 拒绝 Promise 并传递错误消息给调用者
}
});
}
});
},
fail: function (res) {
console.log("获取蓝牙设备所有服务 失败", res.errMsg);
reject(res.errMsg); // 拒绝 Promise 并传递错误消息给调用者
}
});
} catch (e) {
console.log("发送数据失败", e);
reject(e.errMsg); // 拒绝 Promise 并传递错误消息给调用者
}
});
}
!!!微信小程序原生API的调用同上