小程序操作蓝牙读写

xml

<wxs module="utils">
module.exports.max = function(n1, n2) {
  return Math.max(n1, n2)
}
module.exports.len = function(arr) {
  arr = arr || []
  return arr.length
}
</wxs>
<view>我是蓝牙测试页面</view>
<button bindtap="openBluetoothAdapter">开始扫描</button>
<button bindtap="stopBluetoothDevicesDiscovery">停止扫描</button>
<button bindtap="closeBluetoothAdapter">结束流程</button>

<view class="devices_summary">已发现 {{devices.length}} 个外围设备:</view>
<scroll-view class="device_list" scroll-y scroll-with-animation>
  <view wx:for="{{devices}}" wx:key="index"
   data-device-id="{{item.deviceId}}"
   data-name="{{item.name || item.localName}}"
   bindtap="createBLEConnection" 
   class="device_item"
   hover-class="device_item_hover">
    <view style="font-size: 16px; color: #333;">{{item.name}}</view>
    <view style="font-size: 10px">信号强度: {{item.RSSI}}dBm ({{utils.max(0, item.RSSI + 100)}}%)</view>
    <view style="font-size: 10px">UUID: {{item.deviceId}}</view>
    <view style="font-size: 10px">Service数量: {{utils.len(item.advertisServiceUUIDs)}}</view>
  </view>
</scroll-view>

<view class="connected_info" wx:if="{{connected}}">
  <view>
    <text>已连接到 {{name}}</text>
    <view class="operation">
    <button wx:if="{{canWrite}}" size="mini" bindtap="writeBLECharacteristicValue">写数据</button>
    <button size="mini" bindtap="closeBLEConnection">断开连接</button>
    </view>
  </view>
  <view wx:for="{{chs}}" wx:key="index" style="font-size: 12px; margin-top: 10px;">
    <view>特性UUID: {{item.uuid}}</view>
    <view>特性值: {{item.value}}</view>
  </view>
</view>

wxss

page {
  color: #333;
}
.devices_summary {
  margin-top: 30px;
  padding: 10px;
  font-size: 16px;
}
.device_list {
  height: 300px;
  margin: 50px 5px;
  margin-top: 0;
  border: 1px solid #EEE;
  border-radius: 5px;
  width: auto;
}
.device_item {
  border-bottom: 1px solid #EEE;
  padding: 10px;
  color: #666;
}
.device_item_hover {
  background-color: rgba(0, 0, 0, .1);
}
.connected_info {
  position: fixed;
  bottom: 0;
  width: 100%;
  background-color: #F0F0F0;
  padding: 10px;
  padding-bottom: 20px;
  margin-bottom: env(safe-area-inset-bottom);
  font-size: 14px;
  min-height: 100px;
  box-shadow: 0px 0px 3px 0px;
}
.connected_info .operation {
  position: absolute;
  display: inline-block;
  right: 30px;
}

js

const app = getApp()

function inArray(arr, key, val) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i][key] === val) {
      return i;
    }
  }
  return -1;
}
// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  var hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('');
}

Page({
  data: {
    devices: [],
    connected: false,
    chs: [],
  },
  //打开蓝牙连接初始化
  openBluetoothAdapter() {
    //初始化蓝牙模块。iOS 上开启主机/从机模式时需分别调用一次,指定对应的 mode
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('openBluetoothAdapter success', res)
        //开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索并连接到设备后调用 wx.stopBluetoothDevicesDiscovery 方法停止搜索。
        this.startBluetoothDevicesDiscovery()
      },
      fail: (res) => {
        if (res.errCode === 10001) {
          //监听蓝牙适配器状态变化事件
          wx.onBluetoothAdapterStateChange(function (res) {
            console.log('onBluetoothAdapterStateChange', res)
            if (res.available) {
              //检测蓝牙设备是否可用
              this.startBluetoothDevicesDiscovery()
            }
          })
        }
      }
    })
  },
  //开启搜寻设备
  startBluetoothDevicesDiscovery() {
    if (this._discoveryStarted) {
      return
    }
    this._discoveryStarted = true
    //开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索并连接到设备后调用 wx.stopBluetoothDevicesDiscovery 方法停止搜索。
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: true,
      success: (res) => {
        console.log('startBluetoothDevicesDiscovery success', res)
        //监听寻找到新设备的事件
        this.onBluetoothDeviceFound()
      },
    })
  },
  //停止搜索
  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery()
  },
  // 监听寻找到新设备的事件
  onBluetoothDeviceFound() {
    wx.onBluetoothDeviceFound((res) => {
      res.devices.forEach(device => {
        //蓝牙设备名称,某些设备可能没有    当前蓝牙设备的广播数据段中的 LocalName 数据段
        if (!device.name && !device.localName) {
          return
        }
        const foundDevices = this.data.devices;
        // 处理一下获取列表
        const idx = inArray(foundDevices, 'deviceId', device.deviceId)
        const data = {}
        if (idx === -1) {
          data[`devices[${foundDevices.length}]`] = device
        } else {
          data[`devices[${idx}]`] = device
        }
        this.setData(data)
      })
    })
  },
  //连接设备
  createBLEConnection(e) {
    const ds = e.currentTarget.dataset
    const deviceId = ds.deviceId
    const name = ds.name
    //调用wx.createBLEConnection 使用DeviceId 参数 连接蓝牙设备
    wx.createBLEConnection({
      deviceId,
      success: (res) => {
        this.setData({
          connected: true,
          name,
          deviceId,
        })
          //获取蓝牙设备所有服务(service)
        this.getBLEDeviceServices(deviceId)
      }
    })
    this.stopBluetoothDevicesDiscovery()
  },
  //获取蓝牙设备所有服务(service)
  getBLEDeviceServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      //res为设备服务列表
      success: (res) => {
        for (let i = 0; i < res.services.length; i++) {
          //isPrimary该服务是否为主服务
          if (res.services[i].isPrimary) {
            //蓝牙设备服务的 uuid(通用唯一识别码)
            this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
            return
          }
        }
      }
    })
  },
  //获取蓝牙设备某个服务中所有特征值(characteristic)。
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        //设备特征值列表
        console.log('getBLEDeviceCharacteristics success', res.characteristics)
        for (let i = 0; i < res.characteristics.length; i++) {
          //该特征值支持的操作类型
          let item = res.characteristics[i]
          //如果支持读
          if (item.properties.read) {
            wx.readBLECharacteristicValue({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
            })
          }
          //如果支持写
          if (item.properties.write) {
            console.log('我可以写');
            this.setData({
              canWrite: true
            })
            this._deviceId = deviceId
            this._serviceId = serviceId
            this._characteristicId = item.uuid
            this.writeBLECharacteristicValue()
          }
          //如果支持通知
          if (item.properties.notify || item.properties.indicate) {
            wx.notifyBLECharacteristicValueChange({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
              state: true,
            })
          }
        }
      },
      fail(res) {
        console.error('getBLEDeviceCharacteristics', res)
      }
    })
    // 操作之前先监听,保证第一时间获取数据
    //监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
    wx.onBLECharacteristicValueChange((characteristic) => {
      const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
      const data = {}
      if (idx === -1) {
        data[`chs[${this.data.chs.length}]`] = {
          uuid: characteristic.characteristicId,
          value: ab2hex(characteristic.value)
        }
      } else {
        data[`chs[${idx}]`] = {
          uuid: characteristic.characteristicId,
          value: ab2hex(characteristic.value)
        }
      }
      // data[`chs[${this.data.chs.length}]`] = {
      //   uuid: characteristic.characteristicId,
      //   value: ab2hex(characteristic.value)
      // }
      this.setData(data)
    })
  },
  writeBLECharacteristicValue() {
    // 向蓝牙设备发送一个0x00的16进制数据
    //表示通用的、固定长度的原始二进制数据缓冲区。
    let buffer = new ArrayBuffer(1)
    //从 二进制ArrayBuffer 对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的字节序问题。
    let dataView = new DataView(buffer)
    //起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(无符号字节).
    dataView.setUint8(0, Math.random() * 255 | 0)
    //向低功耗蓝牙设备特征值中写入二进制数据。注意:必须设备的特征值支持 write 才可以成功调用。
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: buffer,
      success () {
        console.log('我写成功啦');
      }
    })
  },
  onLoad() {
  }
})

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值