一、很久以前就要发布的,一直拖到现在,记忆都有点模糊了,抱歉了各位大佬,各位开发者.
二、首先我们要清楚一套蓝牙工作的流程,然后通过这个流程才能够一步一步的去实现我们想要得到的结果。
三、流程
- 获取蓝牙的状态:getBluetoothAdapterState
- 初始化蓝牙模块:openBluetoothAdapter
- 搜索附近的蓝牙设备:startBluetoothDevicesDiscovery
- 监听发现附近的蓝牙设备:onBluetoothDeviceFound
- 添加蓝牙,添加成功,断开搜索:stopBluetoothDevicesDiscovery
- 建立连接:createBLEConnection
- 获取蓝牙设备所有服务(service):getBLEDeviceServices
- 获取蓝牙设备特增值(characteristicId):getBLEDeviceCharacteristics
- 启用低功耗蓝牙设备特征值变化时的 notify 功能(notify):notifyBLECharacteristicValueChange
- 向低功耗蓝牙设备写入数据:writeBLECharacteristicValue
- 断开蓝牙:closeBLEConnection
四、根据项目需求来更改自己的需求,上诉流程是我项目所运用到的。详情请看官方文档:https://developers.weixin.qq.com/miniprogram/dev/api/device/bluetooth/wx.openBluetoothAdapter.html
五、 具体代码块:
引入的辅助代码块:
function inArray(arr, key, val) {
for (let i = 0; i < arr.length; i++) {
if (arr[i][key] === val) {
return i;
}
}
return -1;
}
// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
var hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
}
data: {
devices:[],
chs: [],
deviceId: '', //蓝牙设备 id
device_name: '', //蓝牙设备 名称 编号
servicesId: '', // 服务Id uuid
characteristicId: '', //特征值 ID uuid
},
获取蓝牙的状态:getBluetoothAdapterState
// 获取蓝牙状态
GetBluetoothAdapterState() {
wx.getBluetoothAdapterState({
success: (res) => {
console.log('蓝牙状态', res)
if (res.discovering) {
this.OnBluetoothDeviceFound()
} else if (res.available) {
this.StartBluetoothDevicesDiscovery()
}
},
fail:(fail)=>{
console.log("蓝牙状态",fail)
},
})
},
初始化蓝牙模块:openBluetoothAdapter
//初始化蓝牙模块
openBluetoothAdapter: function() {
wx.openBluetoothAdapter({
success: (res) => {
console.log('第一步、蓝牙初始化成功', res)
// 开始搜索附近蓝牙
this.startBluetoothDevicesDiscovery()
},
fail: (res) => {
console.log("第一步、蓝牙初始化失败", res);
wx.showModal({
title: '提示',
content:'蓝牙未启用',
success:(res)=>{
if(res.confirm){
this.onShow();
}else if(res.cancel){
wx.reLaunch({
url: '/pages/Center/Center',
})
}
}
})
}
})
},
搜索附近的蓝牙设备:startBluetoothDevicesDiscovery
//开始搜索附近的蓝牙设备
startBluetoothDevicesDiscovery: function() {
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true,
success: (res) => {
console.log('开始搜索附近的蓝牙设备', res)
this.onBluetoothDeviceFound()
},
})
},
监听发现附近的蓝牙设备:onBluetoothDeviceFound
// 监听发现附近的蓝牙设备
onBluetoothDeviceFound: function() {
wx.onBluetoothDeviceFound((res) => {
res.devices.forEach(device => {
if (!device.name && !device.localName) {
return
}
console.log("发现的蓝牙设备", device)
var foundDevices = this.data.devices
var idx = inArray(foundDevices, 'deviceId', device.deviceId)
var data = {}
if (idx === -1) {
data[`devices[${foundDevices.length}]`] = device
} else {
data[`devices[${idx}]`] = device
}
this.setData(data)
})
})
},
添加蓝牙,添加成功,断开搜索:stopBluetoothDevicesDiscovery
//添加蓝牙
conAdd: function(e){
var deviceId = e.currentTarget.dataset.deviceid,
name = e.currentTarget.dataset.name;
wx.stopBluetoothDevicesDiscovery();//关闭搜索
},
建立连接:createBLEConnection
//建立连接
createBLEConnection(deviceId) {
wx.createBLEConnection({
deviceId: deviceId,
success: (res) => {
console.log(res)
wx.showToast({
title: '蓝牙连接成功',
icon: 'none'
})
this.setData({
purchaseHide: true,
Connected: false
})
this.getBLEDeviceServices()
},
fail(res) {
wx.showToast({
title: '蓝牙连接失败',
icon: 'none'
})
}
})
},
获取蓝牙设备所有服务(service):getBLEDeviceServices
// 获取蓝牙设备所有服务(service)。
getBLEDeviceServices() {
let that = this;
wx.getBLEDeviceServices({
deviceId: that.data.deviceId,
success: (res) => {
console.log('蓝牙设备所有服务', res)
let model = res.services[0];
that.setData({
serviceId: model.uuid
})
that.getBLEDeviceCharacteristics(model.uuid);
},
fail(res) {
console.log('蓝牙设备所有服务失败', res)
}
})
},
获取蓝牙设备特增值(characteristicId):getBLEDeviceCharacteristics
// 获取蓝牙设备特增值(characteristicId)。
getBLEDeviceCharacteristics(serviceId) {
let that = this;
wx.getBLEDeviceCharacteristics({
deviceId: that.data.deviceId,
serviceId: serviceId,
success: (res) => {
console.log(res)
for (let i = 0; i < res.characteristics.length; i++) {
let model = res.characteristics[i];
if (model.properties.notify == true) {
that.setData({
notifyid: model.uuid //监听的 uuid值
})
that.notifyBLECharacteristicValueChange(model.uuid)
}
if (model.properties.write == true) {
that.setData({
characteristicId: model.uuid //用来写入的uuid值
})
}
}
}
})
},
启用低功耗蓝牙设备特征值变化时的 notify 功能(notify):notifyBLECharacteristicValueChange
// 启用低功耗蓝牙设备特征值变化时的 notify 功能(notify)。
notifyBLECharacteristicValueChange(uuid) {
let that = this;
wx.notifyBLECharacteristicValueChange({
characteristicId: uuid,
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
state: true,
success: (res) => {
console.log('启用notify 功能成功:', res)
wx.onBLECharacteristicValueChange((r) => {
console.log('返回的值', r);
console.log('返回的值', ab2hex(r.value));
})
},
fail: (fail) => {
console.log('启用notify 功能失败:', fail)
}
})
},
向低功耗蓝牙设备写入数据:writeBLECharacteristicValue
//向低功耗蓝牙设备写入数据writeBLECharacteristicValue。
writeBLECharacteristicValue(buffer) {
let that = this;
// buffer = "F00601003C2CDB84";通过合作硬件方蓝牙的协议经过md5加密得到
buffer = that.string2buffer(buffer);
console.log("buffer:", buffer)
wx.writeBLECharacteristicValue({
characteristicId: that.data.characteristicId,
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
value: buffer,
success: (res) => {
console.log("写入成功", res);
wx.onBLECharacteristicValueChange(function (r) {
console.log("ValueChange1: ", r)
console.log("ValueChange2: ", ab2hex(r.value))
})
wx.showToast({
title: '充电启动成功',
icon: 'none'
})
},
fail: (fail) => {
console.log("写入失败", fail);
wx.showToast({
title: '充电启动失败',
icon: 'none'
})
}
})
},
断开蓝牙:closeBLEConnection
//断开蓝牙
closeBLEConnection(deviceId) {
if (deviceId == '' || deviceId == null) {
return
} else {
wx.closeBLEConnection({
deviceId: deviceId,
success: (res) => {
console.log("蓝牙断开成功", res)
wx.showToast({
title: '蓝牙断开成功',
icon: 'none'
})
},
fail: (fail) => {
console.log("蓝牙断开失败", fail)
wx.showToast({
title: '蓝牙断开失败',
icon: 'none'
})
}
})
}
},
所用到的方法
string2buffer(str) {
let val = ""
if (!str) return;
let length = str.length;
let index = 0;
let array = []
while (index < length) {
array.push(str.substring(index, index + 2));
index = index + 2;
}
val = array.join(",");
// 将16进制转化为ArrayBuffer
return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16)
})).buffer
},
官方还有一个dome给参考(api最后的那个示例代码,运行到开发者工具就知道了,大同小异,或者也有所启发),可以多结合来看看,具体需求就看个人的项目需求而定了
后面的充电过程我就不写了,其实最后写入命令到蓝牙只要成功了那就相当于这个蓝牙共享充电器已经开始充电了,就像共享单车锁打开了一样
总结:所有的流程不外乎得到这几个值,然后通过这几个值来进行一系列的操作,所以如果实际操作中有任何问题的话,去好好打印一下这几个值,然后通过协议书来一一验证:deviceId: '', //蓝牙设备 id,servicesId: '', // 服务Id uuid,characteristicId: '', //特征值 ID uuid 以及最后写入数据的value //蓝牙设备特征值对应的二进制值,最后祝大家步步高升