文章目录
html
html
<view class="m_t_36">
<view class="w_50_ h_100 lh_100 m_l_a m_r_a bc_409eff radius_10 color_fff ta_c" @click="openBluetoothAdapter()">一键开门</view>
</view>
JavaScript
javascript
export default {
data() {
return {
timeout: undefined,
// 后端保存蓝牙信息
bluetooths: [
{
deviceId: "0A:45:32:0C:78:C6",
name: "YX_0A45320C78C6",
serviceId: '0000FFB0-0000-1000-8000-00805F9B34FB',
notifyId: '0000FFB2-0000-1000-8000-00805F9B34FB',
writeId: '0000FFB1-0000-1000-8000-00805F9B34FB',
instruction: 'EE03E30100'
},
{
deviceId: "5C:C3:36:8D:B9:FC",
name: "RTK_BT_4.1v",
serviceId: '0000FFB0-0000-1000-8000-00805F9B34FB',
notifyId: '0000FFB2-0000-1000-8000-00805F9B34FB',
writeId: '0000FFB1-0000-1000-8000-00805F9B34FB',
instruction: 'EE03E30100'
}
],
bluetooth: {}
}
},
methods: {
/**
* 根据不同方法名调用方法,统一定时器的触发判断,
* 当定时器触发时,无法确定当前调用的方法是哪个
* @param {String} fnName
*/
methodExecution(fnName = '') {
if (this.timeout) {
this[fnName]();
} else {
console.log('执行方法');
}
},
// 数据初始化
initInfo() {
// 清除定时器无效的解决方案
this.timeout = undefined;
this.bluetooth = {};
},
// 初始化蓝牙模块
openBluetoothAdapter() {
let that = this;
// 向低功耗蓝牙设备特征值中写入二进制数据。
// 注意:必须设备的特征值支持 write 才可以成功调用。
if (Object.keys(that.bluetooth).length) return that.writeBLECharacteristicValue();
// 数据初始化
that.initInfo();
// 初始化蓝牙模块
uni.openBluetoothAdapter({
// 主服务的UUID是YX。传入这个参数,只搜索主服务UUID为YX的设备
// services: ['YX'],
success() {
// 开始搜索附近的蓝牙设备
that.startBluetoothDevicesDiscovery();
},
fail() {
uni.showToast({
icon: 'none',
title: '查看手机蓝牙是否打开'
});
}
});
},
// 开始搜索附近的蓝牙设备
startBluetoothDevicesDiscovery() {
let that = this;
uni.showLoading({
title: '加载中',
mask: true
});
that.timeout = setTimeout(() => {
// 数据初始化
that.initInfo();
uni.hideLoading();
uni.showToast({
icon: 'none',
title: '开门失败'
});
}, 1000 * 20);
// 开始搜索附近的蓝牙设备
uni.startBluetoothDevicesDiscovery({
success() {
// 监听返回的蓝牙设备
uni.onBluetoothDeviceFound(({
devices
}) => {
if (devices.length) {
let bluetooths = that.bluetooths;
// 多对多查找
for (let i = 0; i < devices.length; i++) {
let itemI = devices[i];
if (itemI.name) {
for (let j = 0; j < bluetooths.length; j++) {
let itemJ = bluetooths[i];
if (itemI.deviceId === itemJ.deviceId && itemI.name === itemJ.name) {
that.bluetooth = itemJ;
setTimeout(() => { that.createBLEConnection() }, 0);
return undefined;
}
}
}
}
}
});
},
fail() {
that.methodExecution('startBluetoothDevicesDiscovery');
}
});
},
// 连接低功耗蓝牙设备
createBLEConnection() {
let that = this;
// 连接低功耗蓝牙设备
uni.createBLEConnection({
deviceId: that.bluetooth.deviceId,
success() {
// 停止搜寻附近的蓝牙外围设备
uni.stopBluetoothDevicesDiscovery({
success() {
// 获取蓝牙服务
// that.getBLEDeviceServices();
// 启用低功耗蓝牙设备特征值变化时的notify功能,订阅特征值
that.notifyBLECharacteristicValueChange();
},
fail() { }
});
},
fail() {
// 连接低功耗蓝牙设备
that.methodExecution('createBLEConnection');
}
});
},
// 启用低功耗蓝牙设备特征值变化时的notify功能,订阅特征值
notifyBLECharacteristicValueChange() {
let that = this,
{ deviceId, serviceId, notifyId } = that.bluetooth;
// 启用低功耗蓝牙设备特征值变化时的notify功能,订阅特征值
uni.notifyBLECharacteristicValueChange({
state: true,
deviceId,
serviceId,
characteristicId: notifyId,
success() {
// 监听低功耗蓝牙设备的特征值变化事件。
// 必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
that.onBLECharacteristicValueChange();
},
fail() {
// 启用低功耗蓝牙设备特征值变化时的notify功能,订阅特征值
that.methodExecution('notifyBLECharacteristicValueChange');
}
});
},
// 监听低功耗蓝牙设备的特征值变化事件。
// 必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
onBLECharacteristicValueChange() {
let that = this;
// 监听低功耗蓝牙设备的特征值变化事件。
// 必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
uni.onBLECharacteristicValueChange(() => {
that.writeBLECharacteristicValue();
});
},
// 向低功耗蓝牙设备特征值中写入二进制数据。
// 注意:必须设备的特征值支持 write 才可以成功调用。
writeBLECharacteristicValue() {
let that = this,
{ deviceId, serviceId, writeId, instruction } = that.bluetooth,
typedArray = new Uint8Array(instruction.match(/[\da-f]{2}/gi).map((h) => parseInt(h, 16))),
buffer = typedArray.buffer;
// 向低功耗蓝牙设备特征值中写入二进制数据。
// 注意:必须设备的特征值支持 write 才可以成功调用。
uni.writeBLECharacteristicValue({
deviceId,
serviceId,
characteristicId: writeId,
value: buffer,
success() {
uni.showToast({
title: '开门成功',
icon: 'none'
});
},
fail() {
uni.showToast({
title: '开门失败',
icon: 'none'
});
},
complete() {
clearTimeout(that.timeout);
that.timeout = undefined;
uni.hideLoading();
}
});
},
// 关闭(断开)蓝牙模块
closeBluetoothAdapter() {
let that = this;
// 关闭(断开)蓝牙模块
uni.closeBluetoothAdapter({
success: () => {
uni.showToast({
title: '蓝牙已关闭',
icon: 'none'
});
clearTimeout(that.timeout);
that.timeout = undefined;
uni.hideLoading();
that.initInfo();
},
fail() {
that.closeBluetoothAdapter();
}
});
},
// 监听页面隐藏
onHide() {
// 关闭(断开)蓝牙模块
// this.closeBluetoothAdapter();
},
// 监听页面卸载
onUnload() {
// 关闭(断开)蓝牙模块
this.closeBluetoothAdapter();
}
}
}
坑
1、
notifyBLECharacteristicValueChange
方法用的是读取的特征值。
2、writeBLECharacteristicValue
发送指令,返回成功,蓝牙设备无反应,大概率是指令问题。
3、关闭蓝牙有两个API
,目前测试只有closeBluetoothAdapter
彻底断开蓝牙。
4、setTimeout
无法彻底清除定时器,需要手动设置属性值为undefined
。