手把手,教你調用小程序藍牙介面
文 | 極樂叔
這兩天,我試著在小程序中,調用藍牙設備介面。
這個模塊做了2周,找了很多資料文檔,看示例看別人的 demo,最後發現其實還是得靠自己。
下面,我將在知曉程序(微信號 zxcx0101)為大家總結,我在研究小程序藍牙介面的時候遇到的問題。
小程序如何連接藍牙設備?
我實現的小程序模塊自動連接(根據需要,可改手動),是在小程序初始化完成時開始自動調用執行。
大致流程:
開啟藍牙適配;
獲取藍牙適配器狀態,判斷設備藍牙是否可用;
判斷藍牙適配器可用時開啟掃描藍牙設備和開啟獲取已連接的藍牙設備;
如果開啟掃描藍牙設備失敗 5s 後,自動再次開啟掃描;
開啟掃描藍牙設備成功後,開啟監聽已掃描的設備;
如果已掃描到的新設備,包含特定名稱規律,則開始連接該設備;
開啟獲取已連接藍牙設備,成功後,連接包含特定名稱規律的設備;
兩者都無法搜索到相應設備,則等待 5 s,重新搜索;
開始連接某設備時停止掃描設備,停止循環獲取已連接設備;
連接成功後停止掃描設備,停止循環獲取已連接設備。
下面,我們一步步來完成這個流程。
手把手教你做小程序藍牙連接
1. 開啟連接
的 方法中,我們調用開啟連接 ,彈出提示框,開啟適配。如果失敗,則提示設備藍牙不可用,同時開啟藍牙適配器狀態監聽。
startConnect: function () { var that = this; wx.showLoading({ title: "開啟藍牙適配" }); wx.openBluetoothAdapter({ success: function (res) { console.log("初始化藍牙適配器"); console.log(res); that.getBluetoothAdapterState(); }, fail: function (err) { console.log(err); wx.showToast({ title: "藍牙初始化失敗", icon: "success", duration: 2000 }) setTimeout(function () { wx.hideToast() }, 2000) } }); wx.onBluetoothAdapterStateChange(function (res) { var available = res.available; if (available) { that.getBluetoothAdapterState(); } }) }2. 獲取本機藍牙狀態
調用 獲取本機藍牙適配器狀態,判斷是否可用, 為 ,則為用戶沒有開啟系統藍牙。
同時,判斷程序還沒有開始搜索藍牙設備,調用 開始掃描附近的藍牙設備,以及 ,獲取本機已配對的藍牙設備。
getBluetoothAdapterState: function () { var that = this; wx.getBluetoothAdapterState({ success: function (res) { var available = res.available, discovering = res.discovering; if (!available) { wx.showToast({ title: "設備無法開啟藍牙連接", icon: "success", duration: 2000 }) setTimeout(function () { wx.hideToast() }, 2000) } else { if (!discovering) { that.startBluetoothDevicesDiscovery(); that.getConnectedBluetoothDevices(); } } } }) }3. 開始搜索新設備
開始搜索藍牙設備 ,提示藍牙搜索。
startBluetoothDevicesDiscovery: function () { var that = this; wx.showLoading({ title: "藍牙搜索" }); wx.startBluetoothDevicesDiscovery({ services: [], allowDuplicatesKey: false, success: function (res) { if (!res.isDiscovering) { that.getBluetoothAdapterState(); } else { that.onBluetoothDeviceFound(); } }, fail: function (err) { console.log(err); } }); }4. 獲取已配對的藍牙設備
需要注意的是,參數 ()是必填的,但是官方示例中以及各種坑爹 demo 里從沒見過有誰填寫。不填寫這個屬性此方法,將無法獲取到任何已配對設備。
如果要調用此方法,則代表需要連接特定設備,並且知道該設備的一個主服務 。
如暫時不知道這個 ID,可以先手動連接一次想要連接的設備,然後獲取 列表,記錄屬性 為 的值至少一個。
getConnectedBluetoothDevices: function () { var that = this; wx.getConnectedBluetoothDevices({ services: [that.serviceId], success: function (res) { console.log("獲取處於連接狀態的設備", res); var devices = res["devices"], flag = false, index = 0, conDevList = []; devices.forEach(function (value, index, array) { if (value["name"].indexOf("FeiZhi") != -1) { // 如果存在包含FeiZhi欄位的設備 flag = true; index += 1; conDevList.push(value["deviceId"]); that.deviceId = value["deviceId"]; return; } }); if (flag) { this.connectDeviceIndex = 0; that.loopConnect(conDevList); } else { if (!this.getConnectedTimer) { that.getConnectedTimer = setTimeout(function () { that.getConnectedBluetoothDevices(); }, 5000); } } }, fail: function (err) { if (!this.getConnectedTimer) { that.getConnectedTimer = setTimeout(function () { that.getConnectedBluetoothDevices(); }, 5000); } } }); }5. 處理搜索功能開啟失敗的情況
如果搜索功能啟動失敗,回到第 2 步,重新檢查藍牙適配器。如果可用,開啟藍牙搜索功能成功後開啟發現附近藍牙設備事件監聽:。
onBluetoothDeviceFound: function () { var that = this; console.log("onBluetoothDeviceFound"); wx.onBluetoothDeviceFound(function (res) { console.log("new device list has founded") console.log(res); if (res.devices[0]) { var name = res.devices[0]["name"]; if (name != "") { if (name.indexOf("FeiZhi") != -1) { var deviceId = res.devices[0]["deviceId"]; that.deviceId = deviceId; console.log(that.deviceId); that.startConnectDevices(); } } } }) }
此方法可自定義過濾一些無效的藍牙設備比如 為空的,或是個人產品開發中需要過濾設備名稱不含有特定規律字元串的設備。
6. 自動連接設備
在第 5 步中發現了某個想配對的設備,則獲取到該設備的 ,然後開始配對該設備 。
startConnectDevices: function (ltype, array) { var that = this; clearTimeout(that.getConnectedTimer); that.getConnectedTimer = null; clearTimeout(that.discoveryDevicesTimer); that.stopBluetoothDevicesDiscovery(); this.isConnectting = true; wx.createBLEConnection({ deviceId: that.deviceId, success: function (res) { if (res.errCode == 0) { setTimeout(function () { that.getService(that.deviceId); }, 5000) } }, fail: function (err) { console.log("連接失敗:", err); if (ltype == "loop") { that.connectDeviceIndex += 1; that.loopConnect(array); } else { that.startBluetoothDevicesDiscovery(); that.getConnectedBluetoothDevices(); } }, complete: function () { console.log("complete connect devices"); this.isConnectting = false; } }); }
開啟連接後,為了避免出現衝突,一旦開啟連接,則需要終止掃描附近藍牙設備、終止讀取本機已配對設備。
7. 連接成功後握手
連接成功後,使用 介面,獲取設備的所有服務。
getService: function (deviceId) { var that = this; // 監聽藍牙連接 wx.onBLEConnectionStateChange(function (res) { console.log(res); }); // 獲取藍牙設備service值 wx.getBLEDeviceServices({ deviceId: deviceId, success: function (res) { that.getCharacter(deviceId, res.services); } }) }8. 讀取服務的特徵值
getCharacter: function (deviceId, services) { var that = this; services.forEach(function (value, index, array) { if (value == that.serviceId) { that.serviceId = array[index]; } }); wx.getBLEDeviceCharacteristics({ deviceId: deviceId, serviceId: that.serviceId, success: function (res) { that.writeBLECharacteristicValue(deviceId, that.serviceId, that.characterId_write); that.openNotifyService(deviceId, that.serviceId, that.characterId_read); }, fail: function (err) { console.log(err); }, complete: function () { console.log("complete"); } }) }9. 意外處理
如果掃描到的設備中沒有想要連接的設備,可以嘗試使用系統藍牙手動配對,然後再小程序中調用 獲取本機已配對的藍牙設備,然後過濾設備(可能獲取多個已配對的藍牙設備)。
將已獲取的藍牙設備 列表放入到一個數組中,然後調用自定義方法 。
思路:通過遞歸調用獲取已配對藍牙設備的 ,如果獲取到了就去連接,如果 為空,說明上傳調用 時,獲取到的已配對設備全部連接失敗了。
這時候,我們需要開啟重新獲取已配對藍牙設備的狀態,並開始掃描附近藍牙設備。
loopConnect: function (devicesId) { var that = this; var listLen = devicesId.length; if (devicesId[this.connectDeviceIndex]) { this.deviceId = devicesId[this.connectDeviceIndex]; this.startConnectDevices("loop", devicesId); } else { console.log("已配對的設備小程序藍牙連接失敗"); that.startBluetoothDevicesDiscovery(); that.getConnectedBluetoothDevices(); } }10. 自動連接藍牙設備
方法,是當獲取已配對藍牙設備進行連接時調用。
其中的處理邏輯上文已經貼出,意思就是在連接失敗後 方法里累加一個全局變數,然後回調 方法。
11. 手動連接
上文介紹的方法是為了直接自動連接,如果不需要自動連接,可在使用方法 將會獲取到已掃描到的藍牙設備的列表。
開發者可以做個頁面顯示出設備名,點擊該設備開始連接。
需要注意的事項
是在初始化時設置的,由於對需要連接設備的主服務 serivceId 和各種特徵值都是已知的因此可以這樣做。如果不可知可以做一個掃描方法自己檢查特徵值的用途。
連接成功後的 和 操作需要注意,如果同時開啟這兩項操作要先調用 再開啟 (原因未知,個人心得)。
3、經人提醒,還可以再完善一下在 監聽藍牙適配器狀態,以此判斷連接過程中、連接後用戶開關了設備藍牙。如果判斷到關了藍牙,發出開啟藍牙的提示;如果監聽到開啟了,就重新回到第 1 步。
最後本文屬於個人開發者的一點總結,歡迎留言指導討論。
關注「知曉程序」公眾號
※刷臉時代到來!小米都已經用上人臉識別了,iPhone 8會有嗎?
※標註圖像:超強大!有了這個 App,圖片標註從此一清二楚#iOS
※三星 Note 8 拆解:零件更好換,電池更安全
TAG:愛范兒 |