快應(yīng)用 使用藍(lán)牙

2020-08-08 15:26 更新
了解如何使用低功耗藍(lán)牙

通過(guò)本節(jié),你將學(xué)會(huì):

使用方法

初始化藍(lán)牙模塊

為了使用藍(lán)牙功能,你需要先初始化藍(lán)牙模塊。除了設(shè)置狀態(tài)監(jiān)聽(tīng)以外,所有的藍(lán)牙接口都需要在初始化完成以后才能正常使用。

//初始化藍(lán)牙模塊
bluetooth.openAdapter({
  //是否打開(kāi)系統(tǒng)藍(lán)牙開(kāi)關(guān),默認(rèn)false
  operateAdapter: true,
  success: function() {
    console.log('success')
  },
  fail: function(data, code) {
    console.log(`handling fail, code = ${code}`)
    if (code === 10001) {
      //藍(lán)牙未打開(kāi),提示用戶(hù)打開(kāi)藍(lán)牙
    }
  },
  complete: function() {
    console.log('complete')
  }
})

搜索周?chē)O(shè)備

你可以通過(guò)搜索操作,發(fā)現(xiàn)周?chē)牡凸乃{(lán)牙設(shè)備。在進(jìn)行掃描前,你需要注冊(cè)設(shè)備發(fā)現(xiàn)回調(diào)以及時(shí)接收搜索結(jié)果

//在掃描之前先注冊(cè)設(shè)備發(fā)現(xiàn)回調(diào)
bluetooth.ondevicefound = function (data) {
  console.log("new device list has founded");
  data.devices.forEach(device => {
    //發(fā)現(xiàn)所需設(shè)備后停止掃描
    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])}`
      );
    }
  });
};
//開(kāi)始掃描
bluetooth.startDevicesDiscovery({
  //指定設(shè)備uuid,支持16-bit,32-bit,128-bit uuid,不填則掃描周?chē)性O(shè)備
  services: ["1105"],
  //是否允許重復(fù)設(shè)備上報(bào),如果不需要監(jiān)聽(tīng)廣播包數(shù)據(jù),建議不設(shè)置此項(xiàng),默認(rèn)值為false
  allowDuplicatesKey: false,
  //上報(bào)間隔,單位毫秒,為0則立即上報(bào),默認(rèn)值為0
  interval: 1000,
  success: function () {
    console.log("success");
  }
});

連接設(shè)備

在操作設(shè)備前,你需要先連接設(shè)備,連接操作可以通過(guò)deviceId直接進(jìn)行,掃描并不是必要的操作。在連接前,你可以注冊(cè)設(shè)備連接狀態(tài)接口來(lái)監(jiān)聽(tīng)設(shè)備斷連狀態(tài)

//注冊(cè)設(shè)備連接狀態(tài)監(jiān)聽(tīng)
bluetooth.onbleconnectionstatechange = function (data) {
  console.log(`handling device state change: deviceId = ${data.deviceId}, connected = ${data.connected}`)
  //更新設(shè)備連接狀態(tài)
  _this.connected = data.connected
  if (data.connected) {
    //目標(biāo)設(shè)備連接后,獲取服務(wù)列表
    _this.getServices()
  } else {
    //做斷開(kāi)連接的相關(guān)操作,比如重新連接,或者重新掃描等
  }
}
//連接設(shè)備
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")
  }
})

獲取設(shè)備服務(wù)信息

每個(gè)設(shè)備都會(huì)定義若干個(gè)服務(wù),你可以從中獲取需要操作的服務(wù)信息

bluetooth.getBLEDeviceServices({
  deviceId: _this.deviceId,
  success: function (data) {
    data.services.forEach(service => {
      console.log(`handling device services: uuid = ${service.uuid}, isPrimary = ${service.isPrimary}`)
      //獲取需要的服務(wù),可以根據(jù)設(shè)備定義的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")
  }
})

獲取設(shè)備特征值信息

每個(gè)服務(wù)內(nèi)會(huì)定義若干個(gè)特征值,你可以從中獲取需要操作的特征值信息

bluetooth.getBLEDeviceCharacteristics({
  deviceId: _this.deviceId,
  serviceId: _this.serviceId,
  success: function (data) {
    data.characteristics.forEach(characteristic => {
      console.log(`handling device characteristic : ${JSON.stringify(characteristic)}`)
      //獲取需要的特征值,可以根據(jù)設(shè)備定義的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")
  }
})

向設(shè)備寫(xiě)入數(shù)據(jù)

通過(guò)獲取到的服務(wù)與特征值信息,可以向設(shè)備對(duì)應(yīng)的特征值寫(xiě)入數(shù)據(jù),需要該特征值支持 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類(lèi)型
  value: buffer,
  success: function () {
    console.log("success")
  },
  fail: function (data, code) {
    console.log(`handling fail, code = ${code}`)
  },
  complete: function () {
    console.log("complete")
  }
})

讀取設(shè)備數(shù)據(jù)

通過(guò)獲取到的服務(wù)與特征值信息,可以讀取設(shè)備對(duì)應(yīng)特征值數(shù)據(jù),需要該特征值支持 read,讀取到的設(shè)備信息會(huì)通過(guò)onblecharacteristicvaluechange監(jiān)聽(tīng)接口上報(bào),此接口藍(lán)牙模塊通用,無(wú)需重復(fù)注冊(cè)

//注冊(cè)特征值改變監(jiān)聽(tīng)
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 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接
  deviceId: _this.deviceId,
  // 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取
  serviceId: _this.serviceId,
  // 這里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中獲取
  characteristicId: _this.readCharacteristicId,
  success: function () {
    // 執(zhí)行操作成功,讀取的值會(huì)在onblecharacteristicvaluechange 接口中上報(bào)
    console.log("success")
  }
})

監(jiān)聽(tīng)設(shè)備數(shù)據(jù)變化

通過(guò)獲取到的服務(wù)與特征值信息,可以開(kāi)啟或者關(guān)閉設(shè)備相應(yīng)的特征值變化時(shí)的通知功能,需要該特征值支持 notify 或者 indicate,讀取到的設(shè)備信息會(huì)通過(guò)onblecharacteristicvaluechange監(jiān)聽(tīng)接口上報(bào),此接口藍(lán)牙模塊通用,無(wú)需重復(fù)注冊(cè)

//注冊(cè)特征值改變監(jiān)聽(tīng)
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則開(kāi)啟通知
  state: enable,
  // 這里的 deviceId 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接
  deviceId: _this.deviceId,
  // 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取
  serviceId: _this.serviceId,
  // 這里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中獲取
  characteristicId: _this.notifyCharacteristicId,
  success: function () {
    // 執(zhí)行操作成功,讀取的值會(huì)在onblecharacteristicvaluechange 接口中上報(bào)
    _this.notifyEnabled = enable
    console.log("success")
  },
  fail: function (data, code) {
    console.log(`handling fail, code = ${code}`)
  },
  complete: function () {
    console.log("complete")
  }
})

注銷(xiāo)藍(lán)牙模塊

在不需要使用藍(lán)牙時(shí),需要注銷(xiāo)藍(lán)牙模塊,以釋放系統(tǒng)資源

//取消不需要的狀態(tài)監(jiān)聽(tīng)
bluetooth.onadapterstatechange = null
bluetooth.onbleconnectionstatechange = null
bluetooth.onblecharacteristicvaluechange = null
bluetooth.ondevicefound = null

//注銷(xiāo)藍(lán)牙模塊
bluetooth.closeAdapter({
  //是否關(guān)閉系統(tǒng)藍(lán)牙開(kāi)關(guān),默認(rèn)false,此操作會(huì)直接關(guān)閉系統(tǒng)藍(lán)牙,為了不影響用戶(hù)其他藍(lán)牙設(shè)備的體驗(yàn),不建議設(shè)置為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="掃描設(shè)備" />
      <input type="button" class="btn" onclick="createConnection" value="連接設(shè)備" />
      <input type="button" class="btn" onclick="closeConnection" value="斷開(kāi)設(shè)備" />
    </div>
    <div class="item-container" if=false>
      <input type="button" class="btn" onclick="write" value="寫(xiě)入數(shù)據(jù)" />
      <input type="button" class="btn" onclick="read" value="讀取數(shù)據(jù)" />

    </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轉(zhuǎn)String
    ab2hex(buffer) {
      var hexArr = Array.prototype.map.call(
        new Uint8Array(buffer),
        function (bit) {
          return ("00" + bit.toString(16)).slice(-2);
        });
      return hexArr.join("");
    },
    //在頁(yè)面初始化時(shí)進(jìn)行藍(lán)牙模塊初始化操作
    onInit() {
      let _this = this
      //注冊(cè)藍(lán)牙適配器監(jiān)聽(tīng)
      bluetooth.onadapterstatechange = function (data) {
        console.log("adapterState changed, now is", data.available);
      };

      //注冊(cè)設(shè)備連接狀態(tài)監(jiān)聽(tīng)
      bluetooth.onbleconnectionstatechange = function (data) {
        console.log(`handling device state change: deviceId = ${data.deviceId}, connected = ${data.connected}`)
        //更新設(shè)備連接狀態(tài)
        _this.connected = data.connected
        if (data.connected) {
          //目標(biāo)設(shè)備連接后,獲取服務(wù)列表
          _this.getServices()
        } else {
          //做斷開(kāi)連接的相關(guān)操作,比如重新連接,或者重新掃描等
        }
      }

      //注冊(cè)特征值改變監(jiān)聽(tīng)
      bluetooth.onblecharacteristicvaluechange = function (data) {
        console.log(`handling characteristic value change: deviceId = ${data.deviceId}, serviceId = ${data.serviceId}, characteristicId = ${data.characteristicId}, value = ${_this.ab2hex(data.value)}`)
      }

      //初始化藍(lán)牙模塊
      bluetooth.openAdapter({
        //是否打開(kāi)系統(tǒng)藍(lán)牙開(kāi)關(guān),默認(rèn)false
        operateAdapter: true,
        success: function () {
          console.log("success");
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`);
          if (code === 10001) {
            //藍(lán)牙未打開(kāi),提示用戶(hù)打開(kāi)藍(lán)牙
          }
        },
        complete: function () {
          console.log("complete");
        }
      });
    },
    //在結(jié)束時(shí)注銷(xiāo)藍(lán)牙模塊
    onDestroy() {
      //取消不需要的狀態(tài)監(jiān)聽(tīng)
      bluetooth.onadapterstatechange = null
      bluetooth.onbleconnectionstatechange = null
      bluetooth.onblecharacteristicvaluechange = null
      bluetooth.ondevicefound = null

      //注銷(xiāo)藍(lán)牙模塊
      bluetooth.closeAdapter({
        //是否關(guān)閉系統(tǒng)藍(lán)牙開(kāi)關(guān),默認(rèn)false,此操作會(huì)直接關(guān)閉系統(tǒng)藍(lán)牙,為了不影響用戶(hù)其他藍(lán)牙設(shè)備的體驗(yàn),不建議設(shè)置為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
      //在掃描之前先注冊(cè)設(shè)備發(fā)現(xiàn)回調(diào)
      bluetooth.ondevicefound = function (data) {
        console.log("new device list has founded");
        data.devices.forEach(device => {
          //發(fā)現(xiàn)所需設(shè)備后停止掃描
          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])}`
            );
          }
        });
      };
      //開(kāi)始掃描
      bluetooth.startDevicesDiscovery({
        //指定設(shè)備uuid,支持16-bit,32-bit,128-bit uuid,不填則掃描周?chē)性O(shè)備
        services: ["1105"],
        //是否允許重復(fù)設(shè)備上報(bào),如果不需要監(jiān)聽(tīng)廣播包數(shù)據(jù),建議不設(shè)置此項(xiàng),默認(rèn)值為false
        allowDuplicatesKey: false,
        success: function () {
          console.log("success");
        }
      });
    },
    createConnection() {
      let _this = this
      //連接設(shè)備
      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}`)
            //獲取需要的服務(wù),可以根據(jù)設(shè)備定義的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)}`)
            //獲取需要的特征,可以根據(jù)設(shè)備定義的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類(lèi)型
        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 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接
        deviceId: _this.deviceId,
        // 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取
        serviceId: _this.serviceId,
        // 這里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中獲取
        characteristicId: _this.readCharacteristicId,
        success: function () {
          // 執(zhí)行操作成功,讀取的值會(huì)在onblecharacteristicvaluechange 接口中上報(bào)
          console.log("success")
        }
      })
    },
    notifyDevice(enable) {
      let _this = this
      bluetooth.notifyBLECharacteristicValueChange({
        // 啟用 notify 功能
        state: enable,
        // 這里的 deviceId 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接
        deviceId: _this.deviceId,
        // 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取
        serviceId: _this.serviceId,
        // 這里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中獲取
        characteristicId: _this.notifyCharacteristicId,
        success: function () {
          // 執(zhí)行操作成功,讀取的值會(huì)在onblecharacteristicvaluechange 接口中上報(bào)
          _this.notifyEnabled = enable
          console.log("success")
        },
        fail: function (data, code) {
          console.log(`handling fail, code = ${code}`)
        },
        complete: function () {
          console.log("complete")
        }
      })
    }
  };
</script>


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)