了解如何使用低功耗藍牙
通過本節(jié),你將學會:
為了使用藍牙功能,你需要先初始化藍牙模塊。除了設置狀態(tài)監(jiān)聽以外,所有的藍牙接口都需要在初始化完成以后才能正常使用。
//初始化藍牙模塊
bluetooth.openAdapter({
//是否打開系統(tǒng)藍牙開關(guān),默認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')
}
})
你可以通過搜索操作,發(fā)現(xiàn)周圍的低功耗藍牙設備。在進行掃描前,你需要注冊設備發(fā)現(xiàn)回調(diào)以及時接收搜索結(jié)果
//在掃描之前先注冊設備發(fā)現(xiàn)回調(diào)
bluetooth.ondevicefound = function (data) {
console.log("new device list has founded");
data.devices.forEach(device => {
//發(fā)現(xiàn)所需設備后停止掃描
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"],
//是否允許重復設備上報,如果不需要監(jiān)聽廣播包數(shù)據(jù),建議不設置此項,默認值為false
allowDuplicatesKey: false,
//上報間隔,單位毫秒,為0則立即上報,默認值為0
interval: 1000,
success: function () {
console.log("success");
}
});
在操作設備前,你需要先連接設備,連接操作可以通過deviceId直接進行,掃描并不是必要的操作。在連接前,你可以注冊設備連接狀態(tài)接口來監(jiān)聽設備斷連狀態(tài)
//注冊設備連接狀態(tài)監(jiān)聽
bluetooth.onbleconnectionstatechange = function (data) {
console.log(`handling device state change: deviceId = ${data.deviceId}, connected = ${data.connected}`)
//更新設備連接狀態(tài)
_this.connected = data.connected
if (data.connected) {
//目標設備連接后,獲取服務列表
_this.getServices()
} else {
//做斷開連接的相關(guān)操作,比如重新連接,或者重新掃描等
}
}
//連接設備
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}`)
//獲取需要的服務,可以根據(jù)設備定義的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")
}
})
每個服務內(nèi)會定義若干個特征值,你可以從中獲取需要操作的特征值信息
bluetooth.getBLEDeviceCharacteristics({
deviceId: _this.deviceId,
serviceId: _this.serviceId,
success: function (data) {
data.characteristics.forEach(characteristic => {
console.log(`handling device characteristic : ${JSON.stringify(characteristic)}`)
//獲取需要的特征值,可以根據(jù)設備定義的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ù)據(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類型
value: buffer,
success: function () {
console.log("success")
},
fail: function (data, code) {
console.log(`handling fail, code = ${code}`)
},
complete: function () {
console.log("complete")
}
})
通過獲取到的服務與特征值信息,可以讀取設備對應特征值數(shù)據(jù),需要該特征值支持 read,讀取到的設備信息會通過onblecharacteristicvaluechange監(jiān)聽接口上報,此接口藍牙模塊通用,無需重復注冊
//注冊特征值改變監(jiān)聽
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)通過 createBLEConnection 與對應設備建立鏈接
deviceId: _this.deviceId,
// 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取
serviceId: _this.serviceId,
// 這里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中獲取
characteristicId: _this.readCharacteristicId,
success: function () {
// 執(zhí)行操作成功,讀取的值會在onblecharacteristicvaluechange 接口中上報
console.log("success")
}
})
通過獲取到的服務與特征值信息,可以開啟或者關(guān)閉設備相應的特征值變化時的通知功能,需要該特征值支持 notify 或者 indicate,讀取到的設備信息會通過onblecharacteristicvaluechange監(jiān)聽接口上報,此接口藍牙模塊通用,無需重復注冊
//注冊特征值改變監(jiān)聽
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 需要已經(jīng)通過 createBLEConnection 與對應設備建立鏈接
deviceId: _this.deviceId,
// 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取
serviceId: _this.serviceId,
// 這里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中獲取
characteristicId: _this.notifyCharacteristicId,
success: function () {
// 執(zhí)行操作成功,讀取的值會在onblecharacteristicvaluechange 接口中上報
_this.notifyEnabled = enable
console.log("success")
},
fail: function (data, code) {
console.log(`handling fail, code = ${code}`)
},
complete: function () {
console.log("complete")
}
})
在不需要使用藍牙時,需要注銷藍牙模塊,以釋放系統(tǒng)資源
//取消不需要的狀態(tài)監(jiān)聽
bluetooth.onadapterstatechange = null
bluetooth.onbleconnectionstatechange = null
bluetooth.onblecharacteristicvaluechange = null
bluetooth.ondevicefound = null
//注銷藍牙模塊
bluetooth.closeAdapter({
//是否關(guān)閉系統(tǒng)藍牙開關(guān),默認false,此操作會直接關(guān)閉系統(tǒng)藍牙,為了不影響用戶其他藍牙設備的體驗,不建議設置為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="寫入數(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("");
},
//在頁面初始化時進行藍牙模塊初始化操作
onInit() {
let _this = this
//注冊藍牙適配器監(jiān)聽
bluetooth.onadapterstatechange = function (data) {
console.log("adapterState changed, now is", data.available);
};
//注冊設備連接狀態(tài)監(jiān)聽
bluetooth.onbleconnectionstatechange = function (data) {
console.log(`handling device state change: deviceId = ${data.deviceId}, connected = ${data.connected}`)
//更新設備連接狀態(tài)
_this.connected = data.connected
if (data.connected) {
//目標設備連接后,獲取服務列表
_this.getServices()
} else {
//做斷開連接的相關(guān)操作,比如重新連接,或者重新掃描等
}
}
//注冊特征值改變監(jiān)聽
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({
//是否打開系統(tǒng)藍牙開關(guān),默認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");
}
});
},
//在結(jié)束時注銷藍牙模塊
onDestroy() {
//取消不需要的狀態(tài)監(jiān)聽
bluetooth.onadapterstatechange = null
bluetooth.onbleconnectionstatechange = null
bluetooth.onblecharacteristicvaluechange = null
bluetooth.ondevicefound = null
//注銷藍牙模塊
bluetooth.closeAdapter({
//是否關(guān)閉系統(tǒng)藍牙開關(guān),默認false,此操作會直接關(guān)閉系統(tǒng)藍牙,為了不影響用戶其他藍牙設備的體驗,不建議設置為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
//在掃描之前先注冊設備發(fā)現(xiàn)回調(diào)
bluetooth.ondevicefound = function (data) {
console.log("new device list has founded");
data.devices.forEach(device => {
//發(fā)現(xiàn)所需設備后停止掃描
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"],
//是否允許重復設備上報,如果不需要監(jiān)聽廣播包數(shù)據(jù),建議不設置此項,默認值為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}`)
//獲取需要的服務,可以根據(jù)設備定義的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ù)設備定義的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 需要已經(jīng)通過 createBLEConnection 與對應設備建立鏈接
deviceId: _this.deviceId,
// 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取
serviceId: _this.serviceId,
// 這里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中獲取
characteristicId: _this.readCharacteristicId,
success: function () {
// 執(zhí)行操作成功,讀取的值會在onblecharacteristicvaluechange 接口中上報
console.log("success")
}
})
},
notifyDevice(enable) {
let _this = this
bluetooth.notifyBLECharacteristicValueChange({
// 啟用 notify 功能
state: enable,
// 這里的 deviceId 需要已經(jīng)通過 createBLEConnection 與對應設備建立鏈接
deviceId: _this.deviceId,
// 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取
serviceId: _this.serviceId,
// 這里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中獲取
characteristicId: _this.notifyCharacteristicId,
success: function () {
// 執(zhí)行操作成功,讀取的值會在onblecharacteristicvaluechange 接口中上報
_this.notifyEnabled = enable
console.log("success")
},
fail: function (data, code) {
console.log(`handling fail, code = ${code}`)
},
complete: function () {
console.log("complete")
}
})
}
};
</script>
更多建議: