FE - 微信小程序 - 藍牙 BLE 開發調研與使用

背景

最近在研究 weex 的時候,感受到的不只是一點痛楚,從文檔到示例代碼,再到代碼倉庫,真是一塌糊塗。反看 微信小程序的文檔 簡直好到極點,公司現有產品本身是和硬件打交道的,所以在藍牙開發上的就下了下功夫。年初,看到小程序的時候,其藍牙還不支持 android ,少了很多特性。不知何時,微信就已經更新藍牙(ble)開發的內容,今天有幸嘗試這在微信小程序裏,進行了試用和測試。

這裏寫圖片描述

先說感受,優點:只需要根據 api 文檔寫 js 即可,可以在 微信的 androidios 端的小程序中使用,很強。缺點:屬於微信小程序生態環境。

效果圖

基本測試內容:連接我公司的ble 產品 , 並能正常傳輸數據,最後,還要測試在 android ios 的微信小程序中同時測試下,是否可以正常運行。

  • 掃描 ble 設備
  • 連接 ble 設備
  • 接收 ble 設備數據
  • androidios 是否均正常

(ios 效果圖)
這裏寫圖片描述

(圖中’藍牙未打開’字樣是在藍牙關閉和打開的時候變化的)

1、ble-初始化

初始化是會判斷當前是否支持 ble 是否可以獲得 bleAdapter;

 bleInit:function(){
    console.log('初始化藍牙')
    let self = this
    wx.openBluetoothAdapter({
      success: function(res) {
        self.setData({
          bleAdapterStatus: "初始化成功"
        })
      },
      fail:function(msg){
        self.setData({
          bleAdapterStatus: "初始化失敗"
        })
        wx.showModal({
          showCancel:false,
          title: '提示',
          content: '設備藍牙未打開,請打開藍牙功能',
          success:function(res){
            if (res.confirm) {
              //console.log('用戶點擊確定')
              // 退出小程序
            }
          }
        });
      }
    });
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

2、ble-掃描藍牙

基本步驟:ble 初始化 => 掃描設備 => 獲取設備信息

 onScanClick:function(event){
    console.log('掃描開始')
    let self = this
    wx.openBluetoothAdapter({
      success: function(res) {
        // 掃描藍牙
        self.bleDisCovery()
        self.setData({
          bleAdapterStatus:"初始化成功"
        })
      },
      fail:function(error){
        self.setData({
          bleAdapterStatus: "初始化失敗"
        })
        wx.showModal({
          showCancel: false,
          title: '提示',
          content: '設備藍牙未打開,請打開藍牙功能',
          success: function (res) {
            if (res.confirm) {
              //console.log('用戶點擊確定')
            }
          }
        });
      },
      complete:function(){
        //console.log('complete')
      }
    });
  },,
  /**
   * 解析數據信息
   */
  bleFound:function(){
    console.log("發現設備信息")
    let self =this
    wx.onBluetoothDeviceFound(function (res) {
      let devices = res.devices
      console.log(devices)
      let length = self.data.bleChips.length
      let devicesLength = devices.length
      if (devicesLength > length){
        self.data.bleChips = devices
        self.setData({
          bleChips: devices
        });
      }
      console.log(self.data.bleChips)
    });

  },
  /**
   * 掃描設備
   */
  bleDisCovery:function(){
    console.log("掃描藍牙")
    let self = this
     wx.startBluetoothDevicesDiscovery({
          interval:1000,
          success: function(res){
            self.bleFound();
          }
        });
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

3、ble-連接設備

掃描到的數據列表顯示,注意看連接 button , 點擊事件傳參數,通過 data-自定義參數名稱;

比如我的 data-item :參數名稱就爲 item ;

  <view wx:if="{{!bleConnSuccess}}" class='scan_result' wx:for="{{bleChips}}">
     <text class="result_text">{{index}}-{{item.name}}-{{item.deviceId}}</text>
     <button bindtap='onConnBle' data-item='{{item}}'>連接</button>
  </view>
  • 1
  • 2
  • 3
  • 4

其次,接收數據:

onConnBle:function(e){
    // 停止掃描
    wx.stopBluetoothDevicesDiscovery({
      success: function(res) {
      },
    });
    // 接收點擊事件的參數
    let device = e.currentTarget.dataset.item
    console.log(`conn ble >> ${device}`)
    this.setData({
      bleChipInfo: device
    })
    let deviceId = device.deviceId
    let self = this
    // 連接設備
    console.log("連接設備中...")
    wx.createBLEConnection({
      deviceId: deviceId,
      success: function(res) {
        wx.showToast({
          title: '連接成功',
        });
        // 連接成功,打開 notify
        setTimeout(function(){
          self.bleServices(deviceId)
        },1500)

      },
      fail:function(errMsg){
        wx.showToast({
          title: `連接失敗:${errMsg}`,
        })
      }
    });
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

4、ble- 獲取 services

 bleServices: function (deviceId){
    let self = this
    wx.getBLEDeviceServices({
      deviceId: deviceId,
      success: function (res) {
        wx.showToast({
          title: 'service success',
        })
        // 設備中的 services
        let services = res.services
        for(let index in services){
          let service= services[index]
          console.log(service)
        }       
        console.log('device services:', res.services)
      }
    })
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

5、ble-service 獲取 characteristics

bleServiceChart: function (deviceId,serviceId){
    let self = this;
    wx.getBLEDeviceCharacteristics({
      // 這裏的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中獲取
      deviceId: deviceId,
      // 這裏的 serviceId 需要在上面的 getBLEDeviceServices 接口中獲取
      serviceId: serviceId,
      success: function (res) {
        console.log('device getBLEDeviceCharacteristics:', res.characteristics)
        let characteristics = res.characteristics
        for (let index in characteristics){
          let characteristic = characteristics[index]
            //
          }
          console.log(characteristic)
        }
        self.openNotify(deviceId) 
      }
    })
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

6、ble- notify data

開啓 notify data ,要使用 onBLECharacteristicValueChange 進行數據接收;

 openNotify: function (deviceId) {
    this.setData({
      bleConnSuccess: true
    });
    let self = this
    wx.notifyBLECharacteristicValueChange({
      deviceId: deviceId,
      serviceId: '你的 service id',
      characteristicId: '你的  characteristic Id',
      state: true,
      success: function (res) {
        console.log('notify success')
        self.onNotifyChange()
        wx.showToast({
          title: 'notify success',
        });
      },
      fail: function (err) {
        console.log(err)
        wx.showToast({
          title: 'notify fail',
        });
      }
    });
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

7、ble - 接收數據

  onNotifyChange:function(){
    // 接收數據
    let self = this
    wx.onBLECharacteristicValueChange(function (res) {
      console.log(res.characteristicId)
      let byteDatas = Array.from(new Int8Array(res.value))
      console.log(byteDatas)
      const data = byteDatas.join(',')
      self.setData({
        bleNotifyData:data
      });
      console.log(data)
    });
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

最後

寫入和讀取操作,我這裏就不做過多說明,官方文檔說的已經很明確了;

注意事項

在 ios 和 android 測試時,android 平臺不需要獲取 service 和 characteristic,就可以進行開啓 notify ;而在 ios 平臺必須手動的去獲取你要操作的 service 和 characteristic,不然會 notify 不成功;

Github :

wechat-ble-demo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章