我的微信小程序蓝牙控制工具类
utils.showToast(‘蓝牙连接失败’,1000)
就是微信的吐司
const app = getApp();
const utils = require('../utils/utils')
let showLogs = true
//16进制字符串转ArrayBuffer
function hexStringToArrayBuffer(str) {
let hex = str
let typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16)
}))
let buffer = typedArray.buffer
return buffer;
}
// buffer转16进制
function ab2hex(buffer) {
let hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
}
// 发送数据
function sendMsg(msg, toArrayBuf = true) {
let buf = toArrayBuf ? hexStringToArrayBuffer(msg) : msg;
let bluetoothInfoTemp = wx.getStorageSync('bluetoothInfoTemp');
return new Promise((resolve, reject) => {
wx.writeBLECharacteristicValue({
deviceId: bluetoothInfoTemp.deviceID,
serviceId: bluetoothInfoTemp.servicesInfo.writeServiceID,
characteristicId: bluetoothInfoTemp.characterInfo.writeCharactersID,
value: buf,
success: function (res) {
console.log('发送成功====>',res)
resolve(res);
},
fail: function (res) {
console.log('发送失败====>',res)
}
})
})
}
// 接受数据
function readMsg(){
wx.onBLECharacteristicValueChange(function(characteristic) {
var msg = ab2hex(characteristic.value)
console.log("接受的消息===》",msg)
})
}
// 开启蓝牙适配器
function startBlueAdapter() {
console.log('开启蓝牙适配器====>')
if (!wx.openBluetoothAdapter) {
return;
}
return new Promise((resolve, reject) => {
wx.openBluetoothAdapter({
success: res => {
console.log("蓝牙适配器打开成功===>", res);
resolve(true)
},
fail: res => {
console.error("蓝牙适配器打开失败===>", res);
resolve(false)
}
})
})
}
let stopBluetoothTimeId ;
//搜索设备
function startBluetoothDevicesDiscovery() {
return new Promise((resolve, reject) => {
// 搜不到5s自动关闭
stopBluetoothTimeId = setTimeout(() => {
stopBluetoothDevicesDiscovery();
utils.showToast('蓝牙连接失败',1000)
}, 10000);
wx.startBluetoothDevicesDiscovery({
services: [],
success: function (res) {
if (showLogs) {
console.log("success startBluetoothDevicesDiscovery:", res)
}
resolve(res);
},
fail: function (res) {
if (showLogs) {
console.log("fail startBluetoothDevicesDiscovery:", res)
}
reject({})
}
})
}).catch((res) => {
})
}
// 获取mac地址
// device_id其实是mac地址(新的)
function getBluetoothDevices(bluetoothName) {
console.log("搜索新设备bluetoothName===》",bluetoothName)
return new Promise((resolve, reject) => {
wx.getBluetoothDevices({
success: (res) => {
let devices = res.devices;
if (showLogs) {
console.log("success getBluetoothDevices:", devices)
}
let device_id;
for (let device of devices) {
if (device.name == bluetoothName || device.localName == bluetoothName) {
device_id = device.deviceId;
console.log("success bluetoothName:", bluetoothName)
console.log("success device.name:", device.name)
console.log("success localName:",device.localName)
console.log("success device_id:", device_id)
stopBluetoothDevicesDiscovery();
resolve(device_id);
}
}
if (!device_id) {
resolve();
}
},
})
}).catch((res) => {
})
}
// 关闭蓝牙搜索
function stopBluetoothDevicesDiscovery() {
wx.stopBluetoothDevicesDiscovery({
success: (res) => {
console.log('关闭蓝牙停止搜索成功');
},
fail: (res) => {
console.log('关闭蓝牙停止搜索失败');
},
})
}
// 查找蓝牙设备(已经连接过的设备)
function onBluetoothDeviceFound(bluetoothName) {
console.log("搜索已经连接过的设备bluetoothName===》",bluetoothName)
return new Promise((resolve, reject) => {
wx.onBluetoothDeviceFound(function (res) {
let devices = res.devices;
if (showLogs) {
console.log("success onBluetoothDeviceFound:", devices);
}
for (let device of devices) {
if (device.name == bluetoothName || device.localName == bluetoothName) {
let device_id = device.deviceId;
stopBluetoothDevicesDiscovery();
clearTimeout(stopBluetoothTimeId)
resolve(device_id);
}
}
});
}).catch((res) => {
stopBluetoothDevicesDiscovery();
console.error("异常")
})
}
function createBLEConnection(deviceID) {
return new Promise((resolve, reject) => {
wx.createBLEConnection({
deviceId: deviceID,
timeout: 10000,
success: function (res) {
monitorIsBreak()
if (showLogs) {
console.log("success createBLEConnection:", res);
}
resolve(res);
},
fail: function (res) {
if (showLogs) {
console.log("fail createBLEConnection:", res);
}
resolve();
}
})
})
}
function getBLEDeviceServices(deviceID) {
return new Promise((resolve, reject) => {
wx.getBLEDeviceServices({
deviceId: deviceID,
success: function (res) {
if (showLogs) {
console.log("success getBLEDeviceServices:", res);
}
resolve(res)
},
fail: function (res) {
if (showLogs) {
console.log("fail getBLEDeviceServices:", res);
}
resolve();
}
})
})
}
// 过滤需要的服务
function filterService(services) {
return new Promise((resolve, reject) => {
let servicesInfo = {};
// 遍历过滤要的服务
for (let service of services) {
if (service.uuid.toUpperCase().indexOf("FFE0") != -1) {
servicesInfo.readServiceID = service.uuid;
}else if(service.uuid.toUpperCase().indexOf("FFE5") != -1) {
servicesInfo.writeServiceID = service.uuid;
}else if(service.uuid.toUpperCase().indexOf("D973") != -1){
servicesInfo.writeServiceID = service.uuid;
servicesInfo.readServiceID = service.uuid;
}
}
console.log("filter_servicesInfo===>",servicesInfo)
// 没有的话,默认选择首个
if(typeof servicesInfo.writeServiceID!=undefined){
servicesInfo.writeServiceID = services[0].uuid;
}
if(typeof servicesInfo.readServiceID!=undefined){
servicesInfo.readServiceID = services[0].uuid;
}
console.log("end_servicesInfo===>",servicesInfo)
//完成标识
if (typeof servicesInfo.readServiceID!=undefined && typeof servicesInfo.readServiceID!=undefined) {
resolve(servicesInfo);
} else {
resolve();
}
})
}
function getDeviceCharacter(deviceID, serviceID) {
return new Promise((resolve, reject) => {
wx.getBLEDeviceCharacteristics({
deviceId: deviceID,
serviceId: serviceID,
success: function (res) {
if (showLogs) {
console.log("success getDeviceCharacter:", res);
}
resolve(res);
},
fail: function (res) {
if (showLogs) {
console.log("fail getDeviceCharacter:", res);
}
resolve();
}
})
})
}
function notifyBLECharacteristicValueChange(deviceID, serviceID, characteristicID) {
return new Promise((resolve, reject) => {
wx.notifyBLECharacteristicValueChange({
state: true,
deviceId: deviceID,
serviceId: serviceID,
characteristicId: characteristicID,
success: function (res) {
if (showLogs) {
console.log("success notifyBLECharacteristicValueChange:", res);
}
resolve(res);
},
fail: function (res) {
if (showLogs) {
console.log("fail notifyBLECharacteristicValueChange:", res);
}
resolve();
},
})
})
}
function closeBLEConnection(deviceID) {
return new Promise((resolve, reject) => {
wx.closeBLEConnection({
deviceId: deviceID,
success: function (res) {
if (showLogs) {
console.log("success closeBLEConnection:", res);
}
app.globalData.bluetooth_connected = false
resolve(res);
},
fail: function (res) {
if (showLogs) {
console.log("fail closeBLEConnection:", res);
}
resolve();
}
});
})
}
function closeBluetoothAdapter() {
return new Promise((resolve, reject) => {
wx.closeBluetoothAdapter({
success: function (res) {
if (showLogs) {
console.log("success closeBluetoothAdapter:", res);
}
app.globalData.bluetooth_connected = false
resolve(res);
},
fail: function (res) {
if (showLogs) {
console.log("fail closeBluetoothAdapter:", res);
}
resolve();
},
})
})
}
//查看蓝牙是否断开
function monitorIsBreak(){ // 监听异常断开
wx.onBLEConnectionStateChange(function(res) {
if(!res.connected) { // 判断是否为断开连接
wx.vibrateLong()
console.error("断开连接")
app.globalData.bluetooth_connected = false
}else{
console.log("连接中")
app.globalData.bluetooth_connected = true
}
})
}
async function createBluetooth(deviceID){
console.log("createBluetooth===>")
let createConnectionRes = await createBLEConnection(deviceID);
console.log("createConnectionRes===>",createConnectionRes)
if (!createConnectionRes || createConnectionRes.errCode != 0) {
console.log("连接失败,重新连接中");
return;
}
//获取蓝牙的服务
let getServiceRes = await getBLEDeviceServices(deviceID);
console.log("getBLEDeviceServices", getServiceRes);
if (!getServiceRes || getServiceRes.errCode != 0) {
return;
}
//过滤出读写服务值
let servicesInfo = await filterService(getServiceRes.services);
console.log("filterService", servicesInfo);
if (!servicesInfo) {
return;
}
//获取写的特征值
let writeCharacters = await getDeviceCharacter(deviceID, servicesInfo.writeServiceID);
console.log("getDeviceCharacter write", writeCharacters);
let writeCharactersID;
if (writeCharacters && writeCharacters.errMsg == "getBLEDeviceCharacteristics:ok") {
for (let character of writeCharacters.characteristics) {
if (character.properties.write) {
writeCharactersID = character.uuid;
break;
}
}
}
console.log("write character", writeCharactersID);
if (!writeCharactersID) {
return;
}
//获取读的特征值
let readCharacters = await getDeviceCharacter(deviceID, servicesInfo.readServiceID);
console.log("getDeviceCharacter read", readCharacters);
let readCharactersID;
if (readCharacters && readCharacters.errMsg == "getBLEDeviceCharacteristics:ok") {
for (let character of readCharacters.characteristics) {
if (character.properties.notify) {
readCharactersID = character.uuid;
break;
}
}
}
console.log("read character", readCharactersID);
if (!readCharactersID) {
return;
}
let characterInfo = {
writeCharactersID: writeCharactersID,
readCharactersID: readCharactersID
};
console.log("characterInfo===>",characterInfo)
let bluetoothInfoTemp = {
deviceID: deviceID,
servicesInfo: servicesInfo,
characterInfo: characterInfo,
}
console.log("bluetoothInfoTemp===>",bluetoothInfoTemp)
wx.setStorageSync('bluetoothInfoTemp', bluetoothInfoTemp)
let notifyChangeRes = await notifyBLECharacteristicValueChange(deviceID, servicesInfo.readServiceID, readCharactersID);
console.log("notifyBLECharacteristicValueChange", notifyChangeRes);
if (!notifyChangeRes || notifyChangeRes.errCode != 0) {
return;
}
clearTimeout(stopBluetoothTimeId)
utils.showToast('蓝牙成功',1000)
}
async function oneTouchConnectBluetooth(bluetoothname,showLoading=false){
//已经连接或者没有绑定设备号
if(app.globalData.bluetooth_connected || bluetoothname.length == 0){
console.log("bluetoothname===>",bluetoothname)
console.log("蓝牙状态===>",app.globalData.bluetooth_connected,"是否有设备连接===>",!bluetoothname.length == 0)
return
}
// 开启蓝牙适配器
console.log("连接蓝牙目标===>",bluetoothname)
let hasStartBlueAdapter = await startBlueAdapter()
if(!hasStartBlueAdapter){
utils.showToast('请打开手机蓝牙')
return
}
console.log("检测小程序是否具备蓝牙权限")
// 检测小程序是否具备蓝牙权限
let hasBuletoothPermission = await getBuletoothPermission()
if(!hasBuletoothPermission){
utils.showToast('检测小程序是否具备蓝牙权限')
return
}
// 搜索附件的设备
await startBluetoothDevicesDiscovery();
// 连接指定设备,返回mac地址(新设备)
let deviceID = await getBluetoothDevices(bluetoothname);
if (!deviceID) {
// 再次查找(连接过的设备)
deviceID = await onBluetoothDeviceFound(bluetoothname);
}
console.log("是否存在找到设备==>", deviceID);
// 连接存在设备
if (deviceID) {
console.log("连接存在设备")
createBluetooth(deviceID);
}
if(!showLoading){
clearTimeout(stopBluetoothTimeId)
}
}
// 获取蓝牙权限
function getBuletoothPermission(){
return new Promise((resolve, reject) => {
wx.getSetting({
success: res => {
console.log("获取设置信息===》",res)
// 位置权限没有或者拒绝
if (typeof (res.authSetting['scope.bluetooth']) != undefined && !res.authSetting['scope.bluetooth']) {
wx.getSetting({
success(res) {
if (!res.authSetting['scope.bluetooth']) {
wx.authorize({
scope: 'scope.bluetooth',
success () {
console.log("同意蓝牙")
resolve(true);
},
fail(){
resolve(false);
}
})
}
}
})
}else{
// app.globalData.bluetooth = true
console.log("蓝牙有权限")
resolve(true);
}
},fail:res=>{
console.log("获取蓝牙权限失败")
resolve(false);
}
})
})
}
module.exports = {
startBlueAdapter,
sendMsg,
readMsg,
startBluetoothDevicesDiscovery,
getBluetoothDevices,
onBluetoothDeviceFound,
stopBluetoothDevicesDiscovery,
createBLEConnection,
getBLEDeviceServices,
filterService,
getDeviceCharacter,
notifyBLECharacteristicValueChange,
closeBLEConnection,
closeBluetoothAdapter,
createBluetooth,
oneTouchConnectBluetooth,
ab2hex,
}