Android通過BLE傳輸文件遇到問題解決
1、遇到的問題
公司要通過Android設(shè)備給外圍設(shè)備的固件進(jìn)行OTA升級(jí),最開始想到的有兩種方案。
1、將當(dāng)前Android設(shè)備所連接 Wifi名稱,WiFi密碼通過BLE發(fā)送給外圍設(shè)備。 外圍設(shè)備拿到當(dāng)前環(huán)境的WiFi名稱和密碼連接熱點(diǎn), 然后自己去服務(wù)器下載OTA文件,進(jìn)行升級(jí)
2、當(dāng)前Android設(shè)備和外圍設(shè)備通過經(jīng)典藍(lán)牙進(jìn)行傳輸OTA文件, 外圍設(shè)備拿到OTA文件進(jìn)行升級(jí)
但是很遺憾,外圍設(shè)備既沒有WiFi芯片, 也沒有經(jīng)典藍(lán)牙芯片, 只有一顆BLE(低功耗藍(lán)牙)芯片。 這意味著上面的兩種方案都行不通。 那我們能不能通過BLE芯片來做文章, 來傳輸OTA文件?
BLE設(shè)計(jì)之初就是為了傳輸簡(jiǎn)單的指令的, 傳輸一些小數(shù)據(jù)的, 每次發(fā)送的數(shù)據(jù)大小不能超過20個(gè)字節(jié)。到底靠不靠譜啊?
2、 能不能通過BLE傳輸文件
讓我們來問問 GPT 吧
GPT 的回答, 是可以通過BLE傳輸文件的, 由于BLE 每次傳輸?shù)膬?nèi)容最大為20個(gè)字節(jié), 傳輸大文件時(shí)就需要分包傳輸, 同時(shí)需要確保分包傳輸?shù)目煽啃院头€(wěn)定性。
3、 如何傳輸文件
讓 GPT 給我們一些示例代碼
可以看出, 發(fā)送端分包批量發(fā)送數(shù)據(jù),接收端
4、如何保證可靠性和穩(wěn)定性
1、超時(shí)重傳
藍(lán)牙在傳輸過程中, 可能會(huì)存在丟包的情況。分兩種情況, 1、Android設(shè)備發(fā)送的數(shù)據(jù),外設(shè)設(shè)備沒有收到。 2、Android設(shè)備發(fā)送的數(shù)據(jù),外設(shè)設(shè)備收到了,并且發(fā)送了回復(fù)確認(rèn)。 回復(fù)確認(rèn)包Android設(shè)備卻沒有收到。
出現(xiàn)了這兩種情況的任意一種, 則認(rèn)為發(fā)生了丟包的情況。 Android 對(duì)這個(gè)包進(jìn)行重發(fā)。
2、序列號(hào)
針對(duì)超時(shí)重傳的第二種情況, 外設(shè)設(shè)備會(huì)收到兩個(gè)相同的包。 但是外設(shè)設(shè)備不清楚是不是重裝包。 這時(shí)就要給每個(gè)數(shù)據(jù)包添加序列號(hào)。 等外設(shè)設(shè)備收到兩個(gè)相同序列號(hào)的數(shù)據(jù)包時(shí), 丟棄這個(gè)數(shù)據(jù)包, 回復(fù)Android設(shè)備收到此包, 開始發(fā)送下一個(gè)數(shù)據(jù)包。
3、數(shù)據(jù)校驗(yàn)
BLE在傳輸?shù)倪^程中, 如果周圍環(huán)境有強(qiáng)藍(lán)牙干擾,或者其他傳輸通道, 可能會(huì)導(dǎo)致數(shù)據(jù)包變更, 所以需要在數(shù)據(jù)包添加一個(gè)校驗(yàn)位, 這個(gè)校驗(yàn)位根據(jù)特定的算法,由數(shù)據(jù)包的數(shù)據(jù)計(jì)算得來。 外設(shè)設(shè)備收到數(shù)據(jù)后, 重新計(jì)算校驗(yàn)位, 判斷數(shù)據(jù)傳輸過程是否出現(xiàn)差錯(cuò), 如果計(jì)算的校驗(yàn)位和包傳輸?shù)男r?yàn)位不一致, 則要求Android設(shè)備重新發(fā)送這個(gè)包。
5、 傳輸速度提升 RequestMtu
為了保證傳輸過程中的可靠性和穩(wěn)定性,我們需要在傳輸包中,添加序列號(hào),數(shù)據(jù)校驗(yàn)等信息。 Android默認(rèn)每個(gè)BLE數(shù)據(jù)包不超過20個(gè)字節(jié),當(dāng)我們加了一些其他信息時(shí), 每次傳輸?shù)挠行?shù)據(jù)可能只有15個(gè)字節(jié)左右。 導(dǎo)致在傳輸?shù)倪^程中分包更多, 傳輸時(shí)間更長(zhǎng)。
為了提升傳輸?shù)乃俣龋?我們來提升BLE每個(gè)數(shù)據(jù)包的傳輸大小限制, 使每個(gè)分包可以傳輸更多的數(shù)據(jù)。 系統(tǒng)為我們提供了 RequestMtu這個(gè)接口。 需要在gatt連接成功時(shí)調(diào)用
private val bluetoothGattCallback = object : BluetoothGattCallback() { override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) { super.onConnectionStateChange(gatt, status, newState) if (newState == BluetoothGatt.STATE_CONNECTED) { Log.d(TAG, "gatt 連接成功") gatt?.requestMtu(40) } else { Log.d(TAG, "gatt 連接失敗 status $status newstate $newState") } } override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) { super.onMtuChanged(gatt, mtu, status) if (BluetoothGatt.GATT_SUCCESS == status) { Log.d(TAG, "onMtuChanged suc : $mtu") gatt?.discoverServices() } else { Log.d(TAG, "onMtuChanged fail : $status") } } }
MTU改變成功后, 再去gatt.discoverServices()發(fā)現(xiàn)服務(wù)
參考:
http://www.dbjr.com.cn/article/282668.htm
以上就是Android通過BLE傳輸文件遇到問題 解決的詳細(xì)內(nèi)容,更多關(guān)于Android BLE傳輸文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android通過實(shí)現(xiàn)GridView的橫向滾動(dòng)實(shí)現(xiàn)仿京東秒殺效果
這篇文章主要介紹了Android通過實(shí)現(xiàn)GridView的橫向滾動(dòng)實(shí)現(xiàn)仿京東秒殺效果,實(shí)現(xiàn)代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07Android實(shí)現(xiàn)PDF預(yù)覽打印功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)PDF預(yù)覽打印功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12Android無需權(quán)限調(diào)起系統(tǒng)相機(jī)
在進(jìn)行一些小型APP的開發(fā),或者是對(duì)拍照界面沒有自定義要求時(shí),我們可以用調(diào)起系統(tǒng)相機(jī)的方式快速完成拍照需求2023-03-03Android實(shí)現(xiàn)點(diǎn)擊AlertDialog上按鈕時(shí)不關(guān)閉對(duì)話框的方法
這篇文章主要介紹了Android實(shí)現(xiàn)點(diǎn)擊AlertDialog上按鈕時(shí)不關(guān)閉對(duì)話框的方法,涉及設(shè)置監(jiān)聽的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02Android實(shí)現(xiàn)微信加號(hào)菜單模式
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)微信加號(hào)菜單模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08Android中通過AsyncTask類來制作炫酷進(jìn)度條的實(shí)例教程
這篇文章主要介紹了Android中通過AsyncTask來制作炫酷進(jìn)度條的實(shí)例教程,借助AsyncTask類的線程操作方法來管理異步任務(wù),需要的朋友可以參考下2016-05-05