藍(lán)牙項(xiàng)目-微信小程序藍(lán)牙使用分享

導(dǎo)語(yǔ)

藍(lán)牙在日常生活中廣泛使用的一項(xiàng)技術(shù),小程序給了我們前端工程師一個(gè)控制藍(lán)牙的方法,帶上你的設(shè)備,來(lái)看看怎么控制你的藍(lán)牙設(shè)備吧。



1. 小程序藍(lán)牙介紹

藍(lán)牙終端:我們常說(shuō)的硬件設(shè)備,包括手機(jī),電腦等等。

設(shè)備地址:每個(gè)藍(lán)牙設(shè)備都有一個(gè)設(shè)備地址deviceId,但是安卓和IOS差別很大,安卓下設(shè)備地址就是mac地址,但是IOS無(wú)法獲取mac地址,所以設(shè)備地址是針對(duì)本機(jī)范圍有效的UUID,所以這里需要注意,后面會(huì)介紹。

2. API總覽

小程序?qū)λ{(lán)牙設(shè)備的操作有18個(gè)API

API名稱說(shuō)明

openBluetoothAdapter初始化藍(lán)牙適配器,在此可用判斷藍(lán)牙是否可用

closeBluetoothAdapter關(guān)閉藍(lán)牙連接,釋放資源

getBluetoothAdapterState獲取藍(lán)牙適配器狀態(tài),如果藍(lán)牙未開(kāi)或不可用,這里可用檢測(cè)到

onBluetoothAdapterStateChange藍(lán)牙適配器狀態(tài)發(fā)生變化事件,這里可用監(jiān)控藍(lán)牙的關(guān)閉和打開(kāi)動(dòng)作

startBluetoothDevicesDiscovery開(kāi)始搜索設(shè)備,藍(lán)牙初始化成功后就可以搜索設(shè)備

stopBluetoothDevicesDiscovery當(dāng)找到目標(biāo)設(shè)備以后需要停止搜索,因?yàn)樗阉髟O(shè)備是比較消耗資源的操作

getBluetoothDevices獲取已經(jīng)搜索到的設(shè)備列表

onBluetoothDeviceFound當(dāng)搜索到一個(gè)設(shè)備時(shí)的事件,在此可用過(guò)濾目標(biāo)設(shè)備

getConnectedBluetoothDevices獲取已連接的設(shè)備

createBLEConnection創(chuàng)建BLE連接

closeBLEConnection關(guān)閉BLE連接

getBLEDeviceServices獲取設(shè)備的服務(wù)列表,每個(gè)藍(lán)牙設(shè)備都有一些服務(wù)

getBLEDeviceCharacteristics獲取藍(lán)牙設(shè)備某個(gè)服務(wù)的特征值列表

readBLECharacteristicValue讀取低功耗藍(lán)牙設(shè)備的特征值的二進(jìn)制數(shù)據(jù)值

writeBLECharacteristicValue向藍(lán)牙設(shè)備寫(xiě)入數(shù)據(jù)

notifyBLECharacteristicValueChange開(kāi)啟藍(lán)牙設(shè)備notify提醒功能,只有開(kāi)啟這個(gè)功能才能接受到藍(lán)牙推送的數(shù)據(jù)

onBLEConnectionStateChange監(jiān)聽(tīng)藍(lán)牙設(shè)備錯(cuò)誤事件,包括異常斷開(kāi)等等

onBLECharacteristicValueChange監(jiān)聽(tīng)藍(lán)牙推送的數(shù)據(jù),也就是notify數(shù)據(jù)

4,小程序藍(lán)牙的主要流程

1,開(kāi)啟藍(lán)牙:調(diào)用openBluetoothAdapter,來(lái)判斷用戶手機(jī)的是否支持藍(lán)牙使用

wx.openBluetoothAdapter({

? ? success: function (res) {

? ? conosle.log('該用戶支持藍(lán)牙的使用')

????wx.getBluetoothAdapterState()調(diào)用小程序藍(lán)牙檢測(cè)是否開(kāi)啟

? ? },????

? ? fail(res){

?????conosle.log('該用戶不支持藍(lán)牙的使用')

? ? }
})

2, 檢查藍(lán)牙狀態(tài):調(diào)用getBluetoothAdapterState來(lái)檢查藍(lán)牙是否開(kāi)啟,如果沒(méi)有開(kāi)啟可以在這里提醒用戶開(kāi)啟藍(lán)牙,并且能在開(kāi)啟后自動(dòng)啟動(dòng)下面的步驟 這里有一個(gè)坑:IOS里面藍(lán)牙狀態(tài)變化以后不能馬上開(kāi)始搜索,否則會(huì)搜索不到設(shè)備,必須要等待2秒以上。


wx.getBluetoothAdapterState({ //獲取本機(jī)藍(lán)牙適配器狀態(tài) 判斷用戶是否開(kāi)啟藍(lán)牙

? ? ? success: res => {

? ? ? ? console.log('藍(lán)牙狀態(tài)', res)

? ? ? ? //discovering 是否正在搜索設(shè)備? available 藍(lán)牙適配器是否可用

? ? ? ? if (res.available == false) {

? ? ? ? ? wx.showToast({

? ? ? ? ? ? title: '設(shè)備無(wú)法開(kāi)啟藍(lán)牙連接',

? ? ? ? ? ? icon: 'none'

? ? ? ? ? })

? ? ? ? } else if (res.discovering == false){

????????????????//discovering 是否正在搜索設(shè)備?

?????????????????wx.startBluetoothDevicesDiscovery() 調(diào)用搜索外圍設(shè)備

? ? ? ? } else if (res.available){

????????????//available 藍(lán)牙適配器是否可用?

? ? ? ? ? ? ? ?wx.startBluetoothDevicesDiscovery() 調(diào)用搜索外圍設(shè)備

? ? ? ? }

? ? ? }

? ? })


3,開(kāi)始搜尋附近的藍(lán)牙外圍設(shè)備

wx.startBluetoothDevicesDiscovery

開(kāi)始搜尋附近的藍(lán)牙外圍設(shè)備。此操作比較耗費(fèi)系統(tǒng)資源,請(qǐng)?jiān)谒阉鞑⑦B接到設(shè)備后調(diào)用( wx.onBluetoothDeviceFound 后結(jié)束,下一有介紹改api使用)?wx.stopBluetoothDevicesDiscovery?方法停止搜索。

wx.startBluetoothDevicesDiscovery({ //開(kāi)始搜尋附近的藍(lán)牙外圍設(shè)備

? ? services: [this.serviceId], //搜索對(duì)應(yīng)設(shè)備的id? 以微信硬件平臺(tái)的藍(lán)牙智能燈為例,主服務(wù)的 UUID 是 FEE7。傳入這個(gè)參數(shù),只搜索主服務(wù) UUID 為 FEE7 的設(shè)備

? ? allowDuplicatesKey:false, 是否允許重復(fù)上報(bào)同一設(shè)備。如果允許重復(fù)上報(bào),則?wx.onBlueToothDeviceFound?方法會(huì)多次上報(bào)同一設(shè)備,但是 RSSI 值會(huì)有不同。

? ? success:res =>{

? ? ? ? console.log(res);

? ? ? if (!res.isDiscovering) { //是否在搜索到了設(shè)備

? ? ? ? this.getBluetoothAdapterState()

? ? ? }else{

? ? ? ? console.log('1');

? ? ? // this.getSystemInfo()

? ? ? ? this.onBluetoothDeviceFound() //設(shè)備參數(shù)返回成功 就去執(zhí)行搜索設(shè)備 安卓mac 和 ios uuid (作為連接設(shè)備人口參數(shù),安卓得不到mac,ios得不到uuid就無(wú)法連接設(shè)備成功)

? ? ? }

? ? },

? ? fail: err => {

? ? ??

? ? }

? })


4,onBluetoothDeviceFound 獲取設(shè)備的mac和uuid,這里分為兩個(gè)場(chǎng)景,可以通過(guò)wx.getSystemInfo該api來(lái)判斷是不是安卓或者ios,是安卓手機(jī)的話,就獲取設(shè)備mac地址,是ios的手機(jī)的話,就獲取uuid(),這里得注意,uuid,設(shè)備藍(lán)牙無(wú)法識(shí)別,要轉(zhuǎn)化成十六進(jìn)制方法如下:


// ArrayBuffer轉(zhuǎn)16進(jìn)度字符串示例functionab2hex(buffer){consthexArr =Array.prototype.map.call(newUint8Array(buffer),function(bit){return('00'+ bit.toString(16)).slice(-2) } )returnhexArr.join('')}wx.onBluetoothDeviceFound(function(devices){console.log('new device list has founded')console.dir(devices)console.log(ab2hex(devices[0].advertisData))})

wx.onBluetoothDeviceFound((res) => {

const that=this;

? ? res.devices.forEach(device => {

? ? ? console.log(device)????

?????????????that.advertisData(寫(xiě)死的mac地址) 我這里是從后臺(tái)接口獲取的,你們做測(cè)試的話,可以寫(xiě)死

? ? ? if (_advertisData == that.advertisData)

? ? ????????that.advertisData=_advertisData??advertisData 保存在全局變量,因?yàn)樗{(lán)牙連接的時(shí)候需要使用他

? ? ? ? ????wx.setStorageSync('device', device.deviceId)//第一搜索到設(shè)備 保存在本地,給下次連接藍(lán)牙的時(shí)候使用,下次倆連接相同的藍(lán)牙的時(shí)候,就不需要再次去執(zhí)行這個(gè)api-onBluetoothDeviceFound


? ? ? wx. stopBluetoothDevicesDiscovery() // 設(shè)備匹配的化已經(jīng)搜索到,停止搜索

? ? ? ? console.log('設(shè)備已經(jīng)搜索到,停止搜索')

? ? wx.createBLEConnection() 這個(gè)去執(zhí)行連接方法

? ? ? }

? ? })

? })


5,wx.createBLEConnection

連接低功耗藍(lán)牙設(shè)備。

若小程序在之前已有搜索過(guò)某個(gè)藍(lán)牙設(shè)備,并成功建立連接,可直接傳入之前搜索獲取的 deviceId 直接嘗試連接該設(shè)備,無(wú)需進(jìn)行搜索操作。


連接設(shè)備這里,建議大家延遲一下和做遞歸循環(huán)處理,最好是10次左右把,過(guò)快連接和一次連接會(huì)出現(xiàn)連接失敗,安卓手機(jī)概率性特別打,在項(xiàng)目中被坑死了,哈哈,現(xiàn)在已經(jīng)半死不活,跟大家開(kāi)一個(gè)小玩笑,快樂(lè)一下。
setTimeout(() => {

? ? wx.createBLEConnection({

? ? ? deviceId: this.deviceId,

? ? ? success: res => {

? ? ? ? console.log('連接', res)

? ? ? ? if (res.errCode == 0) {

? ? ? ? ?wx.showToast({

? ? ? ? ? ? title: '藍(lán)牙連接設(shè)備成功',

? ? ? ? ? ? icon: 'none'

? ? ? ? ? })

?????? ?連接成功以后就開(kāi)始查詢?cè)O(shè)備的服務(wù)列表:getBLEDeviceServices,然后根據(jù)目標(biāo)服務(wù)ID或者標(biāo)識(shí)符來(lái)找到指定的服務(wù)ID

? ? ? ?getBLEDeviceServices(this.deviceId)

? ? ? ? }

? ? ? },

? ? ? fail: err => {

? ? ? ? self.openlock(count++);

? ? ? ? // console.log('連接失?。?, err)

? ? })

? }, 500)


6,getBLEDeviceServices? 獲取藍(lán)牙設(shè)備所有服務(wù)(service)。

這里有個(gè)坑的地方:如果是安卓下如果你知道設(shè)備的服務(wù)ID,你可以省去getBLEDeviceServices的過(guò)程,但是IOS下即使你知道了服務(wù)ID,也不能省去getBLEDeviceServices的過(guò)程,這是小程序里面需要注意的一點(diǎn)。

? ?

wx.getBLEDeviceServices({

// 這里的 deviceId 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接deviceId, success(res) {


返回的參數(shù)
uuidstring藍(lán)牙設(shè)備服務(wù)的 uuid

isPrimaryboolean該服務(wù)是否為主服務(wù)

console.log('device services:', res.services)?

?}})



7? ,

獲取服務(wù)特征值:每個(gè)服務(wù)都包含了一組特征值用來(lái)描述服務(wù)的一些屬性,比如是否可讀,是否可寫(xiě),是否可以開(kāi)啟notify通知等等,當(dāng)你跟藍(lán)牙通信時(shí)需要這些特征值ID來(lái)傳遞數(shù)據(jù)。

,wx.getBLEDeviceCharacteristics({

// 這里的 deviceId 需要已經(jīng)通過(guò) createBLEConnection 與對(duì)應(yīng)設(shè)備建立鏈接deviceId,

// 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取serviceId,?

?success(res) {console.log('device getBLEDeviceCharacteristics:', res.characteristics) }

})


8,獲取特征值ID以后就可以開(kāi)啟notify通知模式,同時(shí)開(kāi)啟監(jiān)聽(tīng)特征值變化消息

wx.notifyBLECharacteristicValueChange({

? state: true,

? deviceId: device_id,

? serviceId: service_id,

? characteristicId:notify_id,

? complete(res) {

? },

? fail(res){

? ? console.log(res);

? }

})




9.writeBLECharacteristicValue 向小程序?qū)懭硕M(jìn)制數(shù)據(jù)

這里面有個(gè)坑:開(kāi)啟notify以后并不能馬上發(fā)送消息,藍(lán)牙設(shè)備有個(gè)準(zhǔn)備的過(guò)程,需要在setTimeout中延遲1秒以上才能發(fā)送,否則會(huì)發(fā)送失敗

writeBLECharacteristicValue = function (deviceId, serviceId, buffer) {

//deviceIdstring是藍(lán)牙設(shè)備 id

//serviceIdstring是藍(lán)牙特征值對(duì)應(yīng)服務(wù)的 uuid

//characteristicIdstring是藍(lán)牙特征值的 uuid

//valueArrayBuffer是藍(lán)牙設(shè)備特征值對(duì)應(yīng)的二進(jìn)制值

? return new Promise((resolve, reject) => {

? ? wx.writeBLECharacteristicValue({

? ? ? deviceId,//設(shè)備的 id

? ? ? serviceId, //0000FFF0-0000-1000-8000-00805F9B34FB

? ? ? characteristicId: this.characteristicId,//0000FFF6-0000-1000-8000-00805F9B34FB

? ? ? value: buffer,//藍(lán)牙設(shè)備特征值對(duì)應(yīng)的二進(jìn)制值

? ? ? success: res => { resolve(res) },

? ? ? fail: err => { reject(err) }

? ? })

? })

}



10,最后工作完成 斷開(kāi)小程序藍(lán)牙

斷開(kāi)與低功耗藍(lán)牙設(shè)備的連接。

wx.closeBLEConnection({

? deviceId: device_id,

? success(res) {

? ? console.log(res)

? },

? fail(res) {

? ? console.log(res)

? }

})



關(guān)閉藍(lán)牙模塊。調(diào)用該方法將斷開(kāi)所有已建立的連接并釋放系統(tǒng)資源。建議在使用藍(lán)牙流程后,與?wx.openBluetoothAdapter?成對(duì)調(diào)用。

wx.closeBluetoothAdapter({

? success: function (res) {

? ? console.log(res)

? }

})


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容