1、檢查小程序是否授權藍牙功能
initBluetooth() {const that = thiswx.getSetting({success: (res) => {if (res.authSetting.hasOwnProperty('scope.bluetooth')) {//'scope.bluetooth'屬性存在,且為falseif (!res.authSetting['scope.bluetooth']) {wx.showModal({title: '溫馨提示',showCancel: false,content: '獲取藍牙授權失敗,需要手動授權'})} else {that.openBluetooth();}} else {//'scope.bluetooth'屬性不存在,需要授權that.openBluetooth();}}})},
wx.getSetting()
方法獲取用戶的設置信息res.authSetting
包含scope.bluetooth
屬性,表示已經獲取到了藍牙權限的設置信息scope.bluetooth
的值為false
,即用戶沒有授權藍牙權限,為true
,即用戶已經授權藍牙權限,調用openBluetooth()
方法打開藍牙功能
打開授權
openBluetooth() {const that = thiswx.closeBluetoothAdapter({success(res) {wx.openBluetoothAdapter({success: function (res) {/*getBluetoothAdapterState() 獲取本機藍牙適配器狀態,判斷是否可用,available為false則因為用戶沒有開啟系統藍牙*/wx.getBluetoothAdapterState({success: function (res) {that.setData({findBluetoothState: setInterval(() => {if (!that.data.theBluetoothState) {that.initBluetooth()clearInterval(that.data.findTimer)}wx.getBluetoothAdapterState({success: function (res) {if (!res.available) {...}},fail: function (res) {...}})}, 1000)})// res.available==true適配器可用 res.available==false適配器不可用if (res.available) {that.findBluetooth()} else {wx.showModal({title: '溫馨提示',showCancel: false,content: '藍牙設備不可用',success(res) {...}})}},fail: function (res) {wx.showModal({title: '溫馨提示',showCancel: false,content: '藍牙設備不可用',success(res) {if (res.confirm) {wx.hideLoading()}}})}})},fail: function (err) {console.log(err);wx.showModal({title: '溫馨提示',showCancel: false,content: '藍牙初始化失敗,請確認藍牙功能已開啟',success(res) {...}})}})}})},
wx.closeBluetoothAdapter()
方法關閉藍牙適配器,在成功關閉藍牙適配器后的回調函數中,調用wx.openBluetoothAdapter()
方法打開藍牙適配器。先關閉再打開
的方式來初始化藍牙功能,確保藍牙適配器工作在一個可靠
的狀態下,這種做法可以幫助解決一些潛在的問題,比如之前可能存在的連接問題、緩存狀態或其他異常情況wx.getBluetoothAdapterState()
方法獲取本機藍牙適配器的狀態- 藍牙適配器可用(
res.available 為 true
),則去查找藍牙設備;不可用(res.available 為 false
),則給出提示
2、搜索附近藍牙設備并匹配
findBluetooth() {const that = thiswx.startBluetoothDevicesDiscovery({services: [],allowDuplicatesKey: false,success: function () {//獲取藍牙設備輸出信息列表let aaa = setInterval(() => {wx.getBluetoothDevices({success: function (res) {res.devices.forEach(item => {if (item.advertisData !== '') {if (...) {console.log('匹配到設備:deviceName-' + item.deviceName + ',deviceId-' + item.deviceId);that.creatDevice(item.deviceId)clearInterval(aaa)}}})}})}, 1000)},fail: function (err) {wx.showModal({title: '溫馨提示',showCancel: false,content: '搜索藍牙失敗,請檢測手機藍牙,定位功能是否已開啟',success(res) {if (res.confirm) {...}}})}});},
wx.startBluetoothDevicesDiscovery()
方法開始搜索附近的藍牙設備setInterval()
方法每隔一段時間執行一次藍牙設備搜索操作,在每次執行時,使用wx.getBluetoothDevices()
方法獲取附近的藍牙設備列表,根據匹配的條件,找到對應的設備,拿到設備的deviceId
去與該設備進行連接,注意及時清理定時器
拓展:
wx.getBluetoothDevices()
和 wx.onBluetoothDeviceFound
是小程序中用于搜索藍牙設備的兩種不同方法,它們有以下區別:
1、wx.getBluetoothDevices
- 用來主動搜索附近的藍牙設備,調用該方法后會返回附近的藍牙設備列表
- 是一個一次性的操作,即調用一次就會返回當前時刻附近的藍牙設備列表,之后如果需要重新搜索需要再次調用該方法
- 適用于需要手動觸發搜索藍牙設備的場景,比如用戶點擊搜索按鈕時
2、wx.onBluetoothDeviceFound
- 用來監聽附近藍牙設備的發現事件,當有新的藍牙設備被發現時會觸發該事件,從而可以實時獲取附近藍牙設備的信息
- 是一個被動的操作,即當有新的藍牙設備被發現時,會觸發相應的事件回調函數,無需手動觸發搜索
- 適用于需要實時監測附近藍牙設備變化的場景,比如展示附近藍牙設備列表并實時更新
3、連接藍牙設備
creatDevice(deviceId) {const that = thiswx.getConnectedBluetoothDevices({services: [this.data.serviceId],success(res) {console.log(res);if (res.devices.length > 0) {that.getServices(deviceId)} else {wx.createBLEConnection({deviceId,success: function (res) {console.log('連接成功輸出信息', res)wx.onBLEConnectionStateChange(function (res) {// 該方法回調中可以用于處理連接意外斷開等異常情況console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)if (!res.connected) {console.log('連接斷開');wx.offBLEConnectionStateChange()clearTimeout(that.data.doLinkAgainTimer)that.setData({doLinkAgainTimer: setTimeout(() => {that.creatDevice(deviceId)}, 200),})}})that.getServices(deviceId)},fail: function (err) {console.log(err, '連接失敗')},})}},fail(err) {console.log(err);}})
},
- 使用
wx.getConnectedBluetoothDevices()
方法獲取已連接的藍牙設備列表 - 如果已連接的設備列表中包含了符合特定服務 UUID 的設備,則直接去獲取服務
- 如果未找到已連接的符合條件的設備,則調用
wx.createBLEConnection()
方法嘗試連接指定的設備 - 如果連接成功,則會設置一個監聽器
wx.onBLEConnectionStateChange()
來監測藍牙連接狀態的變化。如果連接意外斷開,會在回調函數中重新嘗試連接,并設置一個定時器來控制重新連接的時間間隔。
4、獲取服務和特征值
getServices(deviceId) {const that = thiswx.getBLEDeviceServices({// 這里的 deviceId 需要已經通過 wx.createBLEConnection 與對應設備建立連接deviceId,success(res) {console.log('獲取服務:', res)that.getServicesCharacteristics(deviceId)},fail(err) {console.log('獲取服務失敗:', err);}})
},
getServicesCharacteristics(deviceId) {const that = thiswx.getBLEDeviceCharacteristics({// 這里的 deviceId 需要已經通過 wx.createBLEConnection 與對應設備建立連接deviceId,serviceId: this.data.serviceId,success(res) {console.log('獲取特征值:', res);let characteristics = res.characteristics.find(item => item.properties.notify)that.startNotice(characteristics.uuid)},fail(err) {console.log('獲取特征值失敗:', err);}})},
wx.getBLEDeviceServices
獲取到服務列表,里面每一條數據代表一個服務,UUID
是用來唯一標識一個藍牙服務的字符串wx.getBLEDeviceCharacteristics
獲取該服務的所有特征值列表,用properties
來區分,代表該特征值支持的操作類型
5、啟動藍牙服務值變化監聽及監聽特征值變化
startNotice(uuid){var that = this;wx.notifyBLECharacteristicValueChange({state: true, // 啟用 notify 功能deviceId: that.data.deviceid,serviceId: that.data.services,characteristicId: uuid, //第一步 開啟監聽 notityid 第二步發送指令 writesuccess: function (res) {wx.onBLECharacteristicValueChange(function (res) {}})
},
wx.notifyBLECharacteristicValueChang
用于啟用藍牙特征值變化通知wx.onBLECharacteristicValueChange
用于監聽藍牙設備特征值變化,當特征值發生變化時,會觸發這個函數,并可以在這里獲取變化后的值并進行相應的處理
6、建立長連接
藍牙設備通常需要建立長連接才能進行穩定的數據傳輸和控制。默認情況下,微信小程序與藍牙設備的連接會在一定時間內保持活躍,如果超過一定時間沒有數據交互或者沒有持續發送心跳包等保持連接的機制,連接可能會自動斷開。
獲取隨機數并進行外部認證通常用于建立安全連接
獲取隨機數
:設備A生成一個隨機數,并將其發送給設備B進行外部認證
:設備B收到隨機數后,可能會使用預共享密鑰或其他加密算法對隨機數進行處理,然后將處理后的結果發送給設備A驗證認證結果
:設備A收到處理后的結果后,進行驗證以確保通信雙方的身份和通信的完整性