支付宝小程序:开放平台-官方文档地址:https://docs.alipay.com/mini/api/bluetooth-api#a-namegfgkonamyopenbluetoothadapter
微信小程序:公众平台-官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/api/wx.closeBluetoothAdapter.html
依次用到了支付宝小程序提供的这几个接口:(已知服务id和特征id的情况)
my.openBluetoothAdapter
。可在页面加载的时候调用my.closeBluetoothAdapter
。可在初始化失败(可能蓝牙未打开)的时候调用my.startBluetoothDevicesDiscovery
。初始化完成或点击事件里调用,搜寻到设备或超时时记得停止搜寻my.stopBluetoothDevicesDiscovery
。搜索到设备或请求超时时调用my.onBluetoothDeviceFound
。搜索到时记得移除事件监听my.offBluetoothDeviceFound
。搜索到设备时调用my.connectBLEDevice
。放在监听事件的回调函数里my.disconnectBLEDevice
。特定事件调用my.writeBLECharacteristicValue
。搜寻到指定设备,获取到(或有指定的)serverId 和 characteristicId 时调用my.readBLECharacteristicValue
。搜寻到指定设备,获取到(或有指定的)serverId 和 characteristicId 时调用在不清楚服务id和特征id值的情况、或在调试阶段,可使用的接口:获取蓝牙设备所有 service(服务) my.getBLEDeviceServices
、获取蓝牙设备所有 characteristic(特征值) my.getBLEDeviceCharacteristics
。记住这个顺序:用macId或蓝牙名去匹配蓝牙,在蓝牙连接成功时会获得deviceId,用deviceId去获取想要的serverId,用deviceId和serverId去获取想要的characteristicId,再用这三个id去读/写数据。
此示例中的服务id和特征值id为固定值,所以没有去主动获取。如果需要获取可在连接成功时调用相应接口
axml文件:
js文件:
Page({
data: {
deviceId: "", //设备id
serviceId: "abc0", //固定的服务id
characteristicId: "abc1", //固定的特征值id-1
randomCharacteristicId: "FFF2" //固定的特征值id-2
},
onLoad() {
var that = this;
my.openBluetoothAdapter({ //初始化蓝牙模块
success: (res) => {
that.searchBluetooth(); //开始搜索蓝牙设备
},
fail:(res) => {
console.log("------初始化蓝牙模块失败!!------");
my.alert({ content: "请开启手机蓝牙后再试!" });
}
});
},
//移除事件监听
onUnload() { my.offBluetoothDeviceFound(this.callback); },
searchBluetooth: function(){ //开始搜索蓝牙设备
var that = this;
my.startBluetoothDevicesDiscovery({
services: [],
success: (res) => {
my.showLoading({ content: '正在搜索蓝牙设备' });
//搜索到蓝牙事件监听
that.callback = that.callback.bind(that);
my.onBluetoothDeviceFound(that.callback);
//5s内未搜索到设备,关闭搜索,关闭蓝牙模块
setTimeout(function(){
if (!that.data.deviceId){
my.hideLoading();
my.showToast({ type: 'exception', content: '搜索设备超时', duration: 3000 });
console.log("搜索设备超时");
my.stopBluetoothDevicesDiscovery({}); //关闭搜索
my.offBluetoothDeviceFound(that.callback); //移除搜索设备监听
my.closeBluetoothAdapter({}); //关闭蓝牙模块
}
}, 5000);
},
fail:(res) => {
console.log("-------调用搜寻蓝牙设备失败--------");
}
});
},
callback(res) { //新搜索到设备的回调函数(通过蓝牙名去匹配)
var deviceObj = res.devices[0]; //{"deviceId": "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "RSSI": -83, "manufacturerData": "", "deviceName": "ABCDEFG", "advertisData":"", "localName": "ABCDEFG", "name": "ABCDEFG"}
var name = deviceObj.name || deviceObj.deviceName;
if(name && name === "13579"){ //搜索到的目标蓝牙设备信息
my.stopBluetoothDevicesDiscovery({}); //关闭搜索
my.offBluetoothDeviceFound(this.callback); //移除搜索设备监听
this.setData({ deviceId: deviceObj.deviceId }); //存储目标蓝牙设备id
this.connectBLEDevice(); //去连接蓝牙设备
}
},
connectBLEDevice: function(){ //连接低功耗蓝牙设备
var that = this;
var deviceId = that.data.deviceId;
my.connectBLEDevice({
deviceId: that.data.deviceId,
success: (res) => {
console.log("蓝牙连接成功");
my.hideLoading();
},
fail:(res) => {}
});
},
disconnectBLEDevice: function(){ //断开与低功耗蓝牙设备的连接
var that = this;
my.disconnectBLEDevice({
deviceId: that.data.deviceId,
success: (res) => {
console.log("已断开连接!!");
},
fail:(res) => {}
});
},
writeBluetoothData1: function(){ //写入执行1指令
var that = this;
my.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.characteristicId,
value: "123456789"
});
},
writeBluetoothData2: function(){ //写入执行2指令
var that = this;
my.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.characteristicId,
value: "987654321"
});
}
});
用法与支付宝小程序基本相同,几点不同如下:
依次用到了微信小程序提供的这几个接口:
wx.openBluetoothAdapter
。可在页面加载的时候调用;wx.closeBluetoothAdapter
;wx.startBluetoothDevicesDiscovery
。初始化完成或点击事件里调用,搜索并连接到设备后记得停止搜寻;wx.stopBluetoothDevicesDiscovery
。已经找到需要的蓝牙设备并不需要继续搜索时调用;wx.onBluetoothDeviceFound
;wx.createBLEConnection
;wx.closeBLEConnection
;wx.getBLEDeviceServices
;wx.getBLEDeviceCharacteristics
;wx.writeBLECharacteristicValue
。搜寻到指定设备,获取到(或有指定的)serverId 和 characteristicId 时调用wx.readBLECharacteristicValue
。读取到的信息需要在 onBLECharacteristicValueChange 方法注册的回调中获取。axml文件:
js文件:
Page({
data: {
deviceId: "" //设备id
},
onLoad() {
var that = this;
wx.openBluetoothAdapter({ //初始化蓝牙模块
success: (res) => {
that.startBluetoothDevicesDiscovery(); //开始搜索蓝牙设备
},
fail: (res) => {
console.log("------初始化蓝牙模块失败!!------");
wx.showLoading({ title: '请打开蓝牙', icon: 'loading', duration: 3000 })
}
});
},
//当退出页面,断开蓝牙连接
onUnload() {
wx.closeBLEConnection({
deviceId: this.data.deviceId,
success(res) { }
})
},
startBluetoothDevicesDiscovery: function(){ //开始搜索蓝牙设备
var that = this;
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true,
services: [],
success: (res) => {
//搜索到新的蓝牙设备时触发事件
that.callback = that.callback.bind(that);
wx.onBluetoothDeviceFound(that.callback);
//5s内未搜索到设备,关闭搜索,关闭蓝牙模块
setTimeout(function () {
if (!that.data.deviceId) {
that.setData({ hiddenLoading: true });
wx.showToast({title: '搜索设备超时',duration: 3000 })
console.log("搜索设备超时");
wx.stopBluetoothDevicesDiscovery({}); //关闭搜索
wx.closeBluetoothAdapter({}); //关闭蓝牙模块
}
}, 5000);
},
fail: (res) => { }
});
},
callback(res) { //新搜索到设备的回调函数(通过mac地址去匹配)
var deviceObj = res.devices[0];
if (this.data.mac.toLowerCase() === deviceObj.manufacturerData.toLowerCase()) {
wx.stopBluetoothDevicesDiscovery({}); //关闭搜索
this.setData({ deviceId: deviceObj.deviceId }); //存储目标蓝牙设备id
this.connectBLEDevice(); //去连接蓝牙设备
}
},
connectBLEDevice: function(){ //连接低功耗蓝牙设备
var that = this;
var deviceId = that.data.deviceId;
wx.createBLEConnection({
deviceId: that.data.deviceId,
success: (res) => { //连接蓝牙设备成功
wx.getBLEDeviceServices({
deviceId: that.data.deviceId,
success(res) { //获取服务id成功
that.setData({ serviceId: res.services[1].uuid});
wx.getBLEDeviceCharacteristics({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
success(res) { //获取特性值id成功
that.setData({ characteristicId: res.characteristics[0].uuid });
that.setData({ randomCharacteristicId: res.characteristics[1].uuid });
wx.onBLECharacteristicValueChange(function (res) {
//读取数据成功回调-接收并存储转换后的数据
that.setData({ charact1: that.ab2hex(res.value) });
});
wx.readBLECharacteristicValue({ //读取二进制数据
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.randomCharacteristicId,
success: (res) => { }
});
}
})
}
})
},
fail: (res) => {
console.log("连接蓝牙设备失败");
console.log(res);
}
});
},
ab2hex: function(buffer) { //将二进制数组进行转换
var hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
},
closeBLEConnection: function(){ //断开与低功耗蓝牙设备的连接
var that = this;
wx.closeBLEConnection({
deviceId: that.data.deviceId,
success: (res) => { console.log("已断开连接!!"); }
});
},
writeBluetoothData1: function(){ //写入执行1指令
var that = this;
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.characteristicId,
value: that.getBinaryData("0B0075")
});
},
writeBluetoothData2: function(){ //写入执行2指令
var that = this;
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.characteristicId,
value: that.getBinaryData("75000B")
});
},
getBinaryData: function (message) { //将数据转为二进制数组
let buffer = new ArrayBuffer(6);
let dataView = new DataView(buffer);
var numTitle = 0;
for (var i = 0; i < message.length; i = i + 2) {
var numStr16 = message.substr(i, 2);
var num = parseInt(numStr16, 16);
dataView.setUint8(numTitle, num);
numTitle++;
}
return buffer;
}
});
匹配蓝牙设备的时候,可以通过设备名,但是如果附近有多个同名的设备时,就需要通过mac地址来匹配对应的蓝牙设备了。而在苹果手机上返回的mac地址是经过处理后不准确的。如果有这种情况可以联系蓝牙设备硬件方,将mac地址存入manufacturerData中,通过它的值去匹配&连接蓝牙。