了解如何使用低功耗藍(lán)牙
通過(guò)本節(jié),你將學(xué)會(huì):
為了使用藍(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')
}
})
你可以通過(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è)備,連接操作可以通過(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")
}
})
每個(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")
}
})
每個(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")
}
})
通過(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")
}
})
通過(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")
}
})
通過(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")
}
})
在不需要使用藍(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>
更多建議: