赞
踩
由于最近的项目在做小程序蓝牙通讯这块的内容,所以将实现的过程在这简单的记录下。
1、首先要初始化蓝牙-检查蓝牙适配器是否打开
- async initBluetooth(): Promise<void> {
- return new Promise((resolve: any, reject: any) => {
- const _this = this
- if (BluetoothController.adapterOpend) {
- console.log("蓝牙适配器已打开")
- resolve(true)
- return
- }
- wx.openBluetoothAdapter({
- success(res) {
- BluetoothController.adapterOpend = true
- console.log("=====*****蓝牙适配器已打开")
- resolve(true)
- },
- fail(error) { //用来判断蓝牙是否已打开
- reject(error)
- BluetoothController.adapterOpend = false
- console.log("=====*****蓝牙适初始化失败", error)
- }
- })
- })
- }
-
- //使用案例
- initBluetooth().then()
2、开始搜寻附近的蓝牙外围设备
- /**
- * @param options
- * options.keywords 蓝牙名称筛选关键字
- * options.deviceid 可选参数,蓝牙设备id,连接用
- */
- async searchAroundBLE(options: any): Promise<void> {
- return new Promise((resolve: any, reject: any) => {
- const _this = this
- if (_this.startDiscovery) {
- console.log("已开启蓝牙扫描,勿重复开启")
- resolve(true)
- return
- }
- _this.startDiscovery = true
- wx.startBluetoothDevicesDiscovery({
- allowDuplicatesKey: true,
- services: options.services,
- success(res) {
- console.log('搜索成功', res);
- resolve(true)
-
- },
- fail(error) {
- reject(error)
- _this.startDiscovery = false
- },
- })
- })
-
- }
-
-
- //使用案例
- searchAroundBLE({ 'keywords': [''], services: [] }).then()
3、监听搜索到的设备
- /**
- * @param options
- * options.keywords 蓝牙名称筛选关键字
- * options.deviceid 可选参数,蓝牙设备id,连接用
- */
- async onBluetoothDeviceFound(options: any): Promise<void> {
- return new Promise((resolve: any, reject: any) => {
- let _this = this
- let { keywords } = options
- // 超时自动结束
- _this.findTimer = setTimeout(() => {
- clearTimeout(_this.findTimer)
- if (!_this.connectStatus) {
- reject({
- success: false
- })
- console.log('蓝牙扫描超时,自动关闭任务')
- }
- }, 3000); //时间根据自己的需求定
- let arr: any = []
- wx.onBluetoothDeviceFound(res => {
- let devices = res.devices;
- devices.forEach((device) => {
- if (!device.name && !device.localName) {
- return
- }
- // 获取设备MAC地址,并根据关键字过滤
- let systemInfo = wx.getSystemInfoSync()
- let iosDevice = systemInfo.system.toLowerCase().indexOf("ios") > -1;
- let deviceMac = iosDevice ? uuid2Mac(device.advertisData) : device.deviceId
- // keywords
- if (keywords && keywords.length > 0) {
- let key = keywords[0]
- if (device.name.indexOf(key) >= 0) {
- arr.push({
- ...device,
- deviceMac
- })
- }
- if (arr.length) {
- let foundDevices = arr
- _this.deviceList = foundDevices
- resolve({
- data: arr,
- success: true
- })
- }
- }
- })
- })
-
- })
-
- }
-
-
- /**
- * 统一安卓与IOS端deviceId展示
- * @param advertisData
- * 在安卓设备中,获取到的 deviceId 为设备 MAC 地址,iOS 上则为设备 uuid,
- * 因此为了展示一致需要将ios的展示进行输入(当然IOS的连接还是得用获取到的uuid)
- */
- function uuid2Mac(advertisData: any) {
- if (advertisData) {
- let mac = Array.prototype.map
- .call(new Uint8Array(bf), (x) => ("00" + x.toString(16)).slice(-2))
- .join(":");
- mac = mac.toUpperCase();
- return mac;
- }
- }
-
-
- 使用案例: onBluetoothDeviceFound({ 'keywords': [''] }).then() //keywords根据自己的需求去定,
4、处理蓝牙连接(搜索到设备开始蓝牙链接)
- /**
- * @param {string} options.deviceId 蓝牙设备id,连接用
- */
- async createBLEConnection(options: any): Promise<void> {
- return new Promise((resolve: any, reject: any) => {
- let { deviceId } = options,_this = this
- _this.deviceId = deviceId
- if (_this.connectStatus) {
- wx.closeBLEConnection({
- deviceId
- })
- }
- let timeout = 3000 //根据自己需求去定
- console.log('开始连接蓝牙--', deviceId)
- _this.stopBLEDevicesTask()
- wx.createBLEConnection({
- deviceId,
- timeout,
- success(res) {
- console.log('蓝牙连接成功-----', deviceId)
- _this.connectStatus = true
-
- resolve(true)
- },
- fail() {
- _this.connectStatus = false
- reject(false)
- }
- })
- })
- }
-
-
- 使用案例: createBLEConnection({ deviceId: tmp[0].deviceId }).then()
5、连接成功后,要获取蓝牙的所有服务 进而根据项目需求的服务 去获取对应的特征 来进行读写操作
- /**
- * @param deviceId 蓝牙设备Id,来自createBLEConnection调用
- */
- async getBLEDeviceServices(deviceId: any): Promise<void> {
- return new Promise((resolve: any, reject: any) => {
- let _this = this
- wx.getBLEDeviceServices({
- deviceId,
- success(res) {
- /**
- * 16 位 UUID 从对接文档中获取(注意都是0000开头,接着的4位数字为16进制的uuid,所有服务只有4位uuid不一样)
- 注意有多个服务,不同服务的操作不一样,单个服务只能执行单个操作,所以这里需要建立多个连接
- */
- for (let i = 0; i < res.services.length; i++) {
- // 注意uuid的大小写
- if (
- res.services[i].isPrimary &&
- res.services[i].uuid == "0000D0FF-0000-1000-8000-008cbhschs" //设备id,根据自己的项目去走
- ) {
- // _this.getBLEDeviceCharacteristics(res.services[i].uuid);
- resolve({
- data: res.services[i].uuid,
- sucess: true
- })
- return;
- }
- }
- },
- fail: (res) => {
- reject({
- sucess: false,
- data: res.errMsg
- })
- console.log("服务获取失败------------->", res.errMsg);
- },
- });
- })
- }
-
-
- async getBLEDeviceCharacteristics(serviceId: any): Promise<void> {
- return new Promise((resolve: any, reject: any) => {
- let _this = this
- wx.getBLEDeviceCharacteristics({
- deviceId: _this.deviceId, //设备id根据自己项目的去赋值
- serviceId, //服务id
- success: (res) => {
- // 设备特征列表
- let characteristics = res.characteristics;
- for (let i = 0; i < characteristics.length; i++) {
- let item = characteristics[i];
- if (item.properties.write) {
- this.serviceId = serviceId
- this.characteristicId = item.uuid
- }
- if (item.properties.read) {
- wx.readBLECharacteristicValue({
- deviceId: _this.deviceId,
- serviceId,
- characteristicId: item.uuid
- });
- }
- if (item.properties.write) {
- // resolve({
- // data: 1,
- // sucess: true
- // })
- }
- if (item.properties.notify || item.properties.indicate) {
- /* 启用蓝牙低功耗设备特征值变化时的 notify 功能,订阅特征。注 意:必须设备的特征支持 notify 或者 indicate 才可以成功调用。
- 另外,必须先启用 wx.notifyBLECharacteristicValueChange 才能监听到设备 characteristicValueChange 事件*/
-
- wx.notifyBLECharacteristicValueChange({
- deviceId: _this.deviceId,
- serviceId,
- characteristicId: item.uuid,
- state: true,
- });
- resolve({
- data: item.properties,
- sucess: true
- })
- }
- }
- },
- fail(error: any) {
- reject({
- sucess: false,
- data: error
- })
- }
- });
- })
- }
-
- 使用案例: let { data } = await getBLEDeviceServices(tmp[0].deviceId) //data就是所有服务内容
- if (data) {
- // 2、获取蓝牙低功耗设备某个服务中所有特征 (characteristic)
- let ble_chart = await getBLEDeviceCharacteristics(data)
- if (ble_chart.sucess) {
- let item = ble_chart.data
- // 该特征是否支持 write 操作
- if (item.write) {
- // resolve(true)
- this.handleWriteSucess(); //处理写操作
- }
- // 该特征是否支持 notify ,indicate操作 ,开启监听订阅特征消息
- if (item.notify || item.indicate) {
- this.watchBleData()//监听蓝牙数据
- }
- }
- }
6、读写成功后开始根据蓝牙协议进行操作(蓝牙协议有设备方提供)
- handleWriteSucess() //写成功后的操作
- watchBleData() {
- wx.onBLECharacteristicValueChange(async (res) => { //监听蓝牙数据变化
- let resHex = ab2hex(res.value).toLocaleUpperCase() //包数据, 根据蓝牙协议去进行处理
- let { data } = writeBLECharacteristicValue('对应指令', '脚电极')
- })
- }
-
- /**
- * ArrayBuffer转16进度字符串
- * @param buffer
- */
- // ArrayBuffer转16进度字符串
- ab2hex(buffer: any) {
- var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
- return ("00" + bit.toString(16)).slice(-2);
- });
- return hexArr.join("");
- }
7、处理蓝牙写指令
- /**
- * 4. 发送蓝牙指令。蓝牙指令超出20字符时需要截断多次发送
- * @param {string} cmdStr 蓝牙指令
- * @param {string} cmdName 蓝牙指令名称——可选用于打印调试
- */
- async writeBLECharacteristicValue(cmdStr: any, cmdName: string): Promise<void> {
- // // console.log("发送蓝牙指令------------》", cmdStr, cmdName);
- return new Promise((resolve: any, reject: any) => {
- let _this = this
- let data = cmdStr.split(',')
- let buffer = new ArrayBuffer(data.length);
- let dataViewLast = new DataView(buffer);
- for (let i = 0; i < data.length; i++) {
- dataViewLast.setUint8(i, data[i]);
- }
- let param: any = {
- deviceId: _this.deviceId,
- serviceId: _this.serviceId,
- characteristicId: _this.characteristicId, //在获取特性那有
- value: dataViewLast.buffer,
- };
- console.log("param", param)
- wx.writeBLECharacteristicValue({
- ...param,
- success: function () {
- console.log("发送指令成功", cmdName);
- resolve({
- data: {
- cmdName,
- sucess: true
- }
- })
- },
- fail: function (error: any) {
- reject({
- data: {
- data: error,
- sucess: true
- }
- })
- },
- })
- })
-
- }
注意点:
在判断蓝牙是否打开之前,还要先判断下手机上位置是否打开
let locationEnabled = wx.getSystemInfoSync().locationEnabled
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。