promise封装小程序的蓝牙类

// pages/bluetooth/bluetooth.js
import { BluetoothMode } from '../../models/bluetooth.js'
import {System} from '../../models/system.js'
const bluetooth = new BluetoothMode()
const system = new System()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    devicesData: [],
    sys: {}
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    const res=system.getSync()
    this.setData({
      sys:res
    })
  },

  // 点击连接蓝牙设备
  connectionBluetooth: function (e) {
    const deviceId = e.currentTarget.dataset.id
    bluetooth.connect(deviceId).then(res => {
      wx.setStorageSync('serviceData', res)
      // 停止搜索 减少资源
      bluetooth.stop()
      wx.navigateTo({
        url: '../device/device?name=' + e.currentTarget.dataset.name,
      })
    })
  },

  // 扫描设备
  startBluetooth() {
    this._initBluetooth()
  },

  //初始化蓝牙适配器
  _initBluetooth: function () {
    // 调用蓝牙子类的初始化事件
    bluetooth.initBluetooth().then(res => {
      // 监听发现新的设备
      bluetooth.on('newDevice',data => {
        this.setData({
          devicesData:data
        })
      })
    })
  },

})

 

1.继上一篇文章中的观察者模式

import {
  PublishtionModel
} from 'publishtion.js'

const tips = {
  0: '正常',
  10000: '未初始化蓝牙适配器',
  10001: '当前蓝牙适配器不可用,请打开手机蓝牙后重试',
  10002: '没有找到指定设备',
  10003: '连接失败',
  10004: '没有找到指定服务',
  10005: '没有找到指定特征值',
  10006: '当前连接已断开',
  10007: '当前特征值不支持此操作',
  10008: '其余所有系统上报的异常',
  10009: 'Android 系统特有,系统版本低于 4.3 不支持 BLE',
  10012: '连接超时',
  10013: '连接 deviceId 为空或者是格式不正确',
  20000: '蓝牙适配器不可用,蓝牙可能被关闭',
}

class BluetoothMode extends PublishtionModel {

  //获取搜索到的蓝牙设备
  data = []

  //初始化蓝牙适配器
  initBluetooth() {
    return new Promise((resolve, reject) => {
      this._initBluetooth().then(res => {
        this._getBluetoothState()
        return this._search()
      }).then(res => {
        // 开启监听 
        this._onDFound()
        resolve(res)
      })
    })
  }

  _initBluetooth() {
    return new Promise((resolve, reject) => {
      wx.openBluetoothAdapter({
        success: res => {
          console.log(res)
          console.log('初始化蓝牙模块成功')
          resolve()
        },
        fail: error => {
          console.log(error)
          this._showTips(error.errCode)
        }
      })
    })
  }

  // 连接低功耗蓝牙
  connection(deviceId) {
    return new Promise((resolve, reject) => {
      wx.createBLEConnection({
        deviceId,
        success: res => {
          console.log(res)
          this._setDevice(deviceId)
          // 暂停搜索
          this.stop()
          resolve({
            res,
            deviceId
          })
        },
        fail: res => {
          console.log(res)
        }
      })
    })
  }

  connect(deviceId) {
    return new Promise((resolve, reject) => {
      this.connection(deviceId).then(res => {
        return this.getServiceList(res.deviceId)
      }).then(res => {
        let promiseList = []
        for (var i in res.services) {
          promiseList.push(this.getBLEDeviveChar({
            deviceId,
            serviceId: res.services[i].uuid
          }))
        }
        return Promise.all(promiseList)
      }).then(res => {
        resolve(res)
      })
    })
  }

  // 启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。
  // 注意:必须设备的特征值支持 notify 或者 indicate 才可以成功调用。
  notify({
    deviceId,
    serviceId,
    characteristicId
  }) {
    return new Promise((resolve, reject) => {
      wx.notifyBLECharacteristicValueChange({
        state: true, // 启用 notify 功能
        // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
        deviceId,
        // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
        serviceId,
        // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
        characteristicId,
        success(res) {
          resolve(res)
          console.log('notifyBLECharacteristicValueChange success', res.errMsg)
        }
      })
    })
  }

  // 获取服务列表
  getServiceList(deviceId) {
    return new Promise((resolve, reject) => {
      wx.getBLEDeviceServices({
        // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
        deviceId,
        success(res) {
          console.log('device services:', res.services)
          resolve({
            services: res.services,
            deviceId
          })
        }
      })
    })
  }

  // 获取蓝牙设备某个服务中所有特征值 getBLEDeviceCharacteristics
  getBLEDeviveChar({
    deviceId,
    serviceId
  }) {
    return new Promise((resolve, reject) => {
      wx.getBLEDeviceCharacteristics({
        // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
        deviceId,
        // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
        serviceId,
        success(res) {
          resolve(res)
          console.log('device getBLEDeviceCharacteristics:', res.characteristics)
        }
      })
    })
  }

  // 断开与低功耗蓝牙设备的连接。
  closeConnection() {
    wx.closeBLEConnection({
      deviceId,
      success(res) {
        console.log(res)
      }
    })
  }

  //向低功耗蓝牙设备特征值中写入二进制数据。
  write({
    deviceId,
    serviceId,
    characteristicId,
    value
  }) {
    //传入String 返回 ArrayBuffer类型
    let abf = this.__hexStringToArrayBuffer(value)

    return new Promise((resolve, reject) => {
      wx.writeBLECharacteristicValue({
        // 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
        deviceId,
        // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
        serviceId,
        // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
        characteristicId,
        // 这里的value是ArrayBuffer类型
        value: abf,
        success(res) {
          resolve(res)
          console.log('writeBLECharacteristicValue success', res.errMsg)
        }
      })
    })

  }

  // 停止搜寻附近的蓝牙外围设备
  stop() {
    return new Promise((resolve, reject) => {
      wx.stopBluetoothDevicesDiscovery({
        success(res) {
          console.log(res)
          resolve(res)
        }
      })
    })

  }

  // 关闭蓝牙适配器
  close() {
    wx.closeBluetoothAdapter()
  }

  // 获取设备Id
  getDevice() {
    return wx.getStorageSync('deviceId')
  }

  // 开启蓝牙搜索
  _search() {
    wx.showLoading({
      title: '正在扫描中...',
    })
    return new Promise((resolve, reject) => {
      wx.startBluetoothDevicesDiscovery({
        success: res => {
          console.log(res)
          resolve(res)
        },
        fail: err => {
          console.log(err)
        },
        complete: res => {
          setTimeout(() => {
            wx.hideLoading()
          }, 2000)
        }
      })
    })
  }

  //返回ArrayBuffe
  _hexStringToArrayBuffer(str) {
    if (!str) {
      return new ArrayBuffer(0);
    }
    var buffer = new ArrayBuffer(str.length);
    let dataView = new DataView(buffer)
    let ind = 0;
    for (var i = 0, len = str.length; i < len; i += 2) {
      let code = parseInt(str.substr(i, 2), 16)
      dataView.setUint8(ind, code)
      ind++
    }
    return buffer;
  }

  // 开启监听获取到新的设备
  _onDFound() {
    wx.onBluetoothDeviceFound(devices =>{
      this._getDevices().then(res=>{
        // console.log(this)
        this.publish(this.data,'newDevice')
      })
      // console.dir(devices)
    })
  }

  // 获取寻找的所有设备
  _getDevices() {
    return new Promise((resolve, reject) => {
      wx.getBluetoothDevices({
        success: res => {
          // console.log(res)
          let array = []
          for (var x in res.devices) {
            if (res.devices[x].name != '未知设备') {
              res.devices[x].advertisData = this._ab2hex(res.devices[x].advertisData)
              array.push(res.devices[x])
            }
          }
          // console.log(array)
          this.data = array
          resolve(array)
        }
      })
    })
  }

  // 获取蓝牙适配器的状态
  _getBluetoothState() {
    const that = this
    wx.onBluetoothAdapterStateChange(res => {
      console.log(res)
      if (res.available) {
        console.log('蓝牙模块可用')
      } else {
        wx.showModal({
          title: '提示',
          content: '蓝牙已被关闭',
          showCancel: false,
          success(res) {
            if (res.confirm) {
              console.log('用户点击确定')
            } else if (res.cancel) {
              console.log('用户点击取消')
            }
          }
        })
        this._showTips(20000)
        console.log('蓝牙模块不可用')
      }
      if (res.discovering) {
        console.log('蓝牙适配器处于搜索状态')
      } else {
        console.log('蓝牙适配器不处于搜索状态')
      }
    })
  }

  // ArrayBuffer转16进度字符串示例
  _ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function(bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  }

  // 错误提示
  _showTips(code) {
    code && wx.showToast({
      title: tips[code],
      icon: 'none'
    })
  }

  // 储存设备Id
  _setDevice(id) {
    wx.setStorageSync('deviceId', id)
  }

}

export {
  BluetoothMode
}

2.在需要使用的页面中调用

 

posted @ 2019-06-17 11:13  博客小鹏鹏  阅读(1037)  评论(3编辑  收藏  举报