這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
本文簡介
這是一次真實的 藍牙收發資料 的全程序講解,
本文使用 uni-app + Vue3 的方式進行開發,以手機app的方式運行(微信小程式同樣可行),
uni-app 提供了 藍牙 和 低功耗藍牙 的 api ,和微信小程式提供的 api 是一樣的,所以本文的講解也適用于微信小程式,
本文只實作 藍牙收發資料 功能,至于樣式,我懶得調~
藍牙相關功能我會逐步講解,如果你基礎好,又急的話,可以直接跳到 『完整代碼』的章節查看,那里沒廢話,
環境說明
開發工具:HBuilder X 3.4.7.20220422
uni-app + Vue3
以安卓App的方式運行(iOS和小程式同理)
思路
藍牙收發資料的邏輯和我們常用的 AJAX 進行的網路請求是有一丟丟不同的,
其中較大的區別是:藍牙接收資料不是那么的穩定,相比起網路請求,藍牙更容易出現丟包的情況,
在開發中,AJAX 發起的請求不管成功還是失敗,瀏覽器基本都會給你一個答復,但 uni-app 提供的 api 來看,藍牙接收資料會顯得更加 “異步” ,
大致思路
使用藍牙進行資料傳輸的大概思路如下:
初始化:打開藍牙模塊
搜尋:檢測附近存在的設備
連接:找到目標設備進行
監聽:開啟監聽功能,接收其他設備傳過來的資料
發送指令:不管發送資料還是讀取資料,都可以理解為向外發送指令
實作
上面整理出使用藍牙傳輸資料的5大動作,但每個動作其實都是由 uni-app 提供的一個或者多個 api 組合而成,
初始化階段
使用藍牙之前,需要初始化藍牙模塊,這是最最最開始就要做的!
使用 uni.openBluetoothAdapter 這個 api 就可以初始化藍牙模塊,其他藍牙相關 API 必須在 uni.openBluetoothAdapter 呼叫之后使用,否則 API 會回傳錯誤( errCode=10000 ),
代碼示例
<template>
<view>
<button @click="initBlue">初始化藍牙</button>
</view>
</template>
?
<script setup> ?
// 【1】初始化藍牙
function initBlue() {
uni.openBluetoothAdapter({
success(res) {
console.log('初始化藍牙成功')
console.log(res)
},
fail(err) {
console.log('初始化藍牙失敗')
console.error(err)
}
})
} </script>
如果你手機開啟了藍牙,點擊頁面上的按鈕后,控制臺就會輸出如下內容
初始化藍牙成功
{"errMsg":"openBluetoothAdapter:ok"}
如果手機沒開啟藍牙,就會回傳如下內容
初始化藍牙失敗
{"errMsg":"openBluetoothAdapter:fail not available","code":10001}
根據檔案提示,10001代表當前藍牙配接器不可用,


如果你的控制臺能列印出 {"errMsg":"openBluetoothAdapter:ok"} 證明第一步已經成功了,
接下來可以開始搜索附近藍牙設備,
搜尋附近設備
這一步需要2個 api 配合完成,所以可以分解成以下2步:
開啟搜尋功能:uni.startBluetoothDevicesDiscovery
監聽搜尋到新設備:uni.onBluetoothDeviceFound
開發藍牙相關功能時,操作邏輯更像是推送,所以“開啟搜索”和“監聽新設備”是分開操作的,
uni.startBluetoothDevicesDiscovery 可以讓設備開始搜索附近藍牙設備,但這個方法比較耗費系統資源,建議在連接到設備之后就使用 uni.stopBluetoothDevicesDiscovery 停止繼續搜索,
uni.startBluetoothDevicesDiscovery 方法里可以傳入一個物件,該物件接收幾個引數,但初學的話我們只關注 success 和 fail,如果你的專案中硬體佬有提供 service 的 uuid 給你的話,你也可以在 services 里傳入,其他引數可以查看官方檔案的介紹,
在使用 uni.startBluetoothDevicesDiscovery (開始搜索)后,可以使用 uni.onBluetoothDeviceFound 進行監聽,這個方法里面接收一個回呼函式,
代碼示例
<template>
<view>
<scroll-view
scroll-y
>
<view v-for="item in blueDeviceList">
<view>
<text>id: {{ item.deviceId }}</text>
</view>
<view>
<text>name: {{ item.name }}</text>
</view>
</view>
</scroll-view>
<button @click="initBlue">初始化藍牙</button>
<button @click="discovery">搜索附近藍牙設備</button>
</view>
</template>
<script setup> import { ref } from 'vue'
// 搜索到的藍牙設備串列
const blueDeviceList = ref([])
// 【1】初始化藍牙
function initBlue() {
uni.openBluetoothAdapter({
success(res) {
console.log('初始化藍牙成功')
console.log(res)
},
fail(err) {
console.log('初始化藍牙失敗')
console.error(err)
}
})
}
// 【2】開始搜尋附近設備
function discovery() {
uni.startBluetoothDevicesDiscovery({
success(res) {
console.log('開始搜索')
// 開啟監聽回呼
uni.onBluetoothDeviceFound(found)
},
fail(err) {
console.log('搜索失敗')
console.error(err)
}
})
}
// 【3】找到新設備就觸發該方法
function found(res) {
console.log(res)
blueDeviceList.value.push(res.devices[0])
} </script>
<style> .box {
width: 100%;
height: 400rpx;
box-sizing: border-box;
margin-bottom: 20rpx;
border: 2px solid dodgerblue;
}
.item {
box-sizing: border-box;
padding: 10rpx;
border-bottom: 1px solid #ccc;
}
button {
margin-bottom: 20rpx;
} </style>
上面代碼的邏輯是,如果開啟 “尋找附近設備” 功能成功,接著就開啟 “監聽尋找到新設備的事件” ,
搜索到的設備會回傳以下資料:
{
"devices": [{
"deviceId": "B4:10:7B:C4:83:14",
"name": "藍牙設備名",
"RSSI": -58,
"localName": "",
"advertisServiceUUIDs": ["0000FFF0-0000-1000-8000-00805F9B34FB"],
"advertisData": {}
}]
}
每監聽到一個新的設備,我都會將其添加到 藍牙設備串列(blueDeviceList) 里,最后講這個串列的資料渲染到頁面上,
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cePpaik0-1652253685142)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f3a21f372d3b40e996e3a0db9f4aa66b~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]
連接目標設備
連接目標設備只需要1個 api 就能完成,但根據檔案提示,我們連接后還需要關閉 “搜索附近設備” 的功能,這個很好理解,既然找到了,再繼續找就是浪費資源,
流程如下:
獲取設備ID:根據 uni.onBluetoothDeviceFound 回呼,拿到設備ID
連接設備:使用設備ID進行連接 uni.createBLEConnection
停止搜索:uni.stopBluetoothDevicesDiscovery
我給每條搜索到的藍牙結果添加一個 click 事件,會向目標設備發送連接請求,
我的設備名稱是 leihou ,所以我點擊了這條,
代碼示例
<template>
<view>
<scroll-view
scroll-y
>
<view v-for="item in blueDeviceList" @click="connect(item)">
<view>
<text>id: {{ item.deviceId }}</text>
</view>
<view>
<text>name: {{ item.name }}</text>
</view>
</view>
</scroll-view>
<button @click="initBlue">初始化藍牙</button>
<button @click="discovery">搜索附近藍牙設備</button>
?
</view>
</template>
?
<script setup> import { ref } from 'vue'
?
// 搜索到的藍牙設備串列
const blueDeviceList = ref([])
?
// 【1】初始化藍牙
function initBlue() {
uni.openBluetoothAdapter({
success(res) {
console.log('初始化藍牙成功')
console.log(res)
},
fail(err) {
console.log('初始化藍牙失敗')
console.error(err)
}
})
}
?
// 【2】開始搜尋附近設備
function discovery() {
uni.startBluetoothDevicesDiscovery({
success(res) {
console.log('開始搜索')
// 開啟監聽回呼
uni.onBluetoothDeviceFound(found)
},
fail(err) {
console.log('搜索失敗')
console.error(err)
}
})
}
?
// 【3】找到新設備就觸發該方法
function found(res) {
console.log(res)
blueDeviceList.value.push(res.devices[0])
}
?
// 藍牙設備的id
const deviceId = ref('')
?
// 【4】連接設備
function connect(data) {
console.log(data)
?
deviceId.value = https://www.cnblogs.com/smileZAZ/archive/2023/02/15/data.deviceId
?
uni.createBLEConnection({
deviceId: deviceId.value,
success(res) {
console.log('連接成功')
console.log(res)
// 停止搜索
stopDiscovery()
},
fail(err) {
console.log('連接失敗')
console.error(err)
}
})
}
?
// 【5】停止搜索
function stopDiscovery() {
uni.stopBluetoothDevicesDiscovery({
success(res) {
console.log('停止成功')
console.log(res)
},
fail(err) {
console.log('停止失敗')
console.error(err)
}
})
} </script>
?
<style> .box {
width: 100%;
height: 400rpx;
box-sizing: border-box;
margin-bottom: 20rpx;
border: 2px solid dodgerblue;
}
.item {
box-sizing: border-box;
padding: 10rpx;
border-bottom: 1px solid #ccc;
}
button {
margin-bottom: 20rpx;
} </style>
連接成功后在控制臺會輸出
連接成功
{"errMsg":"createBLEConnection:ok"}
在連接成功后就立刻呼叫 uni.stopBluetoothDevicesDiscovery 方法停止繼續搜索附近其他設備,停止成功后會輸出
停止成功
{"errMsg":"stopBluetoothDevicesDiscovery:ok"}
監聽
在連接完設備后,就要先開啟監聽資料的功能,這樣才能接收到發送讀寫指令后設備給你回呼的資訊,
要開啟監聽,首先需要知道藍牙設備提供了那些服務,然后通過服務獲取特征值,特征值會告訴你哪個可讀,哪個可寫,最后根據特征值進行訊息監聽,
步驟如下:
獲取藍牙設備服務:uni.getBLEDeviceServices
獲取特征值:uni.getBLEDeviceCharacteristics
開啟訊息監聽:uni.notifyBLECharacteristicValueChange
接收訊息監聽傳來的資料:uni.onBLECharacteristicValueChange
正常情況下,硬體佬會提前把藍牙設備的指定服務還有特征值告訴你,
比如我這個設備的藍牙服務是:0000FFE0-0000-1000-8000-00805F9B34FB
特征值是:0000FFE1-0000-1000-8000-00805F9B34FB
第一步,獲取藍牙服務
<template>
<view>
<!-- 省略上一步的代碼 -->
<button @click="getServices">獲取藍牙服務</button>
</view>
</template>
?
<script setup> import { ref } from 'vue'
?
// 省略上一步的代碼……
?
// 【6】獲取服務
function getServices() {
uni.getBLEDeviceServices({
deviceId: deviceId.value, // 設備ID,在上一步【4】里獲取
success(res) {
console.log(res)
},
fail(err) {
console.error(err)
}
})
} </script>
此時點擊按鈕,將會獲取到已連接設備的所有服務,
我的設備有以下幾個服務,你在作業中拿到的 服務uuid 和我的是不一樣的,數量也不一定相同,
可以發現,我拿到的結果里有 0000FFE0-0000-1000-8000-00805F9B34FB 這條服務,
{
"services": [{
"uuid": "00001800-0000-1000-8000-00805F9B34FB",
"isPrimary": true
}, {
"uuid": "00001801-0000-1000-8000-00805F9B34FB",
"isPrimary": true
}, {
"uuid": "0000180A-0000-1000-8000-00805F9B34FB",
"isPrimary": true
}, {
"uuid": "0000FFF0-0000-1000-8000-00805F9B34FB",
"isPrimary": true
}, {
"uuid": "0000FFE0-0000-1000-8000-00805F9B34FB",
"isPrimary": true
}],
"errMsg": "getBLEDeviceServices:ok"
}
第二步,獲取指定服務的特征值
獲取特征值,需要傳 設備ID 和 服務ID,
在上兩步我拿到了 設備ID 為 B4:10:7B:C4:83:14,服務ID 為 0000FFE0-0000-1000-8000-00805F9B34FB,
<template>
<view>
<!-- 省略前面幾步代碼 -->
<button @click="getCharacteristics">獲取特征值</button>
</view>
</template>
?
<script setup> import { ref } from 'vue'
?
// 省略前面幾步代碼
?
// 【7】獲取特征值
function getCharacteristics() {
uni.getBLEDeviceCharacteristics({
deviceId: deviceId.value, // 設備ID,在【4】里獲取到
serviceId: '0000FFE0-0000-1000-8000-00805F9B34FB', // 服務UUID,在【6】里能獲取到
success(res) {
console.log(res)
},
fail(err) {
console.error(err)
}
})
} </script>
最后成功輸出
{
"characteristics": [{
"uuid": "0000FFE1-0000-1000-8000-00805F9B34FB",
"properties": {
"read": true,
"write": true,
"notify": true,
"indicate": false
}
}],
"errMsg": "getBLEDeviceCharacteristics:ok"
}
characteristics 欄位里保存了該服務的所有特征值,我的設備這個服務只有1個特征值,并且讀、寫、訊息推送都為 true,
你的設備可能不止一條特征值,需要監聽那條特征值這需要你和硬體佬協商的(通常也是硬體佬直接和你說要監聽哪條),
第三、四步,開啟訊息監聽 并 接收訊息監聽傳來的資料
根據已經拿到的 設備ID、服務ID、特征值,就可以開啟對應的監聽功能,
使用 uni.notifyBLECharacteristicValueChange 開啟訊息監聽;
并在 uni.onBLECharacteristicValueChange 方法觸發監聽到的訊息,
<template>
<view>
<!-- 省略前面幾步代碼 -->
<button @click="notify">開啟訊息監聽</button>
</view>
</template>
?
<script setup> import { ref } from 'vue'
?
// 省略前面幾步代碼
?
// 【8】開啟訊息監聽
function notify() {
uni.notifyBLECharacteristicValueChange({
deviceId: deviceId.value, // 設備ID,在【4】里獲取到
serviceId: '0000FFE0-0000-1000-8000-00805F9B34FB', // 服務UUID,在【6】里能獲取到
characteristicId: '0000FFE1-0000-1000-8000-00805F9B34FB', // 特征值,在【7】里能獲取到
success(res) {
console.log(res)
// 接受訊息的方法
listenValueChange()
},
fail(err) {
console.error(err)
}
})
}
?
// ArrayBuffer轉16進度字串示例
function ab2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('')
}
?
// 將16進制的內容轉成我們看得懂的字串內容
function hexCharCodeToStr(hexCharCodeStr) {
var trimedStr = hexCharCodeStr.trim();
var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
var len = rawStr.length;
if (len % 2 !== 0) {
alert("存在非法字符!");
return "";
}
var curCharCode;
var resultStr = [];
for (var i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16);
resultStr.push(String.fromCharCode(curCharCode));
}
return resultStr.join("");
}
?
// 【9】監聽訊息變化
function listenValueChange() {
uni.onBLECharacteristicValueChange(res => {
// 結果
console.log(res)
// 結果里有個value值,該值為 ArrayBuffer 型別,所以在控制臺無法用肉眼觀察到,必須將該值轉換為16進制
let resHex = ab2hex(res.value)
console.log(resHex)
?
// 最后將16進制轉換為ascii碼,就能看到對應的結果
let result = hexCharCodeToStr(resHex)
console.log(result)
})
} </script>
listenValueChange 方法是用來接收設備傳過來的訊息,
上面的例子中,res 的結果是
{
"deviceId": "B4:10:7B:C4:83:14",
"serviceId": "0000FFE0-0000-1000-8000-00805F9B34FB",
"characteristicId": "0000FFE1-0000-1000-8000-00805F9B34FB",
"value": {}
}
設備傳過來的內容就放在 value 欄位里,但因為該欄位的型別是 ArrayBuffer,所以無法在控制臺用肉眼直接觀察,于是就通過 ab2hex 方法將該值轉成 16進制 ,最后再用 hexCharCodeToStr 方法將 16進制 轉成 ASCII碼,
我從設備里發送一段字串過來:leihou

App端收到的資料轉成 16進制 后的結果:6c6569686f75
再從 16進制 轉成 ASCII碼 后的結果:leihou
發送指令
終于到最后一步了,
從 uni-app 和 微信小程式 提供的藍牙api 來看,發送指令只要有2個方法:
uni.writeBLECharacteristicValue:向低功耗藍牙設備特征值中寫入二進制資料,
uni.readBLECharacteristicValue:讀取低功耗藍牙設備的特征值的二進制資料值,
這里需要理清一個概念,本節的內容為 “發送指令” ,也就是說,從你的app或小程式向其他藍牙設備發送指令,而這個指令分2種情況,一種是你要發送一些資料給藍牙設備,另一種情況是你叫藍牙設備給你發點資訊,
uni.writeBLECharacteristicValue
這兩種情況我們需要分開討論,先講講 uni.writeBLECharacteristicValue ,
uni.writeBLECharacteristicValue 從檔案可以看出,這個 api 是可以發送一些資料給藍牙設備,但發送的值要轉成 ArrayBuffer ,
代碼示例
<template>
<view>
<!-- 省略前面幾步代碼 -->
<button @click="send">發送資料</button>
</view>
</template>
?
<script setup> import { ref } from 'vue'
?
// 省略前面幾步代碼
?
// 【10】發送資料
function send() {
// 向藍牙設備發送一個0x00的16進制資料
let msg = 'hello'
const buffer = new ArrayBuffer(msg.length)
const dataView = new DataView(buffer)
// dataView.setUint8(0, 0)
for (var i = 0; i < msg.length; i++) {
dataView.setUint8(i, msg.charAt(i).charCodeAt())
}
uni.writeBLECharacteristicValue({
deviceId: deviceId.value, // 設備ID,在【4】里獲取到
serviceId: '0000FFE0-0000-1000-8000-00805F9B34FB', // 服務UUID,在【6】里能獲取到
characteristicId: '0000FFE1-0000-1000-8000-00805F9B34FB', // 特征值,在【7】里能獲取到
value: buffer,
success(res) {
console.log(res)
},
fail(err) {
console.error(err)
}
})
} </script>
此時,如果 uni.writeBLECharacteristicValue 走 success ,證明你已經把資料向外成功發送了,但不代表設備一定就收到了,
通常設備收到你發送過去的資訊,會回傳一條訊息給你,而這個回呼訊息會在 uni.onBLECharacteristicValueChange 觸發,也就是 第【9】步 那里,但這是藍牙設備那邊控制的,你作為前端佬,人家“已讀不回”你也拿人家沒辦法,

uni.readBLECharacteristicValue
在 “監聽” 部分,我們使用了 uni.getBLEDeviceCharacteristics 獲取設備的特征值,我的設備提供的特征值支持 read ,所以可以使用 uni.readBLECharacteristicValue 向藍牙設備發送一條 “讀取” 指令,然后在 uni.onBLECharacteristicValueChange 里可以接收設備發送過來的資料,
代碼示例
<template>
<view>
<!-- 省略前面幾步代碼 -->
<button @click="read">讀取資料</button>
</view>
</template>
?
<script setup> import { ref } from 'vue'
?
// 省略前面幾步代碼
?
// 【11】讀取資料
function read() {
uni.readBLECharacteristicValue({
deviceId: deviceId.value,
serviceId: serviceId.value,
characteristicId: characteristicId.value,
success(res) {
console.log('讀取指令發送成功')
console.log(res)
},
fail(err) {
console.log('讀取指令發送失敗')
console.error(err)
}
})
} </script>
使用 “讀取” 的方式向設備發送指令,是不需要另外傳值的,
此時我的設備回傳 00

這個資料是硬體那邊設定的,
在日常作業中,uni.readBLECharacteristicValue 的作用主要是讀取資料,但使用場景不算很多,
我在作業中遇到的場景是:藍牙設備提供了幾個介面,而且傳過來的資料比較大,比如傳圖片給app這邊,我就會先用 uni.writeBLECharacteristicValue 告訴設備我現在需要取什么介面的資料,然后用 uni.readBLECharacteristicValue 發送讀取資料的請求,如果資料量比較大,就要重復使用 uni.readBLECharacteristicValue 進行讀取,比如上面的例子,我讀第一次的時候回傳 00 ,讀第二次就回傳 01 ……
最后再提醒一下,uni.readBLECharacteristicValue 只負責發送讀取的請求,并且里面的 success 和 fail 只是回傳你本次發送請求的動作是否成功,至于對面的藍牙設備有沒有收到這個指令你是不清楚的,
最后需要通過 uni.getBLEDeviceCharacteristics 監聽設備傳過來的資料,
完整代碼
<template>
<view>
<scroll-view
scroll-y
>
<view v-for="item in blueDeviceList" @click="connect(item)">
<view>
<text>id: {{ item.deviceId }}</text>
</view>
<view>
<text>name: {{ item.name }}</text>
</view>
</view>
</scroll-view>
<button @click="initBlue">1 初始化藍牙</button>
<button @click="discovery">2 搜索附近藍牙設備</button>
<button @click="getServices">3 獲取藍牙服務</button>
<button @click="getCharacteristics">4 獲取特征值</button>
<button @click="notify">5 開啟訊息監聽</button>
<button @click="send">6 發送資料</button>
<button @click="read">7 讀取資料</button>
<view >
<view >
監聽到的內容:{{ message }}
</view>
<view >
監聽到的內容(十六進制):{{ messageHex }}
</view>
</view>
?
</view>
</template>
?
<script setup> import { ref } from 'vue'
?
// 搜索到的藍牙設備串列
const blueDeviceList = ref([])
?
// 【1】初始化藍牙
function initBlue() {
uni.openBluetoothAdapter({
success(res) {
console.log('初始化藍牙成功')
console.log(res)
},
fail(err) {
console.log('初始化藍牙失敗')
console.error(err)
}
})
}
?
// 【2】開始搜尋附近設備
function discovery() {
uni.startBluetoothDevicesDiscovery({
success(res) {
console.log('開始搜索')
// 開啟監聽回呼
uni.onBluetoothDeviceFound(found)
},
fail(err) {
console.log('搜索失敗')
console.error(err)
}
})
}
?
// 【3】找到新設備就觸發該方法
function found(res) {
console.log(res)
blueDeviceList.value.push(res.devices[0])
}
?
// 藍牙設備的id
const deviceId = ref('')
?
// 【4】連接設備
function connect(data) {
console.log(data)
deviceId.value = https://www.cnblogs.com/smileZAZ/archive/2023/02/15/data.deviceId // 將獲取到的設備ID存起來
uni.createBLEConnection({
deviceId: deviceId.value,
success(res) {
console.log('連接成功')
console.log(res)
// 停止搜索
stopDiscovery()
uni.showToast({
title: '連接成功'
})
},
fail(err) {
console.log('連接失敗')
console.error(err)
uni.showToast({
title: '連接成功',
icon: 'error'
})
}
})
}
?
// 【5】停止搜索
function stopDiscovery() {
uni.stopBluetoothDevicesDiscovery({
success(res) {
console.log('停止成功')
console.log(res)
},
fail(err) {
console.log('停止失敗')
console.error(err)
}
})
}
?
// 【6】獲取服務
function getServices() {
// 如果是自動鏈接的話,uni.getBLEDeviceServices方法建議使用setTimeout延遲1秒后再執行
uni.getBLEDeviceServices({
deviceId: deviceId.value,
success(res) {
console.log(res) // 可以在res里判斷有沒有硬體佬給你的服務
uni.showToast({
title: '獲取服務成功'
})
},
fail(err) {
console.error(err)
uni.showToast({
title: '獲取服務失敗',
icon: 'error'
})
}
})
}
?
// 硬體提供的服務id,開發中需要問硬體佬獲取該id
const serviceId = ref('0000FFE0-0000-1000-8000-00805F9B34FB')
?
// 【7】獲取特征值
function getCharacteristics() {
// 如果是自動鏈接的話,uni.getBLEDeviceCharacteristics方法建議使用setTimeout延遲1秒后再執行
uni.getBLEDeviceCharacteristics({
deviceId: deviceId.value,
serviceId: serviceId.value,
success(res) {
console.log(res) // 可以在此判斷特征值是否支持讀寫等操作,特征值其實也需要提前向硬體佬索取的
uni.showToast({
title: '獲取特征值成功'
})
},
fail(err) {
console.error(err)
uni.showToast({
title: '獲取特征值失敗',
icon: 'error'
})
}
})
}
?
const characteristicId = ref('0000FFE1-0000-1000-8000-00805F9B34FB')
?
// 【8】開啟訊息監聽
function notify() {
uni.notifyBLECharacteristicValueChange({
deviceId: deviceId.value, // 設備id
serviceId: serviceId.value, // 監聽指定的服務
characteristicId: characteristicId.value, // 監聽對應的特征值
success(res) {
console.log(res)
listenValueChange()
uni.showToast({
title: '已開啟監聽'
})
},
fail(err) {
console.error(err)
uni.showToast({
title: '監聽失敗',
icon: 'error'
})
}
})
}
?
// ArrayBuffer轉16進度字串示例
function ab2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('')
}
?
// 將16進制的內容轉成我們看得懂的字串內容
function hexCharCodeToStr(hexCharCodeStr) {
var trimedStr = hexCharCodeStr.trim();
var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
var len = rawStr.length;
if (len % 2 !== 0) {
alert("存在非法字符!");
return "";
}
var curCharCode;
var resultStr = [];
for (var i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16);
resultStr.push(String.fromCharCode(curCharCode));
}
return resultStr.join("");
}
?
// 監聽到的內容
const message = ref('')
const messageHex = ref('') // 十六進制
?
// 【9】監聽訊息變化
function listenValueChange() {
uni.onBLECharacteristicValueChange(res => {
console.log(res)
let resHex = ab2hex(res.value)
console.log(resHex)
messageHex.value = https://www.cnblogs.com/smileZAZ/archive/2023/02/15/resHex
let result = hexCharCodeToStr(resHex)
console.log(String(result))
message.value = String(result)
})
}
?
// 【10】發送資料
function send() {
// 向藍牙設備發送一個0x00的16進制資料
let msg ='hello'
const buffer = new ArrayBuffer(msg.length)
const dataView = new DataView(buffer)
// dataView.setUint8(0, 0)
for (var i = 0; i < msg.length; i++) {
dataView.setUint8(i, msg.charAt(i).charCodeAt())
}
uni.writeBLECharacteristicValue({
deviceId: deviceId.value,
serviceId: serviceId.value,
characteristicId: characteristicId.value,
value: buffer,
success(res) {
console.log('writeBLECharacteristicValue success', res.errMsg)
uni.showToast({
title: 'write指令發送成功'
})
},
fail(err) {
console.error(err)
uni.showToast({
title: 'write指令發送失敗',
icon: 'error'
})
}
})
}
?
// 【11】讀取資料
function read() {
uni.readBLECharacteristicValue({
deviceId: deviceId.value,
serviceId: serviceId.value,
characteristicId: characteristicId.value,
success(res) {
console.log(res)
uni.showToast({
title: 'read指令發送成功'
})
},
fail(err) {
console.error(err)
uni.showToast({
title: 'read指令發送失敗',
icon: 'error'
})
}
})
} </script>
?
<style> .box {
width: 98%;
height: 400rpx;
box-sizing: border-box;
margin: 0 auto 20rpx;
border: 2px solid dodgerblue;
}
.item {
box-sizing: border-box;
padding: 10rpx;
border-bottom: 1px solid #ccc;
}
button {
margin-bottom: 20rpx;
}
?
.msg_x {
border: 2px solid seagreen;
width: 98%;
margin: 10rpx auto;
box-sizing: border-box;
padding: 20rpx;
}
?
.msg_x .msg_txt {
margin-bottom: 20rpx;
} </style>
本文轉載于:
https://blog.csdn.net/pfourfire/article/details/124711068
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/544052.html
標籤:其他
上一篇:JS table下載
下一篇:002. html篇之《表格》

