一级女人毛片人一女人-一级女性大黄生活片免费-一级女性全黄久久生活片-一级女性全黄生活片免费-国产美女在线一区二区三区-国产美女在线观看

歡迎光臨~深圳市山星盛電子科技有限公司-稱重產(chǎn)品官方展示網(wǎng)站
服務(wù)熱線 全國(guó)服務(wù)熱線:

0755-2979 1990

新聞資訊

電子磅秤稱重設(shè)備 藍(lán)牙低功率對(duì)接微信小程序之藍(lán)牙 BLE 踩坑記錄

前段時(shí)間接手了一個(gè)微信小程序的開發(fā),主要使用了小程序在今年 3 月開放的藍(lán)牙 API ,此過程踩坑無數(shù),特此記錄一下跳坑過程。順便開了另一個(gè)相關(guān)的小項(xiàng)目,歡迎 start 和 fork: BLE_MiniProgram

API簡(jiǎn)介

微信小程序目前有藍(lán)牙 API 共 18 個(gè),其中操作藍(lán)牙適配器的共有 4 個(gè),分別是

wx.openBluetoothAdapter 初始化藍(lán)牙適配器wx.closeBluetoothAdapter 關(guān)閉藍(lán)牙模塊wx.getBluetoothAdapterState 獲取本機(jī)藍(lán)牙適配器狀態(tài)wx.onBluetoothAdapterStateChange 監(jiān)聽藍(lán)牙適配器狀態(tài)變化事件

連接前使用的共有 4 個(gè),分別是

wx.startBluetoothDevicesDiscovery 開始搜尋附近的藍(lán)牙外圍設(shè)備wx.stopBluetoothDevicesDiscovery 停止搜尋附近的藍(lán)牙外圍設(shè)備wx.getBluetoothDevices 獲取所有已發(fā)現(xiàn)的藍(lán)牙設(shè)備wx.onBluetoothDeviceFound 監(jiān)聽尋找到新設(shè)備的事件

連接和斷開時(shí)使用的共有 2 個(gè),分別是

wx.createBLEConnection 連接低功耗藍(lán)牙設(shè)備wx.closeBLEConnection 斷開與低功耗藍(lán)牙設(shè)備的連接

連接成功后使用的共有 8 個(gè),分別是

wx.getConnectedBluetoothDevices 根據(jù) uuid 獲取處于已連接狀態(tài)的設(shè)備wx.getBLEDeviceServices 獲取藍(lán)牙設(shè)備所有 service(服務(wù))wx.getBLEDeviceCharacteristics  獲取藍(lán)牙設(shè)備所有 characteristic(特征值)wx.readBLECharacteristicValue  讀取低功耗藍(lán)牙設(shè)備的特征值的二進(jìn)制數(shù)據(jù)值wx.writeBLECharacteristicValue 向低功耗藍(lán)牙設(shè)備特征值中寫入二進(jìn)制數(shù)據(jù)wx.notifyBLECharacteristicValueChange  啟用低功耗藍(lán)牙設(shè)備特征值變化時(shí)的 notify 功能wx.onBLECharacteristicValueChange 監(jiān)聽低功耗藍(lán)牙設(shè)備的特征值變化wx.onBLEConnectionStateChange 監(jiān)聽低功耗藍(lán)牙連接的錯(cuò)誤事件

基本操作流程

最基本的操作流程是:初始化藍(lán)牙適配器→開始搜尋附近的藍(lán)牙外圍設(shè)備→監(jiān)聽尋找到新設(shè)備的事件→連接低功耗藍(lán)牙設(shè)備→獲取藍(lán)牙設(shè)備所有 service 和 characteristic →讀取或?qū)懭氲凸乃{(lán)牙設(shè)備的特征值的二進(jìn)制數(shù)據(jù)值。

踩過的幾個(gè)坑

支持藍(lán)牙 API 的版本

Android 從微信 6.5.7 開始支持,iOS 從微信 6.5.6 開始支持,因此小程序中需要做好版本檢測(cè),在 app.js 文件中加入以下代碼,其中 wx.getSystemInfoSync 是一個(gè)獲取系統(tǒng)信息的API。

onLaunch: function() {    this.globalData.sysinfo = wx.getSystemInfoSync()
},getModel: function () { //獲取手機(jī)型號(hào)
    return this.globalData.sysinfo["model"]
},getVersion: function () { //獲取微信版本號(hào)
    return this.globalData.sysinfo["version"]
},getSystem: function () { //獲取操作系統(tǒng)版本
    return this.globalData.sysinfo["system"]
},getPlatform: function () { //獲取客戶端平臺(tái)
    return this.globalData.sysinfo["platform"]
},getSDKVersion: function () { //獲取客戶端基礎(chǔ)庫(kù)版本
    return this.globalData.sysinfo["SDKVersion"]
}

在初始頁面(一般是 index.wxml)對(duì)應(yīng)的 js 文件中使用 app.getPlatform() 和 app.getVersion() 即可獲取到客戶端平臺(tái)(安卓或 iOS)和微信版本號(hào)。在onLoad中獲取這兩個(gè)信息后進(jìn)行比較即可,使用了下面的版本比較方法。

versionCompare: function (ver1, ver2) { //版本比較
    var version1pre = parseFloat(ver1)    var version2pre = parseFloat(ver2)    var version1next = parseInt(ver1.replace(version1pre + ".", ""))    var version2next = parseInt(ver2.replace(version2pre + ".", ""))    if (version1pre > version2pre)        return true
    else if (version1pre < version2pre) 
        return false
    else {        if (version1next > version2next)            return true
        else
            return false
    }
}
if (app.getPlatform() == 'android' && this.versionCompare('6.5.7', app.getVersion())) {    wx.showModal({        title: '提示',        content: '當(dāng)前微信版本過低,請(qǐng)更新至最新版本',        showCancel: false
    })
}
else if (app.getPlatform() == 'ios' && this.versionCompare('6.5.6', app.getVersion())) {    wx.showModal({        title: '提示',        content: '當(dāng)前微信版本過低,請(qǐng)更新至最新版本',        showCancel: false
    })
}

安卓 6.0 及以上設(shè)備需打開定位服務(wù)

在測(cè)試中發(fā)現(xiàn)安卓 6.0 以上的手機(jī)未打開系統(tǒng)定位服務(wù)時(shí),搜索不到藍(lán)牙設(shè)備,因此最好在頁面中提示用戶打開定位服務(wù)。

wx.onBluetoothDeviceFound 不兼容

安卓及iOS設(shè)備使用 wx.onBluetoothDeviceFound 時(shí)會(huì)出現(xiàn)不同的返回值,且有概率出現(xiàn)重復(fù)設(shè)備,所以使用以下代碼可以清除重復(fù)的設(shè)備和解決 API 不兼容問題。

wx.onBluetoothDeviceFound(function (devices) {    var isnotExist = true
    if (devices.deviceId) {        for (var i = 0; i < foundDevice.length; i ++) {            if (devices.deviceId == foundDevice[i].deviceId) {
                isnotExist = false
            }
        }        if (isnotexist)
            foundDevice.push(devices)
    }    else if (devices.devices) {        for (var i = 0; i < foundDevice.length; i++) {            if (devices.devices[0].deviceId == foundDevice[i].deviceId) {
                isnotExist = false
            }
        }        if (isnotexist)
            foundDevice.push(devices.devices[0])
    }    else if (devices[0]) {        for (var i = 0; i < foundDevice.length; i++) {            if (devices[0].deviceId == foundDevice[i].deviceId) {
                isnotExist = false
            }
        }        if (isnotexist)
            foundDevice.push(devices[0])
    }
})

讀取廣播數(shù)據(jù)和特征值

小程序中讀取 BLE 廣播數(shù)據(jù)使用 wx.onBluetoothDeviceFound 接口中的 advertisData,對(duì)應(yīng)上面兼容問題的 devices 格式,如 devices.advertisData,這個(gè)數(shù)據(jù)是 ArrayBuffer,需要轉(zhuǎn)換,可以使用以下兩種轉(zhuǎn)換方法。另外 wx.getBLEDeviceCharacteristics 讀取的特征值 characteristic.value 也是 ArrayBuffer,用同樣的方法轉(zhuǎn)換。

buf2string: function (buffer) {    var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x)    var str = ''
    for (var i = 0; i < arr.length; i++) {
      str += String.fromCharCode(arr[i])
    }    return str
}
buf2hex: function (buffer) {    return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}

發(fā)送大于 20 字節(jié)的數(shù)據(jù)包

眾所周知,BLE 4.0 中發(fā)送一個(gè)數(shù)據(jù)包只能包含 20 字節(jié)的數(shù)據(jù),大于 20 字節(jié)只能分包發(fā)送。微信小程序提供的 API 中似乎沒有自動(dòng)分包的功能,這就只能自己手動(dòng)分包了。調(diào)試中發(fā)現(xiàn),在 iOS 系統(tǒng)中調(diào)用 wx.writeBLECharacteristicValue 發(fā)送數(shù)據(jù)包,回調(diào) success 后緊接著發(fā)送下一個(gè)數(shù)據(jù)包,很少出現(xiàn)問題,可以很快全部發(fā)送完畢。而安卓系統(tǒng)中,發(fā)送一個(gè)數(shù)據(jù)包成功后緊接著發(fā)送下一個(gè),很大概率會(huì)出現(xiàn)發(fā)送失敗的情況,在中間稍做延時(shí)再發(fā)送下一個(gè)就可以解決這個(gè)問題(不同安卓手機(jī)的時(shí)間長(zhǎng)短也不一致),照顧下一些比較奇葩的手機(jī),大概需要延時(shí) 250 ms 。不太好的但是比較科學(xué)的辦法是,只要成功發(fā)送一個(gè)數(shù)據(jù)包則發(fā)送下一個(gè),否則不斷重發(fā),具體就是
wx.writeBLECharacteristicValue 回調(diào) fail 則重新發(fā)送,直至發(fā)送完畢。

補(bǔ)充說明

此處補(bǔ)充說明一下,華為榮耀部分機(jī)型、還有藍(lán)綠廠的部分機(jī)型,在藍(lán)牙 API 有深坑,謹(jǐn)慎調(diào)試。另:發(fā)現(xiàn)挺多同學(xué)沒有注意到官方文檔最下方的錯(cuò)誤碼列表,順便在此處貼出來。

藍(lán)牙錯(cuò)誤碼 (errCode) 列表

錯(cuò)誤碼說明備注
0ok正常
10000not init未初始化藍(lán)牙適配器
10001not available當(dāng)前藍(lán)牙適配器不可用
10002no device沒有找到指定設(shè)備
10003connection fail連接失敗
10004no service沒有找到指定服務(wù)
10005no characteristic沒有找到指定特征值
10006no connection當(dāng)前連接已斷開
10007property not support當(dāng)前特征值不支持此操作
10008system error其余所有系統(tǒng)上報(bào)的異常
10009system not supportAndroid 系統(tǒng)特有,系統(tǒng)版本低于 4.3 不支持BLE


用手機(jī)掃描二維碼關(guān)閉
二維碼