蓝牙项目-微信小程序蓝牙使用分享

导语

蓝牙在日常生活中广泛使用的一项技术,小程序给了我们前端工程师一个控制蓝牙的方法,带上你的设备,来看看怎么控制你的蓝牙设备吧。



1. 小程序蓝牙介绍

蓝牙终端:我们常说的硬件设备,包括手机,电脑等等。

设备地址:每个蓝牙设备都有一个设备地址deviceId,但是安卓和IOS差别很大,安卓下设备地址就是mac地址,但是IOS无法获取mac地址,所以设备地址是针对本机范围有效的UUID,所以这里需要注意,后面会介绍。

2. API总览

小程序对蓝牙设备的操作有18个API

API名称说明

openBluetoothAdapter初始化蓝牙适配器,在此可用判断蓝牙是否可用

closeBluetoothAdapter关闭蓝牙连接,释放资源

getBluetoothAdapterState获取蓝牙适配器状态,如果蓝牙未开或不可用,这里可用检测到

onBluetoothAdapterStateChange蓝牙适配器状态发生变化事件,这里可用监控蓝牙的关闭和打开动作

startBluetoothDevicesDiscovery开始搜索设备,蓝牙初始化成功后就可以搜索设备

stopBluetoothDevicesDiscovery当找到目标设备以后需要停止搜索,因为搜索设备是比较消耗资源的操作

getBluetoothDevices获取已经搜索到的设备列表

onBluetoothDeviceFound当搜索到一个设备时的事件,在此可用过滤目标设备

getConnectedBluetoothDevices获取已连接的设备

createBLEConnection创建BLE连接

closeBLEConnection关闭BLE连接

getBLEDeviceServices获取设备的服务列表,每个蓝牙设备都有一些服务

getBLEDeviceCharacteristics获取蓝牙设备某个服务的特征值列表

readBLECharacteristicValue读取低功耗蓝牙设备的特征值的二进制数据值

writeBLECharacteristicValue向蓝牙设备写入数据

notifyBLECharacteristicValueChange开启蓝牙设备notify提醒功能,只有开启这个功能才能接受到蓝牙推送的数据

onBLEConnectionStateChange监听蓝牙设备错误事件,包括异常断开等等

onBLECharacteristicValueChange监听蓝牙推送的数据,也就是notify数据

4,小程序蓝牙的主要流程

1,开启蓝牙:调用openBluetoothAdapter,来判断用户手机的是否支持蓝牙使用

wx.openBluetoothAdapter({

    success: function (res) {

    conosle.log('该用户支持蓝牙的使用')

    wx.getBluetoothAdapterState()调用小程序蓝牙检测是否开启

    },    

    fail(res){

     conosle.log('该用户不支持蓝牙的使用')

    }
})

2, 检查蓝牙状态:调用getBluetoothAdapterState来检查蓝牙是否开启,如果没有开启可以在这里提醒用户开启蓝牙,并且能在开启后自动启动下面的步骤 这里有一个坑:IOS里面蓝牙状态变化以后不能马上开始搜索,否则会搜索不到设备,必须要等待2秒以上。


wx.getBluetoothAdapterState({ //获取本机蓝牙适配器状态 判断用户是否开启蓝牙

      success: res => {

        console.log('蓝牙状态', res)

        //discovering 是否正在搜索设备  available 蓝牙适配器是否可用

        if (res.available == false) {

          wx.showToast({

            title: '设备无法开启蓝牙连接',

            icon: 'none'

          })

        } else if (res.discovering == false){

                //discovering 是否正在搜索设备 

                 wx.startBluetoothDevicesDiscovery() 调用搜索外围设备

        } else if (res.available){

            //available 蓝牙适配器是否可用 

               wx.startBluetoothDevicesDiscovery() 调用搜索外围设备

        }

      }

    })


3,开始搜寻附近的蓝牙外围设备

wx.startBluetoothDevicesDiscovery

开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索并连接到设备后调用( wx.onBluetoothDeviceFound 后结束,下一有介绍改api使用) wx.stopBluetoothDevicesDiscovery 方法停止搜索。

wx.startBluetoothDevicesDiscovery({ //开始搜寻附近的蓝牙外围设备

    services: [this.serviceId], //搜索对应设备的id  以微信硬件平台的蓝牙智能灯为例,主服务的 UUID 是 FEE7。传入这个参数,只搜索主服务 UUID 为 FEE7 的设备

    allowDuplicatesKey:false, 是否允许重复上报同一设备。如果允许重复上报,则 wx.onBlueToothDeviceFound 方法会多次上报同一设备,但是 RSSI 值会有不同。

    success:res =>{

        console.log(res);

      if (!res.isDiscovering) { //是否在搜索到了设备

        this.getBluetoothAdapterState()

      }else{

        console.log('1');

      // this.getSystemInfo()

        this.onBluetoothDeviceFound() //设备参数返回成功 就去执行搜索设备 安卓mac 和 ios uuid (作为连接设备人口参数,安卓得不到mac,ios得不到uuid就无法连接设备成功)

      }

    },

    fail: err => {

      

    }

  })


4,onBluetoothDeviceFound 获取设备的mac和uuid,这里分为两个场景,可以通过wx.getSystemInfo该api来判断是不是安卓或者ios,是安卓手机的话,就获取设备mac地址,是ios的手机的话,就获取uuid(),这里得注意,uuid,设备蓝牙无法识别,要转化成十六进制方法如下:


// ArrayBuffer转16进度字符串示例functionab2hex(buffer){consthexArr =Array.prototype.map.call(newUint8Array(buffer),function(bit){return('00'+ bit.toString(16)).slice(-2) } )returnhexArr.join('')}wx.onBluetoothDeviceFound(function(devices){console.log('new device list has founded')console.dir(devices)console.log(ab2hex(devices[0].advertisData))})

wx.onBluetoothDeviceFound((res) => {

const that=this;

    res.devices.forEach(device => {

      console.log(device)    

             that.advertisData(写死的mac地址) 我这里是从后台接口获取的,你们做测试的话,可以写死

      if (_advertisData == that.advertisData)

            that.advertisData=_advertisData  advertisData 保存在全局变量,因为蓝牙连接的时候需要使用他

            wx.setStorageSync('device', device.deviceId)//第一搜索到设备 保存在本地,给下次连接蓝牙的时候使用,下次俩连接相同的蓝牙的时候,就不需要再次去执行这个api-onBluetoothDeviceFound


      wx. stopBluetoothDevicesDiscovery() // 设备匹配的化已经搜索到,停止搜索

        console.log('设备已经搜索到,停止搜索')

    wx.createBLEConnection() 这个去执行连接方法

      }

    })

  })


5,wx.createBLEConnection

连接低功耗蓝牙设备。

若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。


连接设备这里,建议大家延迟一下和做递归循环处理,最好是10次左右把,过快连接和一次连接会出现连接失败,安卓手机概率性特别打,在项目中被坑死了,哈哈,现在已经半死不活,跟大家开一个小玩笑,快乐一下。
setTimeout(() => {

    wx.createBLEConnection({

      deviceId: this.deviceId,

      success: res => {

        console.log('连接', res)

        if (res.errCode == 0) {

         wx.showToast({

            title: '蓝牙连接设备成功',

            icon: 'none'

          })

        连接成功以后就开始查询设备的服务列表:getBLEDeviceServices,然后根据目标服务ID或者标识符来找到指定的服务ID

       getBLEDeviceServices(this.deviceId)

        }

      },

      fail: err => {

        self.openlock(count++);

        // console.log('连接失败:', err)

    })

  }, 500)


6,getBLEDeviceServices  获取蓝牙设备所有服务(service)。

这里有个坑的地方:如果是安卓下如果你知道设备的服务ID,你可以省去getBLEDeviceServices的过程,但是IOS下即使你知道了服务ID,也不能省去getBLEDeviceServices的过程,这是小程序里面需要注意的一点。

   

wx.getBLEDeviceServices({

// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId, success(res) {


返回的参数
uuidstring蓝牙设备服务的 uuid

isPrimaryboolean该服务是否为主服务

console.log('device services:', res.services) 

 }})



7  ,

获取服务特征值:每个服务都包含了一组特征值用来描述服务的一些属性,比如是否可读,是否可写,是否可以开启notify通知等等,当你跟蓝牙通信时需要这些特征值ID来传递数据。

,wx.getBLEDeviceCharacteristics({

// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId,

// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId, 

 success(res) {console.log('device getBLEDeviceCharacteristics:', res.characteristics) }

})


8,获取特征值ID以后就可以开启notify通知模式,同时开启监听特征值变化消息

wx.notifyBLECharacteristicValueChange({

  state: true,

  deviceId: device_id,

  serviceId: service_id,

  characteristicId:notify_id,

  complete(res) {

  },

  fail(res){

    console.log(res);

  }

})




9.writeBLECharacteristicValue 向小程序写人二进制数据

这里面有个坑:开启notify以后并不能马上发送消息,蓝牙设备有个准备的过程,需要在setTimeout中延迟1秒以上才能发送,否则会发送失败

writeBLECharacteristicValue = function (deviceId, serviceId, buffer) {

//deviceIdstring是蓝牙设备 id

//serviceIdstring是蓝牙特征值对应服务的 uuid

//characteristicIdstring是蓝牙特征值的 uuid

//valueArrayBuffer是蓝牙设备特征值对应的二进制值

  return new Promise((resolve, reject) => {

    wx.writeBLECharacteristicValue({

      deviceId,//设备的 id

      serviceId, //0000FFF0-0000-1000-8000-00805F9B34FB

      characteristicId: this.characteristicId,//0000FFF6-0000-1000-8000-00805F9B34FB

      value: buffer,//蓝牙设备特征值对应的二进制值

      success: res => { resolve(res) },

      fail: err => { reject(err) }

    })

  })

}



10,最后工作完成 断开小程序蓝牙

断开与低功耗蓝牙设备的连接。

wx.closeBLEConnection({

  deviceId: device_id,

  success(res) {

    console.log(res)

  },

  fail(res) {

    console.log(res)

  }

})



关闭蓝牙模块。调用该方法将断开所有已建立的连接并释放系统资源。建议在使用蓝牙流程后,与 wx.openBluetoothAdapter 成对调用。

wx.closeBluetoothAdapter({

  success: function (res) {

    console.log(res)

  }

})


推荐阅读更多精彩内容