教程 其他 框架 组件 接口

Bluetooth 教程

了解如何使用低功耗蓝牙

通过本节,你将学会:

  • 初始化蓝牙模块
  • 搜索周围设备
  • 连接设备
  • 获取设备服务信息
  • 获取设备特征值信息
  • 向设备写入数据
  • 读取设备数据
  • 监听设备数据变化
  • 注销蓝牙模块

使用方法

初始化蓝牙模块

为了使用蓝牙功能,你需要先初始化蓝牙模块。除了设置状态监听以外,所有的蓝牙接口都需要在初始化完成以后才能正常使用。

//初始化蓝牙模块
bluetooth.openAdapter({
  //是否打开系统蓝牙开关,默认false
  operateAdapter: true,
  success: function() {
    console.log('success')
  },
  fail: function(data, code) {
    console.log(`handling fail, code = ${code}`)
    if (code === 10001) {
      //蓝牙未打开,提示用户打开蓝牙
    }
  },
  complete: function() {
    console.log('complete')
  }
})

搜索周围设备

你可以通过搜索操作,发现周围的低功耗蓝牙设备。在进行扫描前,你需要注册设备发现回调以及时接收搜索结果

//在扫描之前先注册设备发现回调
bluetooth.ondevicefound = function (data) {
  console.log("new device list has founded");
  data.devices.forEach(device => {
    //发现所需设备后停止扫描
    bluetooth.stopDevicesDiscovery();
    _this.deviceId = device.deviceId;

    console.log(`handling find new devive:${JSON.stringify(device)}`);
    console.log(`handling advertisData = ${_this.ab2hex(device.advertisData)}`);
    for (let key in device.serviceData) {
      console.log(
        `handling serviceData: uuid = ${key}, serviceData = ${_this.ab2hex(device.serviceData[key])}`
      );
    }
  });
};
//开始扫描
bluetooth.startDevicesDiscovery({
  //指定设备uuid,支持16-bit,32-bit,128-bit uuid,不填则扫描周围所有设备
  services: ["1105"],
  //是否允许重复设备上报,如果不需要监听广播包数据,建议不设置此项,默认值为false
  allowDuplicatesKey: false,
  //上报间隔,单位毫秒,为0则立即上报,默认值为0
  interval: 1000,
  success: function () {
    console.log("success");
  }
});

连接设备

在操作设备前,你需要先连接设备,连接操作可以通过deviceId直接进行,扫描并不是必要的操作。在连接前,你可以注册设备连接状态接口来监听设备断连状态

//注册设备连接状态监听
bluetooth.onbleconnectionstatechange = function (data) {
  console.log(`handling device state change: deviceId = ${data.deviceId}, connected = ${data.connected}`)
  //更新设备连接状态
  _this.connected = data.connected
  if (data.connected) {
    //目标设备连接后,获取服务列表
    _this.getServices()
  } else {
    //做断开连接的相关操作,比如重新连接,或者重新扫描等
  }
}
//连接设备
bluetooth.createBLEConnection({
  deviceId: _this.deviceId,
  success: function () {
    console.log("success")
  },
  fail: function (data, code) {
    console.log(`handling fail, code = ${code}`)
  },
  complete: function () {
    console.log("complete")
  }
})

获取设备服务信息

每个设备都会定义若干个服务,你可以从中获取需要操作的服务信息

bluetooth.getBLEDeviceServices({
  deviceId: _this.deviceId,
  success: function (data) {
    data.services.forEach(service => {
      console.log(`handling device services: uuid = ${service.uuid}, isPrimary = ${service.isPrimary}`)
      //获取需要的服务,可以根据设备定义的uuid筛选
      if (service.isPrimary) {
        _this.serviceId = service.uuid
        //获取特征值列表
        _this.getCharacteristics()
      }
    })
  },
  fail: function (data, code) {
    console.log(`handling fail, code = ${code}`)
  },
  complete: function () {
    console.log("complete")
  }
})

获取设备特征值信息

每个服务内会定义若干个特征值,你可以从中获取需要操作的特征值信息

bluetooth.getBLEDeviceCharacteristics({
  deviceId: _this.deviceId,
  serviceId: _this.serviceId,
  success: function (data) {
    data.characteristics.forEach(characteristic => {
      console.log(`handling device characteristic : ${JSON.stringify(characteristic)}`)
      //获取需要的特征值,可以根据设备定义的uuid筛选
      if (characteristic.properties.write) {
        _this.writeCharacteristicId = characteristic.uuid
      } else if (characteristic.properties.read) {
        _this.readCharacteristicId = characteristic.uuid
      } else if (characteristic.properties.notify || characteristic.properties.indicate) {
        _this.notifyCharacteristicId = characteristic.uuid
      }
    })
  },
  fail: function (data, code) {
    console.log(`handling fail, code = ${code}`)
  },
  complete: function () {
    console.log("complete")
  }
})

向设备写入数据

通过获取到的服务与特征值信息,可以向设备对应的特征值写入数据,需要该特征值支持 write

let buffer = new ArrayBuffer(2)
let dataView = new DataView(buffer)
dataView.setUint8(0, 0)
dataView.setUint8(1, 0xf)
bluetooth.writeBLECharacteristicValue({
  // 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound接口中获取
  deviceId: _this.deviceId,
  // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
  serviceId: _this.serviceId,
  // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
  characteristicId: _this.writeCharacteristicId,
  // 这里的value是ArrayBuffer类型
  value: buffer,
  success: function () {
    console.log("success")
  },
  fail: function (data, code) {
    console.log(`handling fail, code = ${code}`)
  },
  complete: function () {
    console.log("complete")
  }
})

读取设备数据

通过获取到的服务与特征值信息,可以读取设备对应特征值数据,需要该特征值支持 read,读取到的设备信息会通过onblecharacteristicvaluechange监听接口上报,此接口蓝牙模块通用,无需重复注册

//注册特征值改变监听
bluetooth.onblecharacteristicvaluechange = function (data) {
  console.log(`handling characteristic value change: deviceId = ${data.deviceId}, serviceId = ${data.serviceId}, characteristicId = ${data.characteristicId}, value = ${_this.ab2hex(data.value)}`)
}
bluetooth.readBLECharacteristicValue({
  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
  deviceId: _this.deviceId,
  // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
  serviceId: _this.serviceId,
  // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
  characteristicId: _this.readCharacteristicId,
  success: function () {
    // 执行操作成功,读取的值会在onblecharacteristicvaluechange 接口中上报
    console.log("success")
  }
})

监听设备数据变化

通过获取到的服务与特征值信息,可以开启或者关闭设备相应的特征值变化时的通知功能,需要该特征值支持 notify 或者 indicate,读取到的设备信息会通过onblecharacteristicvaluechange监听接口上报,此接口蓝牙模块通用,无需重复注册

//注册特征值改变监听
bluetooth.onblecharacteristicvaluechange = function (data) {
  console.log(`handling characteristic value change: deviceId = ${data.deviceId}, serviceId = ${data.serviceId}, characteristicId = ${data.characteristicId}, value = ${_this.ab2hex(data.value)}`)
}
bluetooth.notifyBLECharacteristicValueChange({
  // 启用 notify 功能,为true则开启通知
  state: enable,
  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
  deviceId: _this.deviceId,
  // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
  serviceId: _this.serviceId,
  // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
  characteristicId: _this.notifyCharacteristicId,
  success: function () {
    // 执行操作成功,读取的值会在onblecharacteristicvaluechange 接口中上报
    _this.notifyEnabled = enable
    console.log("success")
  },
  fail: function (data, code) {
    console.log(`handling fail, code = ${code}`)
  },
  complete: function () {
    console.log("complete")
  }
})

注销蓝牙模块

在不需要使用蓝牙时,需要注销蓝牙模块,以释放系统资源

//取消不需要的状态监听
bluetooth.onadapterstatechange = null
bluetooth.onbleconnectionstatechange = null
bluetooth.onblecharacteristicvaluechange = null
bluetooth.ondevicefound = null

//注销蓝牙模块
bluetooth.closeAdapter({
  //是否关闭系统蓝牙开关,默认false,此操作会直接关闭系统蓝牙,为了不影响用户其他蓝牙设备的体验,不建议设置为true
  operateAdapter: false,
  success: function () {
    console.log("success");
  },
  fail: function (data, code) {
    console.log(`handling fail, code = ${code}`);
  },
  complete: function () {
    console.log("complete");
  }
});

示例代码如下

<template>
  <div class="doc-page">
    <div class="item-container">
      <text></text>
      <input type="button" class="btn" onclick="startDiscovery" value="扫描设备" />
      <input type="button" class="btn" onclick="createConnection" value="连接设备" />
      <input type="button" class="btn" onclick="closeConnection" value="断开设备" />
    </div>
    <div class="item-container" if=false>
      <input type="button" class="btn" onclick="write" value="写入数据" />
      <input type="button" class="btn" onclick="read" value="读取数据" />

    </div>
  </div>
</template>

<style>
  .doc-page {
    flex: 1;
    flex-direction: column;
  }

  .item-container {
    flex - direction: column;
    margin-bottom: 50px;
    margin-right: 60px;
    margin-left: 60px;
  }

  .text {
    width: 100%;
    margin-top: 5px;
    background-color: white;
    padding: 3px;
    margin-top: 1px;
    font-size: 28px;
    color: black;
  }

  .btn {
    height: 80px;
    text-align: center;
    border-radius: 5px;
    margin-right: 60px;
    margin-left: 60px;
    margin-bottom: 50px;
    color: #ffffff;
    font-size: 30px;
    background-color: #0faeff;
    line-height: 80px;
  }
</style>

<script>
  import bluetooth from "@system.bluetooth";

  export default {
    private: {
      connected: false,
      notifyEnabled: false,
      deviceId: '',
      readCharacteristicId: '',
      writeCharacteristicId: '',
      notifyCharacteristicId: ''
    },
    //arrayBuffer转String
    ab2hex(buffer) {
      var hexArr = Array.prototype.map.call(
        new Uint8Array(buffer),
        function (bit) {
          return ("00" + bit.toString(16)).slice(-2);
        });
      return hexArr.join("");
    },
    //在页面初始化时进行蓝牙模块初始化操作
    onInit() {
      let _this = this
      //注册蓝牙适配器监听
      bluetooth.onadapterstatechange = function (data) {
        console.log("adapterState changed, now is", data.available);
      };

      //注册设备连接状态监听
      bluetooth.onbleconnectionstatechange = function (data) {
        console.log(`handling device state change: deviceId = ${data.deviceId}, connected = ${data.connected}`)
        //更新设备连接状态
        _this.connected = data.connected
        if (data.connected) {
          //目标设备连接后,获取服务列表
          _this.getServices()
        } else {
          //做断开连接的相关操作,比如重新连接,或者重新扫描等
        }
      }

      //注册特征值改变监听
      bluetooth.onblecharacteristicvaluechange = function (data) {
        console.log(`handling characteristic value change: deviceId = ${data.deviceId}, serviceId = ${data.serviceId}, characteristicId = ${data.characteristicId}, value = ${_this.ab2hex(data.value)}`)
      }

      //初始化蓝牙模块
      bluetooth.openAdapter({
        //是否打开系统蓝牙开关,默认false
        operateAdapter: true,
        success: function () {
          console.log("success");
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`);
          if (code === 10001) {
            //蓝牙未打开,提示用户打开蓝牙
          }
        },
        complete: function () {
          console.log("complete");
        }
      });
    },
    //在结束时注销蓝牙模块
    onDestroy() {
      //取消不需要的状态监听
      bluetooth.onadapterstatechange = null
      bluetooth.onbleconnectionstatechange = null
      bluetooth.onblecharacteristicvaluechange = null
      bluetooth.ondevicefound = null

      //注销蓝牙模块
      bluetooth.closeAdapter({
        //是否关闭系统蓝牙开关,默认false,此操作会直接关闭系统蓝牙,为了不影响用户其他蓝牙设备的体验,不建议设置为true
        operateAdapter: false,
        success: function () {
          console.log("success");
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`);
        },
        complete: function () {
          console.log("complete");
        }
      });
    },
    startDiscovery() {
      let _this = this
      //在扫描之前先注册设备发现回调
      bluetooth.ondevicefound = function (data) {
        console.log("new device list has founded");
        data.devices.forEach(device => {
          //发现所需设备后停止扫描
          bluetooth.stopDevicesDiscovery();
          _this.deviceId = device.deviceId;

          console.log(`handling find new devive:${JSON.stringify(device)}`);
          console.log(`handling advertisData = ${_this.ab2hex(device.advertisData)}`);
          for (let key in device.serviceData) {
            console.log(
              `handling serviceData: uuid = ${key}, serviceData = ${_this.ab2hex(device.serviceData[key])}`
            );
          }
        });
      };
      //开始扫描
      bluetooth.startDevicesDiscovery({
        //指定设备uuid,支持16-bit,32-bit,128-bit uuid,不填则扫描周围所有设备
        services: ["1105"],
        //是否允许重复设备上报,如果不需要监听广播包数据,建议不设置此项,默认值为false
        allowDuplicatesKey: false,
        success: function () {
          console.log("success");
        }
      });
    },
    createConnection() {
      let _this = this
      //连接设备
      bluetooth.createBLEConnection({
        deviceId: _this.deviceId,
        success: function () {
          console.log("success")
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`)
        },
        complete: function () {
          console.log("complete")
        }
      })
    },
    closeConnection() {
      let _this = this
      bluetooth.closeBLEConnection({
        deviceId: _this.deviceId,
        success: function () {
          console.log("success")
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`)
        },
        complete: function () {
          console.log("complete")
        }
      })
    },
    getServices() {
      let _this = this
      bluetooth.getBLEDeviceServices({
        deviceId: _this.deviceId,
        success: function (data) {
          data.services.forEach(service => {
            console.log(`handling device services: uuid = ${service.uuid}, isPrimary = ${service.isPrimary}`)
            //获取需要的服务,可以根据设备定义的uuid筛选
            if (service.isPrimary) {
              _this.serviceId = service.uuid
              //获取特征列表
              _this.getCharacteristics()
            }
          })
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`)
        },
        complete: function () {
          console.log("complete")
        }
      })
    },
    getCharacteristics() {
      let _this = this
      bluetooth.getBLEDeviceCharacteristics({
        deviceId: _this.deviceId,
        serviceId: _this.serviceId,
        success: function (data) {
          data.characteristics.forEach(characteristic => {
            console.log(`handling device characteristic : ${JSON.stringify(characteristic)}`)
            //获取需要的特征,可以根据设备定义的uuid筛选
            if (characteristic.properties.write) {
              _this.writeCharacteristicId = characteristic.uuid
            } else if (characteristic.properties.read) {
              _this.readCharacteristicId = characteristic.uuid
            } else if (characteristic.properties.notify || characteristic.properties.indicate) {
              _this.notifyCharacteristicId = characteristic.uuid
            }
          })
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`)
        },
        complete: function () {
          console.log("complete")
        }
      })
    },
    write() {
      let _this = this
      let buffer = new ArrayBuffer(2)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0)
      dataView.setUint8(1, 0xf)
      bluetooth.writeBLECharacteristicValue({
        // 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound接口中获取
        deviceId: _this.deviceId,
        // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
        serviceId: _this.serviceId,
        // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
        characteristicId: _this.writeCharacteristicId,
        // 这里的value是ArrayBuffer类型
        value: buffer,
        success: function () {
          console.log("success")
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`)
        },
        complete: function () {
          console.log("complete")
        }
      })
    },
    read() {
      let _this = this
      bluetooth.readBLECharacteristicValue({
        // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
        deviceId: _this.deviceId,
        // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
        serviceId: _this.serviceId,
        // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
        characteristicId: _this.readCharacteristicId,
        success: function () {
          // 执行操作成功,读取的值会在onblecharacteristicvaluechange 接口中上报
          console.log("success")
        }
      })
    },
    notifyDevice(enable) {
      let _this = this
      bluetooth.notifyBLECharacteristicValueChange({
        // 启用 notify 功能
        state: enable,
        // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
        deviceId: _this.deviceId,
        // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
        serviceId: _this.serviceId,
        // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
        characteristicId: _this.notifyCharacteristicId,
        success: function () {
          // 执行操作成功,读取的值会在onblecharacteristicvaluechange 接口中上报
          _this.notifyEnabled = enable
          console.log("success")
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`)
        },
        complete: function () {
          console.log("complete")
        }
      })
    }
  };
</script>

条匹配 "" 的结果

    没有搜索到与 "" 相关的内容