藍牙連接是使用藍牙的基礎,那藍牙斷開可能就不完全是我們能夠控制的。也就是說藍牙鏈路的斷開可能因爲各種各樣的原因,那本篇就帶大家詳解藍牙斷開的原因。
藍牙鏈路也就是藍牙專業人士說的ACL鏈路,所有的藍牙操作都是在此基礎上進行的,一旦ACL斷開,那藍牙功能必定無法使用。但藍牙斷開的原因很多,具體是啥原因?我們從何獲取?帶着這些疑問我們開始吧。
BluetoothDevice類中定義了ACL斷開的廣播爲:
/**
* Broadcast Action: Indicates a low level (ACL) disconnection from a
* remote device.
* <p>Always contains the extra field {@link #EXTRA_DEVICE}.
* <p>ACL connections are managed automatically by the Android Bluetooth
* stack.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ACL_DISCONNECTED =
"android.bluetooth.device.action.ACL_DISCONNECTED";
廣播裏的內容包含了遠端設備BluetoothDevice,無法知道ACL斷開的具體原因,那就讓我們從底層到上層梳理下ACL斷開完成事件上報流程中是否有reason這個參數。
查看藍牙協議Core_v5.0.pdf裏Vol 2, Part E中的7.7.5的HCI事件Disconnection Complete Event:
協議裏詳細規定了上報ACL斷開完成事件時是必須帶有斷開原因的參數,所有我們跟着ACL斷開完成事件的上報流程來追蹤reason參數存儲在何處,下圖爲詳細的上報時序圖:
ACL斷開完成事件的處理在bluedroid中有將reason保存,但最後回調上報JNI時卻沒帶上該參數,導致藍牙服務層沒法知道斷開原因。
到這裏我們大致清楚ACL斷開的reason還被保存在bluedroid中,沒有上報給服務層,只需在合適的地方將該參數通過回調的方式上報給藍牙服務即可。藍牙服務廣播ACL斷開時添加reason參數就可被應用獲取到斷開原因,應用根據不同的斷開原因採取不同的操作來完善藍牙功能。
更多互聯互通技術,歡迎關注微信公衆號:Connectivity