OpenHarmony 藍(lán)牙模塊提供了基礎(chǔ)的傳統(tǒng)藍(lán)牙能力以及 BLE 的掃描、廣播等功能。
這里將介紹如何通過 OpenHarmony 提供的 @ohos.bluetooth (藍(lán)牙接口)打開當(dāng)前設(shè)備的藍(lán)牙,關(guān)閉藍(lán)牙,以及連接 BLE 藍(lán)牙設(shè)備。
設(shè)備與環(huán)境:
設(shè)備:九聯(lián) s905l3a 機(jī)頂盒、開鴻智谷學(xué)生卡 BLE 藍(lán)牙設(shè)備
系統(tǒng):OpenHarmony 3.2 beta2
SDK:9
邏輯流程
首先機(jī)頂盒在開始的時(shí)候獲取藍(lán)牙相關(guān)權(quán)限,然后通過 OpenHarmony 提供的藍(lán)牙接口打開藍(lán)牙。

接著訂閱發(fā)現(xiàn) BLE 設(shè)備發(fā)現(xiàn)事件,然后通過 OpenHarmony 提供的藍(lán)牙接口開啟 BLE 設(shè)備掃描。
當(dāng)發(fā)現(xiàn)到了 BLE 藍(lán)牙設(shè)備后,進(jìn)行上報(bào),BLE 設(shè)備發(fā)現(xiàn)事件觸發(fā),獲取到來自 BLE 設(shè)備的廣播信息包,然后進(jìn)行 BLE 藍(lán)牙連接。
實(shí)現(xiàn)過程
①獲取藍(lán)牙相關(guān)權(quán)限
在使用藍(lán)牙接口之前,首先要讓設(shè)備獲取一下權(quán)限:
ohos.permission.USE_BLUETOOTH //:允許應(yīng)用查看藍(lán)牙的配置。
ohos.permission.DISCOVER_BLUETOOTH //:允許應(yīng)用配置本地藍(lán)牙,查找遠(yuǎn)端設(shè)備且與之配對(duì)連接。
ohos.permission.LOCATION //:允許應(yīng)用獲取設(shè)備位置信息。
ohos.permission.MANAGE_BLUETOOTH //:允許應(yīng)用配對(duì)藍(lán)牙設(shè)備,并對(duì)設(shè)備的電話簿或消息進(jìn)行訪問。
打開 DevEco Studio 3.1.0.200,創(chuàng)建新的 Stage 項(xiàng)目,在項(xiàng)目中的 module.json 文件中添加相關(guān)權(quán)限:
"requestPermissions":[
{
"name":"ohos.permission.USE_BLUETOOTH",
"reason":"$string:grant_use_bluetooth",
"usedScene":{
"abilities":[
"MainAbility"
],
"when":"inuse"
}
},
{
"name":"ohos.permission.DISCOVER_BLUETOOTH",
"reason":"$string:grant_discovery_bluetooth",
"usedScene":{
"abilities":[
"MainAbility"
],
"when":"inuse"
}
},
{
"name":"ohos.permission.LOCATION",
"reason":"$string:grant_location",
"usedScene":{
"abilities":[
"MainAbility"
],
"when":"inuse"
}
},
{
"name":"ohos.permission.MANAGE_BLUETOOTH",
"reason":"$string:grant_manage_bluetooth",
"usedScene":{
"abilities":[
"MainAbility"
],
"when":"inuse"
}
}
]
②打開設(shè)備的藍(lán)牙
首先,通過調(diào)用 bluetooth.getState()藍(lán)牙接口來獲取當(dāng)前設(shè)備藍(lán)牙是否打開,并設(shè)置藍(lán)牙開關(guān)的標(biāo)識(shí)位 isOn。
asyncaboutToAppear(){
//等待獲取藍(lán)牙權(quán)限
awaitglobalThis.abilityContext.requestPermissionsFromUser(['ohos.permission.USE_BLUETOOTH','ohos.permission.DISCOVER_BLUETOOTH','ohos.permission.LOCATION','ohos.permission.MANAGE_BLUETOOTH'])
logger.info(TAG,`獲取權(quán)限grantPermission,requestPermissionsFromUser,PermissionRequestResult`)
//獲取藍(lán)牙狀態(tài)
letstate=bluetooth.getState()
//判斷當(dāng)前設(shè)備藍(lán)牙是否打開
if(state===bluetooth.BluetoothState.STATE_ON){
this.isOn=true
}
if(state===bluetooth.BluetoothState.STATE_OFF){
this.isOn=false
}
}
如果當(dāng)前設(shè)備藍(lán)牙未打開,則通過調(diào)用 bluetooth.enableBluetooth()藍(lán)牙接口來打開藍(lán)牙。
//打開藍(lán)牙函數(shù)
initBluetooth(){
this.enable=bluetooth.enableBluetooth()
//判斷藍(lán)牙是否成功打開
if(this.enable==true){
prompt.showToast({
message:'Openbluetooth'+this.enable,
duration:2000,
});
}
}
③注冊(cè)發(fā)現(xiàn) BLE 設(shè)備監(jiān)聽器
在設(shè)備打開藍(lán)牙之后,通過調(diào)用 bluetooth.BLE.on('BLEDeviceFind')藍(lán)牙接口來訂閱 BLE 設(shè)備發(fā)現(xiàn)上報(bào)事件。 該接口參數(shù)如下:

通過注冊(cè)發(fā)現(xiàn) BLE 設(shè)備監(jiān)聽器,可以得到發(fā)現(xiàn)設(shè)備的集合,BLE 設(shè)備的廣播包、地址、信號(hào)強(qiáng)度 rssi。
在這里發(fā)現(xiàn)獲取連接 BLE 設(shè)備名字的接口 getDeviceName 無法成功調(diào)用,所以自己通過解析廣播包來獲取設(shè)備名字。
//訂閱BLE設(shè)備發(fā)現(xiàn)上報(bào)事件
//獲取到的data包括BLE設(shè)備的廣播包、地址、信號(hào)強(qiáng)度rssi
bluetooth.BLE.on('BLEDeviceFind',(data)=>{
logger.info(TAG,`enteronbluetoothBLEDeviceFind`)
logger.info("rgytl 開始掃描設(shè)備地址! 1")
if(data!==null&&data.length>0){
logger.info("rgytl 開始掃描設(shè)備地址! 2")
if(this.discoveryBleList.indexOf(data[0])===-1){
//把發(fā)現(xiàn)的設(shè)備地址存入列表
this.discoveryBleList.push(data[0].deviceId)
logger.info("rgytl----discoveryBleList="+JSON.stringify(this.discoveryBleList))
//讀取廣播包,解析廣播包,得到設(shè)備名字,并存入設(shè)備列表
vari=0;
varx=data[0].data[i]
vary=data[0].data[i+1]
while(y!=0x09&&i+x+2
④開啟 BLE 設(shè)備掃描
在完成訂閱 BLE 設(shè)備發(fā)現(xiàn)上報(bào)事件后,通過調(diào)用 bluetooth.BLE.startBLEScan 接口去開啟 BLE 設(shè)備掃描。 通過該接口,可以對(duì)掃描 BLE 設(shè)備進(jìn)行過濾,可以過濾的參數(shù)有:BLE 設(shè)備的地址、名字、以及服務(wù)的 UUID 等。

在這里,我設(shè)置只掃描包含我 BLE 設(shè)備名字的 BLE 設(shè)備,這樣子就不會(huì)說掃描到一大堆其他的 BLE 設(shè)備,影響使用,只需要開啟一次掃描和訂閱一次 BLE 設(shè)備發(fā)現(xiàn)上報(bào)事件就可以了,使用的時(shí)候只要沒有關(guān)閉,就不需要重復(fù)調(diào)用。
//設(shè)置藍(lán)牙BLE掃描模式(根據(jù)名字掃描)
bluetooth.BLE.startBLEScan(
[{
deviceId:null,
name:"bleslavetest",
serviceUuid:null
}],
{
interval:0,
dutyMode:bluetooth.ScanDuty.SCAN_MODE_LOW_POWER,
matchMode:bluetooth.MatchMode.MATCH_MODE_AGGRESSIVE,
}
)
⑤連接 BLE 設(shè)備
在掃描到 BLE 設(shè)備之后,可以通過 on(‘BLEConnectionStateChange’)來訂閱獲取 BLE 設(shè)備的連接狀態(tài)變化事件。 在使用該接口之前,要先通過 bluetooth.BLE.createGattClientDevice('XXXXXX:XX')接口創(chuàng)建一個(gè)可使用的 GattClientDevice 實(shí)例。

//訂閱BEL狀態(tài)變化
if(this.BleOnflag){
//只創(chuàng)建一個(gè)GattClient對(duì)象
this.BleOnflag=false
this.BLEDevice=bluetooth.BLE.createGattClientDevice(item);
//訂閱獲取BLE設(shè)備的連接狀態(tài)變化事件
this.BLEDevice.on('BLEConnectionStateChange',(data)=>{
console.log('bluetoothconnectStatestatechanged');
letconnectState=data.state;
//根據(jù)不通的連接狀態(tài),提示不同的信息
if(JSON.stringify(connectState)==0){
logger.info(`connectState=${JSON.stringify(connectState)},斷開連接`)
prompt.showToast({
message:'斷開連接',
duration:2000,
});
}elseif(JSON.stringify(connectState)==2){
logger.info(`connectState=${JSON.stringify(connectState)},連接成功`)
prompt.showToast({
message:'連接成功',
duration:2000,
});
}elseif(JSON.stringify(connectState)==1){
logger.info(`connectState=${JSON.stringify(connectState)},正在連接`)
}else{
logger.info(`connectState=${JSON.stringify(connectState)},正在斷連`)
}
logger.info(`connectState=${JSON.stringify(connectState)}`);
})
}
在前面通過 bluetooth.BLE.createGattClientDevice(item)創(chuàng)建一個(gè) GattClientDevice 實(shí)例 BLEDevice 后,我們可以通過該實(shí)例去調(diào)用 connect()方法連接 BLE 設(shè)備。
注意,GattClientDevice 實(shí)例只需要?jiǎng)?chuàng)建一個(gè)就可以。

//連接藍(lán)牙
letBLEConnect=this.BLEDevice.connect()
//如果連接成功,則把BLE設(shè)備存入連接成功列表
if(BLEConnect){
this.deviceBleList.push(item)
}
⑥結(jié)尾處理
當(dāng)不連接 BLE 設(shè)備的時(shí)候,要記得關(guān)閉 BLE 設(shè)備掃描,取消訂閱設(shè)備發(fā)現(xiàn)事件。
取消 BLE 設(shè)備連接,通過之前創(chuàng)建的 GattClientDevice 實(shí)例 BLEDevice 調(diào)用 disconnect()方法斷開連接 BLE 設(shè)備。
Button("斷開")
.alignSelf(ItemAlign.Center)
.onClick(()=>{
AlertDialog.show({
title:$r('app.string.disconnect'),
message:'此操作將會(huì)斷開該設(shè)備的連接',
primaryButton:{
value:$r('app.string.cancel'),
action:()=>{
}
},
secondaryButton:{
value:$r('app.string.confirm'),
action:()=>{
//斷開連接BLE設(shè)備
letBLEdisConnect=this.BLEDevice.disconnect()
if(BLEdisConnect){
logger.info(`connectStateBLEdisConnect=${JSON.stringify(BLEdisConnect)},斷開連接`)
//移出BLE設(shè)備連接列表
this.deviceBleList.pop(item)
}
}
}
})
})
在斷開連接、關(guān)閉藍(lán)牙之后,可以通過 off(‘connectStateChange’)取消訂閱 BLE 連接狀態(tài)變化事件、bluetooth.BLE.stopBLEScan 停止 BLE 掃描、以及 bluetooth.BLE.off(‘BLEDeviceFind’)取消訂閱 BLE 設(shè)備發(fā)現(xiàn)上報(bào)事件。
最后通過 bluetooth.disableBluetooth()關(guān)閉藍(lán)牙:
.onChange((isOn:boolean)=>{
if(isOn){
this.isOn=true
this.initBluetooth()
}else{
this.isOn=false
bluetooth.BLE.off('BLEDeviceFind',()=>{
logger.info("rgytl 取消BLE設(shè)備發(fā)現(xiàn)訂閱!")
})
bluetooth.BLE.stopBLEScan()
this.disable=bluetooth.disableBluetooth()
this.discoveryList=[]
this.BleInfo=[]
this.BleRssi=[]
if(this.disable==true){
prompt.showToast({
message:'Closebluetooth'+this.disable,
duration:2000,
});
}
}
})
審核編輯:湯梓紅
-
接口
+關(guān)注
關(guān)注
33文章
9519瀏覽量
157019 -
BLE
+關(guān)注
關(guān)注
13文章
776瀏覽量
66339 -
藍(lán)牙模塊
+關(guān)注
關(guān)注
30文章
662瀏覽量
57855 -
SDK
+關(guān)注
關(guān)注
3文章
1101瀏覽量
51713 -
OpenHarmony
+關(guān)注
關(guān)注
33文章
3952瀏覽量
21095
原文標(biāo)題:OpenHarmony BLE藍(lán)牙連接
文章出處:【微信號(hào):gh_834c4b3d87fe,微信公眾號(hào):OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
BLE多連接技術(shù)對(duì)比與應(yīng)用
FCC & CE認(rèn)證 藍(lán)牙5.1協(xié)議 主從并存 低功耗藍(lán)牙模塊BLE5101# 藍(lán)牙
BLE低功耗藍(lán)牙模塊為何如此受歡迎?
經(jīng)驗(yàn)分享:如何選擇適合的BLE藍(lán)牙模塊
如何利用API增加BLE連接性
BLE藍(lán)牙的角色功能
盤點(diǎn)BLE低功耗藍(lán)牙和傳統(tǒng)藍(lán)牙之間的五大區(qū)別
BLE藍(lán)牙模塊選型表介紹
BLE藍(lán)牙的具體優(yōu)勢(shì)以及BLE藍(lán)牙智能門鎖的應(yīng)用
藍(lán)牙和BLE(低功耗藍(lán)牙)的區(qū)別是什么
藍(lán)牙模塊有哪些種類?BLE低功耗藍(lán)牙模塊有什么特點(diǎn)?
Telink BLE多連接應(yīng)用的SDK簡(jiǎn)介
帶你深入了解BLE藍(lán)牙模塊工作模式
OpenHarmony BLE藍(lán)牙連接教程
評(píng)論