• 微信小程序--Ble蓝牙

    2017-04-07 09:07:16
    没有写关于小程序的文章了。3月28日,微信的api又一次新的更新。期待已久的蓝牙api更新。就开始撸一番。源码地址1.简述 蓝牙适配器接口是基础库版本 1.1.0 开始支持。 iOS 微信客户端 6.5.6 版本开始支持,Android ...

    在前面已经写了两篇关于Android蓝牙和ios 蓝牙开发的文章,今天带来的是微信小程序蓝牙实现。

    有一段时间没有。没有写关于小程序的文章了。3月28日,微信的api又一次新的更新。期待已久的蓝牙api更新。就开始撸一番。

    源码地址

    1.简述

    • 蓝牙适配器接口是基础库版本 1.1.0 开始支持。
    • iOS 微信客户端 6.5.6 版本开始支持,Android 客户端暂不支持
    • 蓝牙总共增加了18个api接口。

    2.Api分类

    • 搜索类
    • 连接类
    • 通信类

    3.API的具体使用

    详细见官网:

    https://mp.weixin.qq.com/debug/wxadoc/dev/api/bluetooth.html#wxgetconnectedbluethoothdevicesobject

    4. 案例实现

    4.1 搜索蓝牙设备

    /**
     * 搜索设备界面
     */
    Page({
      data: {
        logs: [],
        list:[],
      },
       onLoad: function () {
        console.log('onLoad')
    var that = this;
    // const SDKVersion = wx.getSystemInfoSync().SDKVersion || '1.0.0'
    // const [MAJOR, MINOR, PATCH] = SDKVersion.split('.').map(Number)
    // console.log(SDKVersion);
    // console.log(MAJOR);
    // console.log(MINOR);
    // console.log(PATCH);
    
    // const canIUse = apiName => {
    //   if (apiName === 'showModal.cancel') {
    //     return MAJOR >= 1 && MINOR >= 1
    //   }
    //   return true
    // }
    
    // wx.showModal({
    //   success: function(res) {
    //     if (canIUse('showModal.cancel')) {
    //       console.log(res.cancel)
    //     }
    //   }
    // })
         //获取适配器
          wx.openBluetoothAdapter({
          success: function(res){
            // success
            console.log("-----success----------");
             console.log(res);
             //开始搜索
           wx.startBluetoothDevicesDiscovery({
      services: [],
      success: function(res){
        // success
         console.log("-----startBluetoothDevicesDiscovery--success----------");
         console.log(res);
      },
      fail: function(res) {
        // fail
         console.log(res);
      },
      complete: function(res) {
        // complete
         console.log(res);
      }
    })
    
    
          },
          fail: function(res) {
             console.log("-----fail----------");
            // fail
             console.log(res);
          },
          complete: function(res) {
            // complete
             console.log("-----complete----------");
             console.log(res);
          }
        })
    
         wx.getBluetoothDevices({
           success: function(res){
             // success
             //{devices: Array[11], errMsg: "getBluetoothDevices:ok"}
             console.log("getBluetoothDevices");
             console.log(res);
              that.setData({
              list:res.devices
              });
              console.log(that.data.list);
           },
           fail: function(res) {
             // fail
           },
           complete: function(res) {
             // complete
           }
         })
    
      },
      onShow:function(){
    
    
      },
       //点击事件处理
      bindViewTap: function(e) {
         console.log(e.currentTarget.dataset.title);
         console.log(e.currentTarget.dataset.name);
         console.log(e.currentTarget.dataset.advertisData);
    
        var title =  e.currentTarget.dataset.title;
        var name = e.currentTarget.dataset.name;
         wx.redirectTo({
           url: '../conn/conn?deviceId='+title+'&name='+name,
           success: function(res){
             // success
           },
           fail: function(res) {
             // fail
           },
           complete: function(res) {
             // complete
           }
         })
      },
    })
    

    4.2连接 获取数据

    
    /**
     * 连接设备。获取数据
     */
    Page({
        data: {
            motto: 'Hello World',
            userInfo: {},
            deviceId: '',
            name: '',
            serviceId: '',
            services: [],
            cd20: '',
            cd01: '',
            cd02: '',
            cd03: '',
            cd04: '',
            characteristics20: null,
            characteristics01: null,
            characteristics02: null,
            characteristics03: null,
            characteristics04: null,
            result,
    
        },
        onLoad: function (opt) {
            var that = this;
            console.log("onLoad");
            console.log('deviceId=' + opt.deviceId);
            console.log('name=' + opt.name);
            that.setData({ deviceId: opt.deviceId });
            /**
             * 监听设备的连接状态
             */
            wx.onBLEConnectionStateChanged(function (res) {
                console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)
            })
            /**
             * 连接设备
             */
            wx.createBLEConnection({
                deviceId: that.data.deviceId,
                success: function (res) {
                    // success
                    console.log(res);
                    /**
                     * 连接成功,后开始获取设备的服务列表
                     */
                    wx.getBLEDeviceServices({
                        // 这里的 deviceId 需要在上面的 getBluetoothDevices中获取
                        deviceId: that.data.deviceId,
                        success: function (res) {
                            console.log('device services:', res.services)
                            that.setData({ services: res.services });
                            console.log('device services:', that.data.services[1].uuid);
                            that.setData({ serviceId: that.data.services[1].uuid });
                            console.log('--------------------------------------');
                            console.log('device设备的id:', that.data.deviceId);
                            console.log('device设备的服务id:', that.data.serviceId);
                            /**
                             * 延迟3秒,根据服务获取特征 
                             */
                            setTimeout(function () {
                                wx.getBLEDeviceCharacteristics({
                                    // 这里的 deviceId 需要在上面的 getBluetoothDevices
                                    deviceId: that.data.deviceId,
                                    // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
                                    serviceId: that.data.serviceId,
                                    success: function (res) {
                                        console.log('000000000000' + that.data.serviceId);
                                        console.log('device getBLEDeviceCharacteristics:', res.characteristics)
                                        for (var i = 0; i < 5; i++) {
                                            if (res.characteristics[i].uuid.indexOf("cd20") != -1) {
                                                that.setData({
                                                    cd20: res.characteristics[i].uuid,
                                                    characteristics20: res.characteristics[i]
                                                });
                                            }
                                            if (res.characteristics[i].uuid.indexOf("cd01") != -1) {
                                                that.setData({
                                                    cd01: res.characteristics[i].uuid,
                                                    characteristics01: res.characteristics[i]
                                                });
                                            }
                                            if (res.characteristics[i].uuid.indexOf("cd02") != -1) {
                                                that.setData({
                                                    cd02: res.characteristics[i].uuid,
                                                    characteristics02: res.characteristics[i]
                                                });
                                            } if (res.characteristics[i].uuid.indexOf("cd03") != -1) {
                                                that.setData({
                                                    cd03: res.characteristics[i].uuid,
                                                    characteristics03: res.characteristics[i]
                                                });
                                            }
                                            if (res.characteristics[i].uuid.indexOf("cd04") != -1) {
                                                that.setData({
                                                    cd04: res.characteristics[i].uuid,
                                                    characteristics04: res.characteristics[i]
                                                });
                                            }
                                        }
                                        console.log('cd01= ' + that.data.cd01 + 'cd02= ' + that.data.cd02 + 'cd03= ' + that.data.cd03 + 'cd04= ' + that.data.cd04 + 'cd20= ' + that.data.cd20);
                                        /**
                                         * 回调获取 设备发过来的数据
                                         */
                                        wx.onBLECharacteristicValueChange(function (characteristic) {
                                            console.log('characteristic value comed:', characteristic.value)
                                            //{value: ArrayBuffer, deviceId: "D8:00:D2:4F:24:17", serviceId: "ba11f08c-5f14-0b0d-1080-007cbe238851-0x600000460240", characteristicId: "0000cd04-0000-1000-8000-00805f9b34fb-0x60800069fb80"}
                                            /**
                                             * 监听cd04cd04中的结果
                                             */
                                            if (characteristic.characteristicId.indexOf("cd01") != -1) {
                                                const result = characteristic.value;
                                                const hex = that.buf2hex(result);
                                                console.log(hex);
                                            }
                                            if (characteristic.characteristicId.indexOf("cd04") != -1) {
                                                const result = characteristic.value;
                                                const hex = that.buf2hex(result);
                                                console.log(hex);
                                                that.setData({ result: hex });
                                            }
    
                                        })
                                        /**
                                         * 顺序开发设备特征notifiy
                                         */
                                        wx.notifyBLECharacteristicValueChanged({
                                            deviceId: that.data.deviceId,
                                            serviceId: that.data.serviceId,
                                            characteristicId: that.data.cd01,
                                            state: true,
                                            success: function (res) {
                                                // success
                                                console.log('notifyBLECharacteristicValueChanged success', res);
                                            },
                                            fail: function (res) {
                                                // fail
                                            },
                                            complete: function (res) {
                                                // complete
                                            }
                                        })
                                        wx.notifyBLECharacteristicValueChanged({
                                            deviceId: that.data.deviceId,
                                            serviceId: that.data.serviceId,
                                            characteristicId: that.data.cd02,
                                            state: true,
                                            success: function (res) {
                                                // success
                                                console.log('notifyBLECharacteristicValueChanged success', res);
                                            },
                                            fail: function (res) {
                                                // fail
                                            },
                                            complete: function (res) {
                                                // complete
                                            }
                                        })
                                        wx.notifyBLECharacteristicValueChanged({
                                            deviceId: that.data.deviceId,
                                            serviceId: that.data.serviceId,
                                            characteristicId: that.data.cd03,
                                            state: true,
                                            success: function (res) {
                                                // success
                                                console.log('notifyBLECharacteristicValueChanged success', res);
                                            },
                                            fail: function (res) {
                                                // fail
                                            },
                                            complete: function (res) {
                                                // complete
                                            }
                                        })
    
                                        wx.notifyBLECharacteristicValueChanged({
                                            // 启用 notify 功能
                                            // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
                                            deviceId: that.data.deviceId,
                                            serviceId: that.data.serviceId,
                                            characteristicId: that.data.cd04,
                                            state: true,
                                            success: function (res) {
                                                console.log('notifyBLECharacteristicValueChanged success', res)
                                            }
                                        })
    
                                    }, fail: function (res) {
                                        console.log(res);
                                    }
                                })
                            }
                                , 1500);
                        }
                    })
                },
                fail: function (res) {
                    // fail
                },
                complete: function (res) {
                    // complete
                }
            })
        },
    
        /**
         * 发送 数据到设备中
         */
        bindViewTap: function () {
            var that = this;
            var hex = 'AA5504B10000B5'
            var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
                return parseInt(h, 16)
            }))
            console.log(typedArray)
            console.log([0xAA, 0x55, 0x04, 0xB1, 0x00, 0x00, 0xB5])
            var buffer1 = typedArray.buffer
            console.log(buffer1)
            wx.writeBLECharacteristicValue({
                deviceId: that.data.deviceId,
                serviceId: that.data.serviceId,
                characteristicId: that.data.cd20,
                value: buffer1,
                success: function (res) {
                    // success
                    console.log("success  指令发送成功");
                    console.log(res);
                },
                fail: function (res) {
                    // fail
                    console.log(res);
                },
                complete: function (res) {
                    // complete
                }
            })
    
        },
        /**
         * ArrayBuffer 转换为  Hex
         */
        buf2hex: function (buffer) { // buffer is an ArrayBuffer
            return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
        }
    })

    5.效果展示

    这里写图片描述

    发送校验指令。获取结果

    这里写图片描述

    展开全文
  • 项目用微信小程序蓝牙通信客户端兼容苹果客户端及安卓客户端。
  • 微信小程序蓝牙通信

    2018-10-08 14:29:50
    微信小程序目前只支持低功耗蓝牙(BLE),不支持经典蓝牙。 微信小程序的当前最新版本为2.3.0,根据实际测试,对IOS支持很好,但对Android支持非常不好,各厂商的Android手机遇到的问题也不一样。因此要开发蓝牙...

    微信小程序目前只支持低功耗蓝牙(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类型,因此需要将写入的命令转为二进制形式存储在这里。

    展开全文
  • 微信小程序BLE蓝牙通信 兼容Android、IOS 关键点: 1、服务ID: var platform = app.globalData.platform //ios 平台 服务id 中字母必须为大写 if (platform == &amp;amp;quot;ios&amp;amp;quot;) ...

    微信小程序BLE蓝牙通信 兼容Android、IOS
    关键点:
    1、服务ID:

     var platform = app.globalData.platform
    
        //ios 平台 服务id 中字母必须为大写
        if (platform == "ios") {
          return this.data.serviceId.toUpperCase();
        }
        //android 平台 服务id 中字母必须为小写
        else if (platform == "android") {
          return this.data.serviceId.toLowerCase();
        }
        else {
          return this.data.serviceId
        }
    

    2、 发送/获取发送id

      getSendId: function () {
        var platform = app.globalData.platform
    
        //ios 平台 服务id 中字母必须为大写
        if (platform == "ios") {
          return this.data.sendId.toUpperCase();
          }
        //android 平台 服务id 中字母必须为小写
        else if (platform == "android") {
          return this.data.sendId.toLowerCase();
          }
        else {
          return this.data.sendId
          }
        },
    

    3、通知ID
    //通知id
    getReceiveId: function () {

    var platform = app.globalData.platform
    
    //ios 平台 服务id 中字母必须为大写
    if (platform == "ios") {
      return this.data.receiveId.toUpperCase();
    }
    //android 平台 服务id 中字母必须为小写
    else if (platform == "android") {
      return this.data.receiveId.toLowerCase();
    }
    else {
      return this.data.receiveId
    }
    

    }

    展开全文
  • 小程序ios下调用蓝牙无法根据mac识别,不多说直接上代码; 官网 地址: https://mp.weixin.qq.com/debug/wxadoc/dev/api/bluetooth.html#wxgetconnectedbluethoothdevicesobject 感谢:http...

    小程序ios下调用蓝牙无法根据mac识别,不多说直接上代码;

    官网 地址:

    https://mp.weixin.qq.com/debug/wxadoc/dev/api/bluetooth.html#wxgetconnectedbluethoothdevicesobject

    感谢:http://www.zhimengzhe.com/IOSkaifa/362398.html

     var that = this;
        //获取适配器
        wx.openBluetoothAdapter({
          success: function (res) {
            // success
            console.log("-----success----------");
            console.log(res);
            //开始搜索
            wx.startBluetoothDevicesDiscovery({
              services: [],
              success: function (res) {
                // success
                console.log("-----startBluetoothDevicesDiscovery--success----------");
                console.log(res);
              },
              fail: function (res) {
                // fail
                console.log("fail"+res);
              },
              complete: function (res) {
                // complete
                console.log("complete" +res);
              }
            })
    
    
          },
          fail: function (res) {
            console.log("-----fail----------");
            // fail
            console.log(res);
          },
          complete: function (res) {
            // complete
            console.log("-----complete----------");
            console.log(res);
          }
        })
     //获取所有已发现的蓝牙设备,包括已经和本机处于连接状态的设备
        wx.getBluetoothDevices({
          success: function (res) {
            // success
            //{devices: Array[11], errMsg: "getBluetoothDevices:ok"}
            console.log("getBluetoothDevices");
            // console.log(res);
            // console.log(res.devices[0]);
            // var bf = res.devices[0].advertisData.slice(2,8);
            // console.log(res.devices[0].advertisData);
            // console.log(bf);
            // console.log(new Uint8Array(bf));
            // // var arrayBuffer = that.buf2hex(bf);
            // var ar = Array.prototype.map.call(new Uint8Array(bf), x => ('00' + x.toString(16)).slice(-2)).join('');
            // console.log(ar);
            that.setData({
              list: res.devices
            });
            console.log(that.data.list);
            let list = that.data.list
            for (var i = 0; i < list.length; i++) {
              // if (list[i].RSSI > -80 ){//判断信号距离最近
              if (list[i].advertisData != null) {//判断对象是否为null,advertisData不一定有
                          //重点 根据advertisData 取出mac进行拼接
                    let bf = list[i].advertisData.slice(4, 10);
                    let mac = Array.prototype.map.call(new Uint8Array(bf), x => ('00' + x.toString(16)).slice(-2)).join(':');
                    console.log(mac.toUpperCase());
                    //判断mac是否为服务器传入mac
                    if (mac.toUpperCase() == '3C:A3:08:BA:45:35') {
                      that.setData({
                        deviceId: list[i].deviceId
                      });
                      console.log('deviceId:' + that.data.deviceId);
                    }
                    console.log(list[i]);
                  }
               
              // }
            }
          },
          fail: function (res) {
            // fail
          },
          complete: function (res) {
            // complete
          }
        })

     

    转载于:https://my.oschina.net/u/1265949/blog/1527143

    展开全文
  • 小程序蓝牙开发。 一、你了解蓝牙吗? 蓝牙是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换(使用2.4—2.485GHz的ISM波段的UHF无线电波)。蓝牙技术最初由电信巨头爱立信公司于...

    前言:

    记得上次分享过一篇小程序的文章《时隔两年,我开始学习微信小程序了~~仿小米手机天气预报》,那是我首次学习小程序,转眼间又过去大半年了,这次我就来谈谈--->小程序蓝牙开发。

    一、你了解蓝牙吗?

    蓝牙是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换(使用2.4—2.485GHz的ISM波段的UHF无线电波)。蓝牙技术最初由电信巨头爱立信公司于1994年创制,当时是作为RS232数据线的替代方案。蓝牙可连接多个设备,克服了数据同步的难题。

    相信负责移动端开发的朋友们或大或小都有了解过“经典蓝牙”和“低功耗蓝牙”这两个代名词;而我总结了一下他们的优缺点:

    1、android手机必须系统版本4.3及以上才支持BLE API。BLE蓝牙较传统蓝牙, 传输速度更快,覆盖范围更广,安全性更高,延迟更短,耗电极低等等优点;
    2、传统蓝牙与BLE蓝牙通信方式也有所不同,传统的一般通过socket方式,而BLE蓝牙是通过Gatt协议来实现;
    3、传统蓝牙可以用与数据量比较大的传输,如语音,音乐,较高数据量传输等;
    低功耗蓝牙这样应用于实时性要求比较高,但是数据速率比较低的产品,如遥控类的,如鼠标,键盘,遥控鼠标(Air Mouse),传感设备的数据发送,如心跳带,血压计,温度传感器等一些医疗器械。

    二、小程序蓝牙开发

    一直以来我都是负责Android端的蓝牙软件项目开发,突然间某某某领导对我说要用小程序开发,那时我心中有一百个不爽,由于小程序的API已经对蓝牙提供支持了,我也没有什么理由去推卸了,但我只能说对领导说关于小程序蓝牙开发还不够成熟,其中可能会有兼容性问题,对于可行性问题我也不太确定,所以我也是抱着学习的心态去面对的。开始行动起来吧,相信敢于挑战,敢于付出的人,肯定有所收获的。

    首先小程序开发 离不开小程序开发文档:先去了解和熟悉蓝牙API;都看一遍,对整个蓝牙开发流程也不过如此简单,都是一些api的套路罢了。

    微信客户端对小程序蓝牙的支持版本为:iOS 微信客户端 6.5.6 版本开始支持,Android微信客户端 6.5.7 版本开始支持,此外还需要注意的就是Android系统需要Android4.3以上才可以使用蓝牙BLE,而小程序蓝牙只支持BLE,这点需要注意下。

    1.获取当前设备平台以及微信版本,判断是否支持小程序蓝牙:

    //获取当前设备平台以及微信版本
        if (app.getPlatform() == 'android' && this.versionCompare('6.5.7', app.getWxVersion())) {
          wx.showModal({
            title: '提示',
            content: '当前微信版本过低,请更新至最新版本',
            showCancel: false,
            success: function (res) {
              if (res.confirm) {
                that.backPage();
              } 
            }
          })
          
        } else if (app.getPlatform() == 'ios' && this.versionCompare('6.5.6', app.getWxVersion())){
          wx.showModal({
            title: '提示',
            content: '当前微信版本过低,请更新至最新版本',
            showCancel: false,
            success: function (res) {
              if (res.confirm) {
                that.backPage();
              }
            }
          })
        }

    2.初始化小程序蓝牙模块,生效周期为调用wx.openBluetoothAdapter至调用wx.closeBluetoothAdapter或小程序被销毁为止。 在小程序蓝牙适配器模块生效期间,开发者可以正常调用下面的小程序API,并会收到蓝牙模块相关的on回调。

    //初始化小程序蓝牙模块
      openBluetoothAdapter:function(){
        var that = this;
        wx.openBluetoothAdapter({
          success: function (res){
            var log = that.data.textLog + "打开蓝牙适配器成功!\n";
            that.setData({
              textLog: log,
              isopen:true
            });
            that.getBluetoothAdapterState();
          },
          fail: function (err){
            isopen: true;
            app.toastTap("蓝牙开关未开启");
            var log = that.data.textLog + "蓝牙开关未开启 \n";
            that.setData({
              textLog: log
            });   
          }  
        })
        //监听蓝牙适配器状态变化事件
        wx.onBluetoothAdapterStateChange(function (res) {
          console.log('onBluetoothAdapterStateChange', res)
          var isDvailable = res.available;//蓝牙适配器是否可用
          if (isDvailable) {
            that.getBluetoothAdapterState();  
          } else {
            that.stopBluetoothDevicesDiscovery();//停止搜索
            that.setData({
              devices: []
            });
            app.toastTap1("蓝牙开关未开启");
          }
        })
      }

    3.获取本机蓝牙适配器状态

    getBluetoothAdapterState: function () {
        var that = this;
        wx.getBluetoothAdapterState({
          success: function (res) {
            var isDiscov = res.discovering;//是否正在搜索设备
            var isDvailable = res.available;//蓝牙适配器是否可用
            if (isDvailable) {
              var log = that.data.textLog + "本机蓝牙适配器状态:可用 \n";
              that.setData({
                textLog: log
              });
              if (!isDiscov){
                that.startBluetoothDevicesDiscovery();
              }else{
                var log = that.data.textLog + "已在搜索设备 \n";
                that.setData({
                  textLog: log
                });
              }
            }
          }
        })
      }

    4.开始扫描附近的蓝牙外围设备。注意,该操作比较耗费系统资源,请在搜索并连接到设备后调用 stop 方法停止搜索。

    wx.startBluetoothDevicesDiscovery({
          services: [],// 以微信硬件平台的蓝牙智能灯为例,主服务的 UUID 是 FEE7。传入这个参数:services: ['FEE7'],只搜索主服务 UUID 为 FEE7 的设备
          allowDuplicatesKey: true,  //是否允许重复上报同一设备, 如果允许重复上报,则onDeviceFound 方法会多次上报同一设备,但是 RSSI(信号) 值会有不同
          success: function (res) {
            var log = that.data.textLog + "扫描附近的蓝牙外围设备成功,准备监听寻找新设备:" + res+"\n";
            that.setData({
              textLog: log
            });
            that.onBluetoothDeviceFound();  //监听寻找到新设备的事件
          }
        });

    5.监听寻找到新设备的事件;Android 上获取到的deviceId为设备 MAC 地址,iOS 上则为设备 uuid。因此deviceId不能硬编码到代码中

    //监听寻找到新设备的事件
      onBluetoothDeviceFound:function() {
        var that = this;
        wx.onBluetoothDeviceFound(function(res) {
          res.devices.forEach(function (device) {
            if (!device.name && !device.localName) {
              return
            }
            const foundDevices = that.data.devices;       
            const idx = inArray(foundDevices, 'deviceId', device.deviceId);       
            const data = {};
            if (idx === -1) {
              data[`devices[${foundDevices.length}]`] = device
            } else {
              data[`devices[${idx}]`] = device
            }
            that.setData(data)
          })
        })
      }

    至此整个过程就完成了对设备的搜索操作,这时就可以对扫描到的设备id以及name,进行处理;不过这个过程需要注意的是:安卓和IOS差别很大,安卓设备地址就是mac地址,但是IOS无法获取mac地址,所以设备地址是针对本机范围有效的UUID,所以这里需要注意。剩下的就是蓝牙设备的连接、读、写、还有监听获取返回值了。

     

    6.连接低功耗蓝牙设备。

    wx.createBLEConnection({
      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 
      deviceId: deviceId,
      success: function (res) {
        console.log(res)
      }
    })

    当使用此方法成功连接蓝牙设备后,需要使用方法:wx.stopBluetoothDevicesDiscovery() 关闭蓝牙扫描功能,释放资源,减少消耗。

     

    7.获取蓝牙设备所有 service(服务)

    //获取蓝牙设备所有 service(服务)
      getBLEDeviceServices:function(devId) {
        var that = this;
        wx.getBLEDeviceServices({
          deviceId:devId,
          success: function(res) {
            for (let i = 0; i < res.services.length; i++) {
              if (res.services[i].isPrimary) {//该服务是否为主服务
                var log = that.data.textLog + "该服务是否为主服务:" + res.services[i].isPrimary + "\n";
                that.setData({
                  textLog: log
                });
               
              }
            }
          }
        })
      }

    8.获取到服务ID后,就可以获取蓝牙设备某个服务中的所有 characteristic(特征值)

    //获取蓝牙设备某个服务中的所有 characteristic(特征值)
      getBLEDeviceCharacteristics: function (deviceId, serviceId){
        var that = this;
        wx.getBLEDeviceCharacteristics({
          deviceId: deviceId,
          serviceId: serviceId,
          success: function (res) {
            for (let i = 0; i < res.characteristics.length; i++) {
              let item = res.characteristics[i]
              if (item.properties.read) {//该特征值是否支持 read 操作
                var log = that.data.textLog + "该特征值支持 read 操作:" + item.uuid + "\n";
                that.setData({
                  textLog: log,
                  readCharacteristicId: item.uuid
                });
              }
              if (item.properties.write) {//该特征值是否支持 write 操作
                var log = that.data.textLog + "该特征值支持 write 操作:" + item.uuid + "\n";
                that.setData({
                  textLog: log,
                  writeCharacteristicId: item.uuid,
                  canWrite:true
                });
              }
              if (item.properties.notify) {//该特征值是否支持 notify或indicate 操作
                var log = that.data.textLog + "该特征值支持 notify 操作:" + item.uuid + "\n";
                that.setData({
                  textLog: log,
                  notifyCharacteristicId: item.uuid,
                });
                that.notifyBLECharacteristicValueChange();
              }
    
            }
    
          }
        })
      }

    至此,我们已经获取了 读的特征值UUID,有些设备不支持读操作的话,就没有这个UUID;我们还获取了写操作的UUID,如果没有此UUID的话,我们的设备就不支持写入指令操作;我们还获取了notify UUID,是用来执行广播监听事件的,就是写入指令后,蓝牙设备有返回数值,都可以监听接收。

    9.开启监听蓝牙设备的返回值,读写操作成功后的返回值也是在下面onBLECharacteristicValueChange这个方法获取,这里相当于Android蓝牙BLE的开启广播监听。

    notifyBLECharacteristicValueChange:function(){
        var that = this;
        wx.notifyBLECharacteristicValueChange({
          state: true, // 启用 notify 功能
          deviceId: that.data.deviceId,
          serviceId: that.data.serviceId,
          characteristicId: that.data.notifyCharacteristicId,
          success: function (res) {
            var log = that.data.textLog + "notify启动成功\n";
            that.setData({ 
              textLog: log,
            });
            that.onBLECharacteristicValueChange();   //监听特征值变化
            
          },
          fail: function (res) {
            wx.showToast({
              title: 'notify启动失败',
              mask: true
            });
            setTimeout(function () {
              wx.hideToast();
            }, 2000)
          }
        })
    
      },
      //监听低功耗蓝牙设备的特征值变化。必须先启用notify接口才能接收到设备推送的notification。
      onBLECharacteristicValueChange:function(){
        var that = this;
        var log = that.data.textLog + "准备监听低功耗蓝牙设备的特征值变化\n";
        that.setData({
          textLog: log,
        });
        wx.onBLECharacteristicValueChange(function (res) {
          var log = that.data.textLog + "监听低功耗蓝牙设备的特征值变化\n";
          that.setData({
            textLog: log,
          });
          // var resValue = that.ab2hext(res.value); //16进制字符串  
          
        });
      }

    10.最后一步,读或写操作;这里需要注意的是:小程序中对蓝牙数据的传递是使用ArrayBuffer的二进制类型来的,所以在我们的使用过程中需要进行转码再进行读或者写操作。

    //读
    wx.readBLECharacteristicValue({
      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  [**new**]
      deviceId: deviceId,
      // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
      serviceId: serviceId,
      // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
      characteristicId: characteristicId,
      success: function (res) {
        console.log('readBLECharacteristicValue:', res.errCode)
      }
    })
    
    
    、、、、、
    
    
    //写
    wx.writeBLECharacteristicValue({
      // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
      deviceId: deviceId,
      // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
      serviceId: serviceId,
      // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
      characteristicId: characteristicId,
      // 这里的value是ArrayBuffer类型
      value: buffer,
      success: function (res) {
        console.log('writeBLECharacteristicValue success', res.errMsg)
      }
    })

     

    查看小程序蓝牙api也会发现如下tip:

    就是要控制单次传送的指令,确保不要超过20个字节,如果超过了,就要进行分包发送了,也就是每次分20个字节,分成多次发送,如果是Android开发的话,可以调整MTU的大小,但是小程序没有封装这个方法,所以只能分包也是可以的。

    在学习小程序蓝牙的过程中,我也写了个demo:小程序蓝牙demo,希望能帮助到大家,并且也能趁此机会和大家交流,望多多指教。

    demo的页面效果图如下:

     

    支持我的话可以关注下我的公众号,也欢迎大家投稿~

    扫一扫关注我的微信公众号:程序猿在广东

     

     

     

     

     

     

    展开全文
  • 小程序蓝牙亲身总结

    2018-08-14 09:07:48
    小程序蓝牙亲身总结 最近做了一个涉及到蓝牙模块小程序,做一下总结,为自己的成长做一份记录,如果能帮到大家的话是再好不过的了; 问题: 1.小程序蓝牙搜索能不能搜到手机设备 2.如何判断蓝牙是否打开,并开始...
  • 最近随项目接触了下小程序的BLE开发。体会颇多。 小程序BLE开发前的准备操作: 1、熟读小程序开发文档,文档链接。 2、微信开发者工具。 3、对应的BLE蓝牙设备,我们需要对BLE设备进行读写操作。 一、小程序...
  • 小程序蓝牙通信

    2018-03-21 10:17:19
    蓝牙在日常生活中广泛使用的一项技术,小程序给了我们前端工程师一个控制蓝牙的方法,带上你的设备,来看看怎么控制你的蓝牙设备吧。 背景介绍 蓝牙是爱立信公司创立的一种无线技术标准,为短距离的硬件设备提供...
  • (一)蓝牙需要知道的几个名词 1、profile profile可以理解为一种规范,一个标准的通信协议,它存在于从机中。蓝牙组织规定了一些标准的profile,例如 HID OVER GATT ,防丢器 ,心率计等。每个profile中会包含多个...
  • 一、微信小程序开发相关资料: 微信公众平台: ... 小程序官方文档: 微信小程序开发离不了官方...这段时间研究了小程序蓝牙API的使用方法,从扫描到连接,从读写数据到监听接收数据,总算调通了整个开发流程!为...
  • 公司项目设计蓝牙ble门禁的设备,范围拓展到支付宝小程序内,写小程序的人不管是android还是ios都是需要适配对方os的,如果是前端的话,可能更是一脸蒙蔽的,我是android,在适配ios遇到了很多坑.完成一次开门是分包发送两...
  • 微信小程序 蓝牙实现

    2018-01-30 21:07:17
    微信小程序 蓝牙实现 此前是通过安卓客户端实现对蓝牙设备的扫描、连接和通讯等操作,本篇主要介绍一下使用微信小程序来对蓝牙设备的操作。...目前不支持在开发者工具上进行调试,需要使用真机才能正常调用小程序蓝牙
  • 微信小程序蓝牙模块今天第一次写博客,关于微信小程序蓝牙这一块,因为公司项目需要搞一个蓝牙的小程序,而小程序蓝牙模块也是刚出不久,遇到的坑很难解决,经过自己的摸索以及同事的忙帮,终于可以实现获取到蓝牙的...
  • 微信小程序蓝牙BLE开发(一) 迟来的更新。上半年4月份以来项目中断续在对接好几个产品关于蓝牙BLE设备,通过蓝牙与设备之间通信进行使用产品。开发中也遇到不少问题哈,后面抽时间续篇。写得不好,请各位大神多多...
  • 微信小程序蓝牙广播中获取mac 微信小程序在使用搜索附近蓝牙获得已发现蓝牙列表中,有些蓝牙会出现广播对象叫advertisData 获取广播中的mac的方法为: var buff = res.devices[i]....
  • 程序功能: 微信小程序连接指定的蓝牙设备,给蓝牙设备发送数据,监听到蓝牙设备回复(需要硬件蓝牙模块处理)的数据后做相应的处理。 实现: 结合硬件设备给蓝牙模块发数据后 能实现控制电机开门动作 小程序和低...
  • 这个库主要使用Promise,封装了微信小程序蓝牙接口,并且具体实现了常用的行为,对不同层面的业务也进行了高度的封装和拓展,可以帮助你快速且方便地进行小程序蓝牙开发。主要功能如下: 以下均是在手机开启了...
  • 微信小程序蓝牙BLE开发实战(二) 上篇主要介绍在开发过程中应用到相关API操作。接下来介绍个人在项目开发中应用蓝牙BLE一些事情。 由于时间比较仓促, 有些注释没那么详细。请理解~写的不好欢迎各位大神指。 项目...
  • Android和ios蓝牙连接的区别 在手机中Android和ios的都是通过蓝牙中的deviceId的值连接的, 但是同一个蓝牙中Android和iOS中的deviceId是不一样的。 在Android中deviceId就是该蓝牙的mac地址,...
1 2 3 4 5 ... 20
收藏数 3,258
精华内容 1,303