微信小程序蓝牙通信

版权声明:本文为博主原创文章,未经博主允许不得用于任何商业用途,转载请注明出处。 https://blog.csdn.net/fyyyr/article/details/82963194

微信小程序目前只支持低功耗蓝牙(BLE),不支持经典蓝牙。

微信小程序的当前最新版本为2.3.0,根据实际测试,IOS支持很好但对Android支持非常不好,各厂商的Android手机遇到的问题也不一样。因此要开发蓝牙功能,推荐只提供IOS版本。

 

小程序与蓝牙进行通信的过程如下:

  • 打开小程序的蓝牙模块(wx.openBluetoothAdapter)。
  • 搜索蓝牙设备(wx.startBluetoothDevicesDiscovery)。需要调用接口(wx.stopBluetoothDevicesDiscovery)来停止搜索。
  • 获取所有蓝牙设备(wx.getBluetoothDevices)。
  • 连接蓝牙设备(wx.createBLEConnection)。
  • 获取service(wx.getBLEDeviceServices)。与设备连接之后,即可调用接口来获取该设备的所有service。接口会返回一个service数组。
  • 获取characteristic(wx.getBLEDeviceCharacteristics)。此时可以启用notify(wx.notifyBLECharacteristicValueChange)并设置监听(wx.onBLECharacteristicValueChange)。
  • 向蓝牙设备写入数据(wx.writeBLECharacteristicValue),等待监听返回。写入的数据必须是ArrayBuff类型。
  • 通信完毕,断开与蓝牙设备的连接(wx.closeBLEConnection)。
  • 关闭小程序蓝牙模块(wx.closeBluetoothAdapte)。

 

关于其中各个要点的详细解释:

蓝牙模块

微信小程序提供了一个蓝牙模块,用于为自身提供蓝牙功能支持。小程序蓝牙模块属于小程序,而不是手机。手机的蓝牙是否打开与小程序蓝牙模块是否打开是无关的。可以类比为家中的网络:手机蓝牙就是网络供应商提供的服务,而小程序蓝牙是家中路由器。

  • 无论网络供应商是否提供服务,我们的路由器都可以打开/关闭(无论手机蓝牙是否打开,小程序蓝牙模块都可以打开/关闭)。
  • 即使网络供应商提供了服务,若路由器关闭,我们是无法使用网络服务的(手机蓝牙打开,但小程序蓝牙模块关闭,则依然无法使用蓝牙服务)。
  • 若网络供应商未提供服务,即使路由器打开,依然无法使用网络服务,但此时路由器是可以检测到网络状况的(手机蓝牙关闭,但小程序蓝牙打开,无法使用蓝牙服务。但小程序蓝牙模块能检测到手机蓝牙是否打开,并且在有相应权限的情况下,小程序蓝牙模块可以申请打开手机蓝牙)。

 

搜索蓝牙设备

即使手机已经打开蓝牙并已经搜索到了一些设备,但对于小程序蓝牙模块而言,并不知道已经发现了哪些设备,必须经过搜索才能获取所有蓝牙设备列表。 搜索是一个持续的动作,必须调用关闭接口(wx.stopBluetoothDevicesDiscovery)才会停止,否则会一直搜索。

 

获取所有蓝牙设备

调用获取所有蓝牙设备接口,会返回小程序所记录的蓝牙设备列表。这一步通常在调用了小程序的搜索蓝牙设备功能之后进行。而由于搜索是一个持续的动作,所以当发现返回的设备列表中出现了目标设备后,就可以调用关闭接口来停止搜索。

若返回的设备列表中没有目标设备,则可等待几秒,让搜索继续进行,然后再次调用获取所有蓝牙设备的接口。反复该过程,直到发现目标设备。

微信小程序目前只支持低功耗蓝牙,不支持经典蓝牙。对于经典蓝牙设备,手机蓝牙可以搜到,但小程序蓝牙的获取所有蓝牙设备列表中是没有的。同时,对于某些低功耗蓝牙设备也可能无法列出,比如蓝牙耳机。

 

连接蓝牙设备

搜索到的设备会提供deviceId。使用该deviceId即可调用接口来创建与设备的连接。

若设备已与手机进行配对,则可直接创建连接;否则会弹出配对提示框。

小程序对连接的蓝牙设备数量并没有限制,但手机有。Android手机一般是5-10个,而IOS多一些。

 

servicecharacteristic

与经典蓝牙不同,低功耗蓝牙(BLE)的通信使用service(服务)与characteristic(蓝牙设备特征值)。

service即提供的服务。BLE提供多个service。实际使用过程中,若能满足具体需求,则使用哪个service都是可以的。至于一个service是否能满足需求,这要看该service下是否有合适的characteristic。

每个service下有多个characteristic。一个characteristic结构如下:

{
    "properties": {
        "notify": false, 
        "write": true, 
        "indicate": false, 
        "read": true
    }, 
    "uuid": "49535343-6DAA-4D02-ABF6-19569ACA69FE"
}

其中:

  • uuid:characteristic的id。
  • properties:characteristic的操作类型。有4个属性:read,write,notify,indicate。这4个属性之间没有制约关系。每个属性可以为true(表示支持该操作)或false(表示不支持该操作)。

characteristic是进行蓝牙通信的媒介。例如要对蓝牙设备进行写操作,那么就需要使用write为true的characteristic;要对蓝牙设备进行读操作,那么就需要使用read为true的characteristic;要对蓝牙设备进行接收数据监听,那么就需要使用notify为true的characteristic。

characteristic的4个属性由于相互独立,所以characteristic下的属性可以有0-4个为true。因此,若一个characteristic的read和write为true,则该characteristic就既支持读操作,又支持写操作。

characteristic只是一个媒介,并不存储数据,所以只要一个characteristic具有我们需要的权限,那么就可以用来进行蓝牙通信。满足需求的characteristic可能有多个,使用其中一个即可。

但是由于characteristic是service下的,对于同一个设备而言,只要确保同一个service下的characteristic的id不同即可,因此不同service下的characteristic的id是可以相同的。所以,characteristicid可以使用硬编码,或者自定义的规则。

同理,不同设备的service也是相互隔离的,因此不同设备serviceid也是可以相同的。所以,serviceid也可以使用硬编码或者自定义的规则,只要确保同一设备下的各个serviceid不同即可。

实际开发过程中,需要确认具体的蓝牙设备通信使用哪个characteristic。例如,蓝牙设备指定了必须使用某个characteristic来进行write操作,那么即使其他的characteristic的write属性也为true,执行write操作也返回成功,但蓝牙设备很可能是不响应的。

蓝牙通信往往也并不是只依赖一个characteristic,而是多个characteristic配合的结果。例如,使用一个write为true的characteristic(设为A)来进行写操作,同时使用一个notify为true的characteristic(设为B)来进行数据监听。使用A对蓝牙设备执行写操作,然后A的任务就完成了。若蓝牙设备有数据返回,则B会监听到,并调用用户自定义的回调函数。

常规的通信有两种方式:

  • 发出请求,然后等待返回。返回的参数中带有所需要的结果。
  • 设置监听。发出请求,然后等待返回。返回的是该次请求是否成功,并不带有结果。当请求接收方需要返回数据时,设置的监听会监听到。

BLE的蓝牙通信使用第二种方式。因此,实际的蓝牙通信过程中,使用read操作的很少,往往是一个writetruecharacteristic配合一个notifytruecharacteristic来进行通信

执行write操作时,需要对蓝牙设备write指定的命令,这个是硬件提供的。调用的wx.writeBLECharacteristicValue需要传入一个value参数,该参数是一个ArrayBuff类型,因此需要将写入的命令转为二进制形式存储在这里。

猜你喜欢

转载自blog.csdn.net/fyyyr/article/details/82963194