當前位置:首頁 » 安卓系統 » androidble斷開

androidble斷開

發布時間: 2022-12-25 02:37:26

A. 安卓BLE知識及EasyBle的使用

BLE(Bluetooth low energy)藍牙低功耗是藍牙4.0新增的子規范,其具有低能耗、低成本、低延遲、傳輸距離長等特點,自安卓4.3(api level 18)起,安卓開始支持BLE。BLE與經典藍牙對比如下圖():

在講鏈接參數之前,需要先了解連接事件Connection Events
1)Conection Events(連接事件)
藍牙設備建立連接後,所有信息的交換都是通過Connetion Events進行的,主設備在Connection Events開始起發送數據包,從屬設備在Connection Events期間回復。Connection Events是周期性出現的且時間間隔很短,在一個Connection Events中,器件最大電流為十幾mA,平均電流1uA,這便是BLE功耗較低的原因。Connection Events如下圖()

2)鏈接參數
在兩個藍牙設備建立連接進入連接狀態前,藍牙設備需要設置一系列的鏈接參數,鏈接參數是在中心設備向外圍設備發起連接請求時傳遞的:

當外圍設備認為中心設備請求的鏈接參數不合適時,外圍設備可在連接期間發送一個 Connetion Parameter UpdateRequest 請求中心設備更改鏈接參數。當中心設備收到請求時可接受或拒絕外圍設備的鏈接參數更新請求

GATT層級圖如下(圖片來自 藍牙官網 )

MTU(Maximum Transmission Unit): 即數據的最大傳輸單元。具體是指一個Chracteristic一次性可傳輸的數據大小。
藍牙核心規范(core spec)中定義了ATT的默認MTU為23byte,除去ATT的opcode一個位元組以及ATT的handle2個位元組之後,剩下的20個位元組便是留給GATT的了。由於ATT的最大長度為512byte,故一般認為MTU的最大長度為512個byte。
註:core spec規定每一個設備都必須支持MTU為23。

用系統api開發參見 安卓BLE開發官方文檔
這里介紹使用第三方庫 EasyBle 快速開發BLE

在項目根gradle中添加

在具體mole的gradle中添加

1)判斷設備是否支持BLE並打開藍牙

安卓版本不小於6.0的,掃描必須要有定位許可權,若版本為Android10及以上,則需精確定位許可權(即 Manifest.permission.ACCESS_FINE_LOCATION )

當需要結束掃描時用以下方法結束掃描,建議在掃描到目標設備後停止掃描

當需要斷開與設備的連接時可使用以下任一方法斷開設備連接

notify和indicate都使用以下方法

當需要取消notify或indicate時調用以下方法

如果一次性寫入的數據長度大於MTU即最大傳輸單元(默認是20位元組),則可以使用下列方法進行分批寫入

當結束BLE通信時不要忘了調用destroy


B. 如何使用android原生BLE藍牙進行操作

之前的涉及的物聯網項目中使用的: BLE 低功耗藍牙(藍牙4.0), 支持android 4.3以上的手機
主從關系: BLE低功耗藍牙只能做從端設備 ,一個藍牙主端設備,可同時與7個藍牙從端設備進行通訊

1)低功耗
低功耗的原理:
1低功耗藍牙僅使用了3個廣播通道,傳統藍牙技術採用 16~32 個頻道
2每次廣播開啟時間也由傳統的 22.5ms 減少到 0.6~1.2ms(毫秒)

2)傳輸距離極大提高
傳統藍牙傳輸距離為 2~10m,而藍牙4.0的有效傳輸距離可達到 60~100m

3)安全性
使用AES-128 CCM加密演算法進行數據包加密和認證。
更多BLE藍牙的解析參考博客 : BLE4.0教程一 藍牙協議連接過程與廣播分析

添加許可權
打開藍牙
1.先拿到BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
2.再拿到BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
判斷是否打開藍牙
未打開彈出 系統彈框 ,除了 魅族手機 是打開系統設置

設備/手機都是藍牙信號

在回調方法中:

一般在掃描的過程中,我們還會設置 設備過濾原則 (因為我只想要搜索到我們想要的設備,忽略無關設備)
如:從 scanRecord -- beacon -- beacon.type == 0xFF代表Manufacture,通過與嵌入式軟體定義 自己的 Manufacture值即可

用BluetoothDevice得到BluetoothGatt:

斷連:

關鍵問題:連接後一般要做什麼事?

( 必須在剛連接成功後2秒內app寫一個值給設備,否則會被設備斷開連接)

主要是讀寫 characteristic
gatt.wirteCharacteristic(mCurrentcharacteristic);

gatt.readCharacteristic(characteristic);

bluetoothGatt.setCharacteristicNotification(data, true);

真實工作中使用的藍牙庫BlueToothKit請參考我的另一篇博客:
android藍牙入門知識和優秀藍牙第三方庫BluetoothKit的使用

C. Android BLE藍牙踩坑總結

自從 Android-BLE 庫開源了一段時間以來,越來越多的小夥伴問到了各種各樣的關於BLE的奇怪問題,在這里我想跟大家分享一下本人對於Android BLE藍牙的一些看法和解決方式,避免剛接觸的小夥伴再次踩坑。

很多人曾問過我這個問題,為什麼其他手機都沒什麼問題,就華為的一些手機老是連接不穩定,經常連接的很慢,而且連接上還經常斷開。的確,在這里強調一下華為的一部分手機確實很容易出現這種問題,有時候軟體、硬體都搞不定,而且經常性收到客戶投訴關於華為手機連接穩定性問題,這個的確沒有完全解決的辦法,只能靠App和硬體的優化,並不是想甩鍋給華為,咱也不敢問到底是什麼原因,而且我們公司專門針對各個Android版本的手機做過測試,包括藍牙傳輸速率的測試,最後發現華為P20的速度竟然跟小米8的速度差了好幾倍,按理說P20手機也不便宜啊,為什麼手機藍牙晶元不能做的再好一點呢?

BLE掃描濫用預防

AOSP-BLE掃描濫用說明

息屏狀態下,藍牙掃描日誌,因為掃描周期是12s,所以列印的時間戳間隔是12s,這里的日誌為系統日誌。

https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/include/bt_target.h#1428

stackoverflow問答社區

D. Android BLE藍牙連接異常處理

藍牙通信過程中異常很常見,大致有以下幾種:

1,連接

2,發現服務

3,讀寫

4,通知

連接失敗可能是設備端原因,也可能是手機端原因。不同的手機來自不同的廠家,用的不同的晶元和藍牙協議棧都會導致藍牙功能的表現不一致,這都會導致各式各樣的兼容性問題,可能有的手機連接成功率高,有的成功率低。設備端原因可能有些時候出現異常導致死機無響應,或某些參數設置得有問題。但對於Android應用層開發來說,能做的很有限,藍牙通信是在系統服務進程中處理的,我們無法跨進程改變系統的行為,如果是在一個進程我們還可能通過Hook等手段來調整其內在邏輯。另外應用層的介面只是將請求封裝傳遞給系統服務進程,並未做一些實質性的通信,所以應用層雖然是同一個進程的,但是Hook意義也不大。所以我們能做的僅僅是看怎樣調整介面的調用,使得整體穩定性更好一點而已。

連接失敗分兩種,一種是超時,一種是提前返回失敗。

關於超時,一般是設備不在周圍,或設備斷電未發廣播,或設備當前被其他人連接。系統默認超時為30s,通常返回133,我們也可以自己設置更短的超時時間,超時則closeGatt,然後重新連接。

關於提前返回失敗,一般是有明確的異常,可能是手機藍牙的異常或者設備異常。

這兩種情況建議closeGatt,延時500ms,然後重試。如果重試三次仍然失敗,則可以考慮提示用戶重啟手機藍牙,或者檢查設備是否正常工作。

還有一種情況,連接成功後沒過多久連接又斷開了,這有可能是設備主動斷開,連接成功後有的設備會等待鑒權,如果一定時間內手機端還未發起鑒權則設備端主動斷開。也可能連接信道不夠穩定導致斷開的,此時closeGatt並重新連接即可。

當連接斷開時,會收到onConnectionStateChanged回調,這個回調可能會有一定延時,甚至有5s以上。解決的辦法是輪詢,如每隔1s發起一次讀請求,如果連接斷了會立即返回失敗。

如果藍牙連接不穩定,可以考慮關掉WIFI,因為WIFI通常和藍牙共用一個天線。

有的手機上discoverService可能會回調不止一次onServiceDiscover,這個要注意防禦。

當連接建立後,可以由設備端發起更改連接間隔,這樣能加快後續發現服務以及數據讀寫的速度。有的手機discover service很慢,原因是connect interval太大了,有的手機會主動向設備發起更改connect interval,而有的手機卻不會。這樣的話connect interval相差就會很大,實踐中發現有的手機是7ms,有的手機是默認的50ms,所以發現service都要8s,甚至20s的都很尋常,這對用戶來說是無法忍受的。所以比較好的辦法是設備主動發起更改connect interval,而Android系統是沒有提供對應API的。

如果發現服務失敗,通常來說不用closeGatt,重試一下就好了。如果重試三次還失敗,建議清一下緩存,再closeGatt,重新連接。

讀寫失敗要看失敗的原因是什麼,如果是許可權問題,則需要和設備端確認是否開放了相應的讀寫許可權。也可能是要讀寫的character不存在,可能是設備端修改了固件,手機端需要刷新一下藍牙緩存,closeGatt再重新連接。如果是其它未知錯誤,則重試三次,仍然失敗則closeGatt。不過通常來說如果是因為連接出了問題導致讀寫失敗的,會收到onConnectionStateChanged回調,此時就不用再無謂的重試了,直接closeGatt,重新連接。

打開/關閉character的notify,必須等收到onDescriptorWrite回調之後才算結束,才能開始下一個任務。

如果打開notify失敗,則可以改成周期性輪詢的方式去查詢character的值。

可參考該文章

Android-BLE-Issues

E. flutter_ble Android 設備藍牙BLE 無法斷開重新問題

https://github.com/pauldemarco/flutter_blue/issues/525
connect() method:

disconnect() method

F. android ble為什麼自動斷開連接

可以直接把ble的電源關閉。也可以在手機設置中,打開藍牙,會看到已連接設備,點來,取消連接就可以了。

熱點內容
uc看緩存的視頻 發布:2025-04-06 09:30:32 瀏覽:558
sql判斷是否日期 發布:2025-04-06 09:29:12 瀏覽:312
存儲過程參數空值 發布:2025-04-06 08:59:59 瀏覽:874
垃圾車壓縮式垃圾車 發布:2025-04-06 08:55:00 瀏覽:206
如何給蘋果iphone手機設置密碼 發布:2025-04-06 08:49:17 瀏覽:811
安卓蘋果王者榮耀數據轉移在哪裡 發布:2025-04-06 08:47:34 瀏覽:892
linux強制退出 發布:2025-04-06 08:47:33 瀏覽:665
python驗證碼切割 發布:2025-04-06 08:47:30 瀏覽:990
校園vlog腳本模板 發布:2025-04-06 08:45:59 瀏覽:464
無法訪問別人的共享 發布:2025-04-06 08:41:31 瀏覽:401