第一步 查询是否授权蓝牙 授权后初始化蓝牙 获取本机蓝牙状态 开启监听蓝牙开启关闭事件 若不调用openBluetoothAdapter方法 下面无法进行
代码中bluetooth 为封装的一些公共方法 会写在最下面
bluetooth.getBluetoothSetting().then(() => {
//已授权 初始化蓝牙模块
wx.openBluetoothAdapter({
success: () => {},
fail: err => bluetooth.errorCodeToStr(err),
complete: () => {
wx.hideLoading()
this.setData({
bluetoothInit: true
})
// 获取本机蓝牙适配器状态。
wx.getBluetoothAdapterState().then(res => {
this.setData({
bluetoothAvailable: res.available,
})
}).catch(err => bluetooth.errorCodeToStr(err))
// 监听蓝牙适配器状态变化事件 是否开启蓝牙
wx.onBluetoothAdapterStateChange((res) => {
let page = getCurrentPages()
if (page[page.length - 1].route != 'pages/index/index') return
wx.showToast({
title: '蓝牙已' + (res.available ? '开启' : '关闭'),
icon: 'none'
})
this.setData({
bluetoothAvailable: res.available,
})
})
}
})
}).catch(err => {
wx.showToast({
title: err,
icon: 'none'
})
})
第二步 搜索低功耗蓝牙设备 和停止搜索 搜索到的设备添加到列表 点击列表选择想要连接的蓝牙设备 (列表点击事件没写 自己写就行)
let timer=null
// 开始搜索蓝牙设备 10秒后自动停止 也可以手动停止搜索
starSearch() {
wx.hideLoading()
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false
}).then(res => {
this.setData({
status: 1
})
// 定时结束搜索
timer = setTimeout(() => {
this.stopSearch()
}, 10000)
}).catch(err => bluetooth.errorCodeToStr(err))
// 监听搜索到新设备的事件 添加到列表
wx.onBluetoothDeviceFound((res) => {
var devices = res.devices[0];
if (devices.name) {
this.setData({
list: [...this.data.list, devices]
})
}
})
},
// 停止搜索(可手动调用)
stopSearch() {
wx.hideLoading()
//清除计时器
clearTimeout(timer)
//取消监听寻找到新设备的事件
wx.offBluetoothDeviceFound()
//停止搜寻附近的蓝牙外围设备 判断设备数量做出提示
wx.stopBluetoothDevicesDiscovery().then(res => {
let status = (this.data.list.length < 1 ? 2 : 3)
this.setData({
status: status
})
if (status == 2) {
wx.showModal({
title: '提示',
content: '未检测到设备,请打开设备重试~',
showCancel: false
})
}
}).catch(err => bluetooth.errorCodeToStr(err))
},
第三步? 创建蓝牙连接获取所需要deviceId(搜索到设备时获取)?serviceId(isPrimary=true的那个uuid),characteristicId(这个是需要characteristics中 write为true时 为写入时需要用到的uuid 若需要监听上报信息 需要选择notify为true的uuid)就是个概念 具体参考官方文档结合自己控制台打印的去判断
当蓝牙连接成功后可以把蓝牙设备的数据 存到缓存或者别的位置 方便下次直接试用
原文:
createBLEConnection 连接蓝牙低功耗设备。
若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需再次进行搜索操作。
// 创建蓝牙连接
createMachineLink() {
// 连接前 断开与其他蓝牙低功耗设备的连接
wx.showLoading({
title: '连接中...',
mask: true
})
// 监听断开连接
wx.onBLEConnectionStateChange((res) => {
if (!res.connected)
this.setData({
isLink: res.connected,
})
})
wx.createBLEConnection({
deviceId: this.data.deviceId,
timeout: 5000,
}).then(() => {
// 获取蓝牙低功耗设备所有服务 (service)
wx.getBLEDeviceServices({
deviceId: this.data.deviceId
}).then(servicesData => {
this.setData({
serviceId: servicesData.services[0].uuid
}, () => {
// 获取蓝牙低功耗设备某个服务中所有特征 (characteristic)
wx.getBLEDeviceCharacteristics({
deviceId: this.data.deviceId,
serviceId: this.data.serviceId,
}).then(res => {
wx.setStorageSync('leaveStatus', 'link')
wx.showToast({
title: '连接成功',
})
this.setData({
isLink: true,
writeCharacteristicId: res.characteristics.find(item => item.properties.write == true).uuid,
notifyCharacteristicId: res.characteristics.find(item => item.properties.notify == true).uuid
}, () => this.notifyBluetoothListener())
}).catch(err => bluetooth.errorCodeToStr(err))
})
}).catch(err => bluetooth.errorCodeToStr(err))
}).catch(err => bluetooth.errorCodeToStr(err))
},
第四步? ?写入数据 我这里直接封装的方法 可以参考(这个是需要传入10字节 的16进制字符串)我这个只是参考
bluetooth.writeData(this.data.deviceId, this.data.serviceId, this.data.writeCharacteristicId, '044000')
//封装
// 写入数据
writeData(deviceId, serviceId, characteristicId, value) {
wx.writeBLECharacteristicValue({
deviceId,
serviceId,
characteristicId,
value: this.createBuffer(value),
}).then(res => {
setTimeout(() => {
wx.hideLoading()
}, 700)
}).catch(err => this.errorCodeToStr(err))
},
// 创建10位 0x00 16进制数据
createBuffer(num) {
let buffer = new ArrayBuffer(10);
let dataView = new DataView(buffer);
// 固定头
dataView.setUint8(0, 0x0D);
dataView.setUint8(1, 0x02);
// 固定头尾
dataView.setUint8(8, 0x0D);
dataView.setUint8(9, 0x03);
for (let i in num) {
dataView.setUint8(parseInt(i) + 2, ('0x' + num[i].charCodeAt().toString(16)));
}
return dataView.buffer
},
第五步 监听蓝牙上报信息 解码并做出相应处理
// 监听 设备上报
notifyBluetoothListener() {
wx.showLoading({
title: '获取状态中...',
mask: true
})
// 启用蓝牙低功耗设备特征值变化时的 notify 功能
wx.notifyBLECharacteristicValueChange({
state: true,
deviceId: this.data.deviceId,
serviceId: this.data.serviceId,
characteristicId: this.data.notifyCharacteristicId,
}).then(res => {
// 启用成功 下发指令 获取 设备状态
bluetooth.writeData(this.data.deviceId, this.data.serviceId, this.data.writeCharacteristicId, '018000')
}).catch(err => bluetooth.errorCodeToStr(err))
// 必须先启用 wx.notifyBLECharacteristicValueChange 才能监听到设备 characteristicValueChange 事件
wx.onBLECharacteristicValueChange((res) => {
setTimeout(() => {
this.setData({
writeType: false
})
}, 1000)
if (res.value.length >= 11) {
bluetooth.closeBLEConnection(this.data.deviceId)
wx.showToast({
title: '未知错误',
})
return
}
this.handleValueChange(bluetooth.ab2hex(res.value))
})
},
// 上报结果处理
handleValueChange(str) {
// 去除固定头固定尾
let hex = str.substring(4,str.length-4)
hex = bluetooth.hexCharCodeToStr(hex)
if (!hex) {
wx.showToast({
title: '未知错误',
})
return
}
let status = Number('0x' + (hex.substring(0, 2)))
if (!status) {
bluetooth.closeBLEConnection(this.data.deviceId)
wx.showToast({
title: '未知错误',
})
return
}
this.setData({
isRun: (status >> 6) & 1, //是否运行中
isHot: (status & 1), //加热
speed: (status >> 2) & 3, //速度
mode: (status >> 4) & 3, //模式
})
},
这里 封装的上面代码中所用的的方法
module.exports = {
// 创建10位 0x00 16进制数据
createBuffer(num) {
let buffer = new ArrayBuffer(10);
let dataView = new DataView(buffer);
// 固定头
dataView.setUint8(0, 0x0D);
dataView.setUint8(1, 0x02);
// 固定头尾
dataView.setUint8(8, 0x0D);
dataView.setUint8(9, 0x03);
for (let i in num) {
dataView.setUint8(parseInt(i) + 2, ('0x' + num[i].charCodeAt().toString(16)));
}
return dataView.buffer
},
// 写入数据
writeData(deviceId, serviceId, characteristicId, value) {
wx.writeBLECharacteristicValue({
deviceId,
serviceId,
characteristicId,
value: this.createBuffer(value),
}).then(res => {
setTimeout(() => {
wx.hideLoading()
}, 700)
}).catch(err => this.errorCodeToStr(err))
},
// 断开蓝牙连接
closeBLEConnection(deviceId, type) {
wx.closeBLEConnection({
deviceId: deviceId,
success: () => {
if (type)
wx.showToast({
title: '断开连接',
icon: 'none'
})
},
fail: err => this.errorCodeToStr(err, type)
})
},
//蓝牙授权查询
getBluetoothSetting() {
return new Promise((resolve, reject) => {
wx.getSetting().then(res => {
if (!res.authSetting['scope.bluetooth']) {
this.scopeBluetooth().then(data => {
resolve(data)
}).catch(err => reject(err))
} else {
resolve(res.authSetting)
}
}).catch(err => reject('getSetting error'))
})
},
//申请蓝牙授权
scopeBluetooth() {
return new Promise((resolve, reject) => {
wx.authorize({
scope: 'scope.bluetooth',
success(res) {
resolve(res)
},
fail(err) {
wx.showModal({
title: '提示',
content: '请授权蓝牙,以便使用设备',
success(res) {
if (res.cancel) {
reject('未授权蓝牙')
return
}
wx.openSetting({
success(data) {
if (data.authSetting['scope.bluetooth']) {
resolve(data.authSetting)
} else {
reject('未授权蓝牙')
}
}
})
}
})
}
})
})
},
// 蓝牙错误统一处理
errorCodeToStr(err, type) {
console.log(err)
if (!err.errCode) {
console.log(err.errMsg)
return
}
if (type) return
wx.showToast({
title: this.codeToStr[err.errCode],
icon: 'none'
})
},
codeToStr: {
"0": "正常",
"-1": "已连接",
"10000": "未初始化蓝牙适配器",
"10001": "当前蓝牙适配器不可用",
"10002": "没有找到指定设备",
"10003": "连接失败",
"10004": "没有找到指定服务",
"10005": "没有找到指定特征",
"10006": "当前连接已断开",
"10007": "当前特征不支持此操作",
"10008": "其余所有系统上报的异常",
"10009": "Android 系统特有,系统版本低于 4.3 不支持 BLE",
"10012": "连接超时",
"10013": "连接 deviceId 为空或者是格式不正确",
},
// ArrayBuffer转16进制字符串
ab2hex(buffer) {
let hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
},
// ArrayBuffer转16进制字符串转16进制数字
hexCharCodeToStr(hexCharCodeStr) {
var trimedStr = hexCharCodeStr.trim();
var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
var len = rawStr.length;
if (len % 2 !== 0) {
alert("存在非法字符!");
return "";
}
var curCharCode;
var resultStr = [];
for (var i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16);
resultStr.push(String.fromCharCode(curCharCode));
}
return resultStr.join("");
},
}
此文章 只是大概记录? 以便再次遇到类似项目能有些经验? 希望能给看到这篇文章的人提供一些帮助?
|