微信小程序调用手机蓝牙

在开发当中需要去和硬件交互,需要蓝牙去发送命令,发现蓝牙交互还是需要挺多的歪歪绕绕的,记录一下:

首先在微信小程序里我们需要几个变量:

const BluetoothDetail = {
  inputValue: '',//想要链接的蓝牙设备id
  deviceId: '',//设备ID
  services: '',//蓝牙设备的uuid
  notify: '',//支持notify的特征值
  write: '',//支持write的特征值
  returnValue:'',//返回的token
  returnValue2:''//开锁后的返回
}

虽然在上面的几个值都是相同的但是微信还是让我们区分开来。

1.判断蓝牙是否打开

  //1. 判断用户手机蓝牙是否打开
   wx.openBluetoothAdapter({//调用微信小程序api 打开蓝牙适配器接口
    success: function (res) {
      wx.showToast({
        title: '初始化成功',
        icon: 'success',
        duration: 800
      })
    },
    fail: function (res) {//如果手机上的蓝牙没有打开,可以提醒用户
      wx.showToast({
        title: '请开启蓝牙',
        icon: 'fails',
        duration: 1000
      })
    }
  })

2.搜索附近的蓝牙设备

 //2.搜索附近蓝牙设备
wx.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: false,
    interval: 0,
    success: function (res) {
      wx.showLoading({
        title: '正在搜索设备',
      })
    }
  })

3.获取蓝牙信息

这里我们获取的蓝牙设备是集合,多个的,所以我们需要变量获取我们想要获取的那个蓝牙的id名称

  //3.获取蓝牙设备信息
   wx.getBluetoothDevices({
    success: function (res) {
      wx.hideLoading();
      if (res.devices.length>0){
        for (var i = 0; i < res.devices.length; i++) {
          console.log(res.devices[i])
          if (res.devices[i].deviceId == BluetoothDetail.inputValue ||
              res.devices[i].localName == BluetoothDetail.inputValue) {
            BluetoothDetail.deviceId = res.devices[i].deviceId
            //进行连接的调用
            break
          }
          if (res.devices.length-1==i){
            //搜索附近蓝牙的回调
          }
        }
      }else{
        //搜索附近蓝牙的回调
      }
    },
    fail: function () {
      console.log("搜索蓝牙设备失败")
    }
  })
}

4.开始建立与蓝牙设备链接

 //4.通过蓝牙设备的id进行蓝牙连接
  wx.createBLEConnection({
    deviceId: BluetoothDetail.deviceId,//设备id
    success: function (res) {
      wx.showToast({
        title: '连接成功',
        icon: 'fails',
        duration: 800
      })
      wx.stopBluetoothDevicesDiscovery({
        success: function (res) {
          console.log('连接蓝牙成功之后关闭蓝牙搜索')
        }
      })
      //获取服务uuid
    }
  })

5.获取服务的UUID

  //5.获取服务的uuid
   wx.getBLEDeviceServices({
    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
    deviceId: BluetoothDetail.deviceId,
    success: function (res) {
      var model = res.services[0]
      BluetoothDetail.services=model.uuid
      console.log("services: " + BluetoothDetail.services);
      //判断蓝牙值的特性值
    }
  })

6.判断蓝牙设备的特性值

  wx.getBLEDeviceCharacteristics({
    deviceId: BluetoothDetail.deviceId,
    serviceId: BluetoothDetail.services,
    success: function (res) {
      for (var i = 0; i < res.characteristics.length; i++) {//2个值
        var model = res.characteristics[i]
        if (model.properties.notify == true) {
          BluetoothDetail.notifyId= model.uuid//监听的值
          console.log("notifyId: " + BluetoothDetail.notifyId)
          //notify
        }
        if (model.properties.write == true) {
            BluetoothDetail.writeId=model.uuid//用来写入的值
          console.log("writeId: " + BluetoothDetail.writeId)
        }
      }
    }
  })

7.启用 notify 功能,只有启用该功能才能进行读写、获取信息等操作。

  wx.notifyBLECharacteristicValueChange({
    state: true, // 启用 notify 功能
    deviceId: BluetoothDetail.deviceId,
    serviceId: BluetoothDetail.services,
    characteristicId: BluetoothDetail.notifyId,  //第一步 开启监听 notityid  第二步发送指令 write
    success: function (res) {
      var str1 = 'CAFB4AC988966A676339FE490705B1F9'

      sendMy(string2buffer(str1))
    }
  })

8.向设备写入数据

 // 8.写入蓝牙设备 内容
   wx.writeBLECharacteristicValue({
    deviceId: BluetoothDetail.deviceId,
    serviceId: BluetoothDetail.services,
    characteristicId: BluetoothDetail.writeId,//第二步写入的特征值
    value: buffer,
    success: function (res) {
      console.log("写入成功")
      wx.onBLECharacteristicValueChange(function (characteristic) {//回调用来接收蓝牙设备返回的信息,需要转为字符串
        BluetoothDetail.returnValue=ab2hex(characteristic.value)//用来写入的值
        console.log("returnValue:  "+BluetoothDetail.returnValue)
      })
    },
    fail: function () {
      console.log('写入失败')
    },
  })

工具方法

这里微信小程序和蓝牙设备的交互需要进行加密解密, 发送需要进行ArrayBufer,接收需要转为字符串,所以需要下面两个工具方法进行转换

 // 将字符串转换成ArrayBufer
  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
  },

  /**
   * 将ArrayBuffer转换成字符串
   */
  ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  },

后续还有几个交互的方法:

蓝牙连接断开

wx.closeBLEConnection({
	deviceld: deviceld,
	 complete: function (res) {
	 	//断开连接后一些参数逻辑的处理
	 }
wx.showToast({
	ititle: '蓝牙连接断开',
	icon: 'success', 
	duration: 2000})
})

释放蓝牙适配器

wx.closeBluetoothAdapter( {
	success: function (res) { 
		//一些释放后的逻辑
		wx.showToast({
			title: '蓝牙适配器释放',
			icon: 'success',
			duration: 2000
		 	})
	}
	fail: function (res) {}
})

一般我蓝牙放在utlis下的一个js文件里:

const util = require('util.js')
const BluetoothDetail = {
  inputValue: '',//想要链接的蓝牙设备id
  deviceId: '',//设备ID
  services: '',//蓝牙设备的uuid
  notify: '',//支持notify的特征值
  write: '',//支持write的特征值
  returnValue:'',//返回的token
  returnValue2:''//开锁后的返回
}

// 1.判断用户手机蓝牙是否打开
const bluetooth = inputValue => {
  BluetoothDetail.inputValue=inputValue
  wx.openBluetoothAdapter({//调用微信小程序api 打开蓝牙适配器接口
    success: function (res) {
      wx.showToast({
        title: '初始化成功',
        icon: 'success',
        duration: 800
      })
      findBlue();//2.0
    },
    fail: function (res) {//如果手机上的蓝牙没有打开,可以提醒用户
      wx.showToast({
        title: '请开启蓝牙',
        icon: 'fails',
        duration: 1000
      })
    }
  })
}
//2.搜索附近蓝牙设备
const findBlue = () => {
  wx.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: false,
    interval: 0,
    success: function (res) {
      wx.showLoading({
        title: '正在搜索设备',
      })
      getBlue()//3.0
    }
  })
}

//3.获取蓝牙设备信息
const getBlue = () => {
  console.log("getBlue")
  wx.getBluetoothDevices({
    success: function (res) {
      wx.hideLoading();
      if (res.devices.length>0){
        for (var i = 0; i < res.devices.length; i++) {
          console.log(res.devices[i])
          if (res.devices[i].deviceId == BluetoothDetail.inputValue ||
              res.devices[i].localName == BluetoothDetail.inputValue) {
            BluetoothDetail.deviceId = res.devices[i].deviceId
            connetBlue();//4.0
            break
          }
          if (res.devices.length-1==i){
            findBlue()
          }
        }
      }else{
        findBlue()
      }
    },
    fail: function () {
      console.log("搜索蓝牙设备失败")
    }
  })
}
//4.通过蓝牙设备的id进行蓝牙连接
const connetBlue = () => {
  wx.createBLEConnection({
    deviceId: BluetoothDetail.deviceId,//设备id
    success: function (res) {
      wx.showToast({
        title: '连接成功',
        icon: 'fails',
        duration: 800
      })
      wx.stopBluetoothDevicesDiscovery({
        success: function (res) {
          console.log('连接蓝牙成功之后关闭蓝牙搜索')
        }
      })
      getServiceId()//5.0
    }
  })
}
//5.获取服务的uuid
const getServiceId = () => {
  wx.getBLEDeviceServices({
    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
    deviceId: BluetoothDetail.deviceId,
    success: function (res) {
      var model = res.services[0]
      BluetoothDetail.services=model.uuid
      console.log("services: " + BluetoothDetail.services);
      getCharacteId()//6.0
    }
  })
}
//6.判断蓝牙设备的特性值
const getCharacteId = () => {
  wx.getBLEDeviceCharacteristics({
    deviceId: BluetoothDetail.deviceId,
    serviceId: BluetoothDetail.services,
    success: function (res) {
      for (var i = 0; i < res.characteristics.length; i++) {//2个值
        var model = res.characteristics[i]
        if (model.properties.notify == true) {
          BluetoothDetail.notifyId= model.uuid//监听的值
          console.log("notifyId: " + BluetoothDetail.notifyId)
          startNotice(BluetoothDetail.notifyId)//7.0
        }
        if (model.properties.write == true) {
            BluetoothDetail.writeId=model.uuid//用来写入的值
          console.log("writeId: " + BluetoothDetail.writeId)
        }
      }
    }
  })
}
//7.notify
const startNotice = uuid => {
  wx.notifyBLECharacteristicValueChange({
    state: true, // 启用 notify 功能
    deviceId: BluetoothDetail.deviceId,
    serviceId: BluetoothDetail.services,
    characteristicId: uuid,  //第一步 开启监听 notityid  第二步发送指令 write
    success: function (res) {
      var str1 = 'CAFB4AC988966A6aasf0705B1F9' //想写入的16进制的16位的字符串

      sendMy(string2buffer(str1))
    }
  })
}
// 8.写入蓝牙设备 内容获取token
const sendMy = buffer => {
  wx.writeBLECharacteristicValue({
    deviceId: BluetoothDetail.deviceId,
    serviceId: BluetoothDetail.services,
    characteristicId: BluetoothDetail.writeId,//第二步写入的特征值
    value: buffer,
    success: function (res) {
      console.log("写入成功")
      wx.onBLECharacteristicValueChange(function (characteristic) {
        BluetoothDetail.returnValue=ab2hex(characteristic.value)//用来写入的值
        console.log("returnValue:  "+BluetoothDetail.returnValue)
        var param = {
          str: BluetoothDetail.returnValue
        }
        mutaul(param)
      })
    },
    fail: function () {
      console.log('写入失败')
    },
  })
}
// 与后端交互获取密码
const mutaul = param => {
  util.postJson({
    url: 'http://192.168.0.105:8089/api/device/encrypt',
    data: { ...param },
    success: function (resp) {
      console.log("发送给后端成功")
      pwd(string2buffer(resp.msg))
    },
    fail: function () {
      console.log('发送给后端失败')
    },
  })
}
// 密码发送
const pwd = buffer => {
  wx.writeBLECharacteristicValue({
    deviceId: BluetoothDetail.deviceId,
    serviceId: BluetoothDetail.services,
    characteristicId: BluetoothDetail.writeId,//第二步写入的特征值
    value: buffer,
    success: function (res) {
      console.log("写入成功")
      wx.onBLECharacteristicValueChange(function (characteristic) {
        BluetoothDetail.returnValue2=ab2hex(characteristic.value)//用来写入的值
        console.log("returnValue2:  "+BluetoothDetail.returnValue2)
      })
    },
    fail: function () {
      console.log('写入失败')
    },
  })
}
// 将字符串转换成ArrayBufer
const 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
}
const ab2hex = buffer => {
  var hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('');
}
module.exports = { 
  bluetooth: bluetooth
  };
  • 5
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值