這篇文章將為大家詳細(xì)講解有關(guān)微信小程序如何實(shí)現(xiàn)藍(lán)牙連接,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
為繁昌等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及繁昌網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、繁昌網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
最近的項(xiàng)目需要使用小程序的藍(lán)牙功能與硬件設(shè)備進(jìn)行連接相互傳送數(shù)據(jù)指令,聯(lián)調(diào)過(guò)程中發(fā)現(xiàn)一些問(wèn)題,于是想著記錄下來(lái),方便以后查看!
1、初始化藍(lán)牙設(shè)備
一般使用藍(lán)牙功能肯定是想連接某一個(gè)藍(lán)牙設(shè)備,所以需要知道這個(gè)藍(lán)牙設(shè)備的名稱,一般來(lái)說(shuō)都是掃描二維碼連接,那么當(dāng)你掃描這個(gè)設(shè)備二維碼的時(shí)候,就需要去初始化你手機(jī)上的藍(lán)牙模塊了
/** * 初始化藍(lán)牙設(shè)備 */ initBlue:function(){ var that = this; wx.openBluetoothAdapter({//調(diào)用微信小程序api 打開藍(lán)牙適配器接口 success: function (res) { // console.log(res) wx.showToast({ title: '初始化成功', icon: 'success', duration: 800 }) that.findBlue();//2.0 }, fail: function (res) {//如果手機(jī)上的藍(lán)牙沒(méi)有打開,可以提醒用戶 wx.showToast({ title: '請(qǐng)開啟藍(lán)牙', icon: 'fails', duration: 1000 }) } }) },
2、搜索藍(lán)牙設(shè)備
手機(jī)藍(lán)牙初始化成功之后,就會(huì)去搜索周邊的藍(lán)牙設(shè)備
/** *開始搜索藍(lán)牙設(shè)備 */ findBlue(){ var that = this wx.startBluetoothDevicesDiscovery({ allowDuplicatesKey: false, interval: 0, success: function (res) { wx.showLoading({ title: '正在搜索設(shè)備', }) that.getBlue()//3.0 } }) },
3、獲取藍(lán)牙設(shè)備信息
搜索藍(lán)牙設(shè)備之后,需要獲取搜索到的藍(lán)牙設(shè)備信息,微信小程序提供了兩個(gè)方法可以獲取搜索到的藍(lán)牙設(shè)備信息,分別是:
wx.onBluetoothDeviceFound:監(jiān)聽尋找到新設(shè)備的事件 ,表示只要找到一個(gè)新的藍(lán)牙設(shè)備就會(huì)調(diào)用一次該方法。
wx.getBluetoothDevices:獲取在藍(lán)牙模塊生效期間所有已發(fā)現(xiàn)的藍(lán)牙設(shè)備,包括已經(jīng)和本機(jī)處于連接狀態(tài)的設(shè)備
看兩個(gè)方法的介紹我們知道他們的區(qū)別,但是不了解他們的區(qū)別會(huì)造成什么樣的問(wèn)題?
第一次我使用的是wx.onBluetoothDeviceFound方法進(jìn)行聯(lián)調(diào),發(fā)現(xiàn)一切正常,由于調(diào)試的時(shí)候就只有一臺(tái)設(shè)備,發(fā)現(xiàn)第二次重新掃碼這個(gè)藍(lán)牙設(shè)備的時(shí)候,找不到這個(gè)設(shè)備了,因?yàn)閷?duì)這個(gè)方法來(lái)說(shuō),這不是一個(gè)新的設(shè)備,以前連接上過(guò);或者當(dāng)你因?yàn)槟承┰蛩{(lán)牙傳送數(shù)據(jù)指令的時(shí)候出錯(cuò)了需要重新連接,再次連接的時(shí)候也找不到當(dāng)前設(shè)備,還是同樣的原因,因?yàn)楫?dāng)前設(shè)備對(duì)這個(gè)方法來(lái)說(shuō)不是一個(gè)新設(shè)備
所以后來(lái)我就用了wx.getBluetoothDevices方法
/** * 獲取搜索到的設(shè)備信息 */ getBlue(){ var that = this wx.getBluetoothDevices({ success: function(res) { wx.hideLoading(); for (var i = 0; i < res.devices.length; i++){ /*that.data.inputValue:表示的是需要連接的藍(lán)牙設(shè)備ID,簡(jiǎn)單點(diǎn)來(lái)說(shuō)就是我想要連接這個(gè)藍(lán)牙設(shè)備,所以我去遍歷我搜索到的藍(lán)牙設(shè)備中是否有這個(gè)ID*/ if (res.devices[i].name == that.data.inputValue || res.devices[i].localName == that.data.inputValue){ that.setData({ deviceId: res.devices[i].deviceId, consoleLog: "設(shè)備:" + res.devices[i].deviceId, }) that.connetBlue(res.devices[i].deviceId);//4.0 return; } } }, fail: function(){ console.log("搜索藍(lán)牙設(shè)備失敗") } }) },
4、連接藍(lán)牙設(shè)備
通過(guò)上一個(gè)步驟找到這個(gè)藍(lán)牙之后,通過(guò)藍(lán)牙設(shè)備的id進(jìn)行藍(lán)牙連接
/** * 獲取到設(shè)備之后連接藍(lán)牙設(shè)備 */ connetBlue(deviceId){ var that = this; wx.createBLEConnection({ // 這里的 deviceId 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接 deviceId: deviceId,//設(shè)備id success: function (res) { wx.showToast({ title: '連接成功', icon: 'fails', duration: 800 }) console.log("連接藍(lán)牙成功!") wx.stopBluetoothDevicesDiscovery({ success: function (res) { console.log('連接藍(lán)牙成功之后關(guān)閉藍(lán)牙搜索'); } }) that.getServiceId()//5.0 } }) },
5、獲取服務(wù)uuid
連接上需要的藍(lán)牙設(shè)備之后,獲取這個(gè)藍(lán)牙設(shè)備的服務(wù)uuid
getServiceId(){ var that = this wx.getBLEDeviceServices({ // 這里的 deviceId 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接 deviceId: that.data.deviceId, success: function (res) { var model = res.services[0] that.setData({ services: model.uuid }) that.getCharacteId()//6.0 } }) },
6、通過(guò)id查看藍(lán)牙設(shè)備的特征值
如果一個(gè)藍(lán)牙設(shè)備需要進(jìn)行數(shù)據(jù)的寫入以及數(shù)據(jù)傳輸,就必須具有某些特征值,所以通過(guò)上面步驟獲取的id可以查看當(dāng)前藍(lán)牙設(shè)備的特征值
getCharacteId(){ var that = this wx.getBLEDeviceCharacteristics({ // 這里的 deviceId 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接 deviceId: that.data.deviceId, // 這里的 serviceId 需要在上面的 getBLEDeviceServices 接口中獲取 serviceId: that.data.services, success: function (res) { for (var i = 0; i < res.characteristics.length; i++) {//2個(gè)值 var model = res.characteristics[i] if (model.properties.notify == true) { that.setData({ notifyId: model.uuid//監(jiān)聽的值 }) that.startNotice(model.uuid)//7.0 } if (model.properties.write == true){ that.setData({ writeId: model.uuid//用來(lái)寫入的值 }) } } } }) },
7、從后臺(tái)服務(wù)器獲取的指令
startNotice(uuid){ var that = this; wx.notifyBLECharacteristicValueChange({ state: true, // 啟用 notify 功能 // 這里的 deviceId 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接 deviceId: that.data.deviceId, // 這里的 serviceId 需要在上面的 getBLEDeviceServices 接口中獲取 serviceId: that.data.services, // 這里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中獲取 characteristicId: uuid, //第一步 開啟監(jiān)聽 notityid 第二步發(fā)送指令 write success: function (res) { // 設(shè)備返回的方法 wx.onBLECharacteristicValueChange(function (res) { // 此時(shí)可以拿到藍(lán)牙設(shè)備返回來(lái)的數(shù)據(jù)是一個(gè)ArrayBuffer類型數(shù)據(jù),所以需要通過(guò)一個(gè)方法轉(zhuǎn)換成字符串 var nonceId = that.ab2hex(res.value) //拿到這個(gè)值后,肯定要去后臺(tái)請(qǐng)求服務(wù)(當(dāng)前步驟根據(jù)當(dāng)前需求自己書寫),獲取下一步操作指令寫入到藍(lán)牙設(shè)備上去 wx.request({ method: "POST", data: { xx:nonceId }, url: url, success: (res) => { //res.data.data.ciphertext:我這邊服務(wù)返回來(lái)的是16進(jìn)制的字符串,藍(lán)牙設(shè)備是接收不到當(dāng)前格式的數(shù)據(jù)的,需要轉(zhuǎn)換成ArrayBuffer that.sendMy(that.string2buffer(res.data.data.ciphertext))//8.0 // 服務(wù)器返回一個(gè)命令 我們要把這個(gè)命令寫入藍(lán)牙設(shè)備 } }) } }) },
8、將從后臺(tái)服務(wù)獲取的指令寫入到藍(lán)牙設(shè)備當(dāng)中
sendMy(buffer){ var that = this wx.writeBLECharacteristicValue({ // 這里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中獲取 deviceId: that.data.deviceId, // 這里的 serviceId 需要在上面的 getBLEDeviceServices 接口中獲取 serviceId: that.data.services, // 這里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中獲取 characteristicId: that.data.writeId,//第二步寫入的特征值 // 這里的value是ArrayBuffer類型 value: buffer, success: function (res) { console.log("寫入成功") }, fail: function () { console.log('寫入失敗') }, complete:function(){ console.log("調(diào)用結(jié)束"); } }) },
注:下面是需要使用到的兩個(gè)格式相互轉(zhuǎn)換的方法
/** * 將字符串轉(zhuǎn)換成ArrayBufer */ string2buffer(str) { let val = "" if(!str) return; let length = str.length; let index = 0; let array = [] while(index < length){ array.push(str.substring(index,index+2)); index = index + 2; } val = array.join(","); // 將16進(jìn)制轉(zhuǎn)化為ArrayBuffer return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) { return parseInt(h, 16) })).buffer }, /** * 將ArrayBuffer轉(zhuǎn)換成字符串 */ ab2hex(buffer) { var hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (bit) { return ('00' + bit.toString(16)).slice(-2) } ) return hexArr.join(''); },
注:以上是藍(lán)牙連接的全部流程,但是我們?cè)趯?shí)際使用中肯定不會(huì)這么順暢,而且藍(lán)牙發(fā)送指令的設(shè)備都會(huì)有一個(gè)特性,就是當(dāng)前藍(lán)牙設(shè)備有人連接上之后,其他人是搜索不到這個(gè)藍(lán)牙設(shè)備的,所以你需要考慮在某些個(gè)特殊情況,代碼里需要主動(dòng)斷開藍(lán)牙連接把設(shè)備釋放出來(lái)供其他用戶使用,還有就是將指令寫入藍(lán)牙設(shè)備的時(shí)候很容易出問(wèn)題,所以要寫個(gè)回調(diào)去多次寫入,保證成功性!
關(guān)于“微信小程序如何實(shí)現(xiàn)藍(lán)牙連接”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。