藍牙電話通話機制原理

本文主要論述基於android 6.0的藍牙上層(Java層)通話機制;總結了藍牙通話框架,而且給出了接聽電話的詳細的流程圖;最後說明了apk的實現以及總結了藍牙/android 相關的知識點。java

1, 藍牙框架
主要代碼路徑:android

路徑1: frameworks\base\core\java\android\bluetooth\  api

藍牙相關接口,藍牙各類功能的發起點。app

路徑2:packages\apps\Bluetooth\src\com\android\bluetooth\  框架

獨立的Bluetooth.apk,裏面包含藍牙相關的各類服務,是java層和C/C++層的橋樑。設計

路徑3: packages\apps\Bluetooth\jni\代理

  調用底層C/C++實現各類藍牙功能,而且反饋給java層。視頻

在路徑2裏面還有各類相互獨立的java代碼包,每個包都包含一個協議,實現一個具體的功能:對象

btservice: 統一管理,控制其餘服務。blog

a2dp: 和藍牙耳機,音頻有關,好比聽歌等。

avrcp: 音頻/視頻經過鏈接的藍牙控制,好比放歌時控制暫停等。

gatt:低功耗BLE有關,好比藍牙按鍵。

hdp: 藍牙醫療有關

hfp和hfpclient : 藍牙通話有關,好比藍牙通話的相關操做

hid: 藍牙鍵盤鍵盤/鼠標

map: 同步藍牙短信相關

opp: 藍牙傳輸,好比傳輸文件等

pan: 我的局域網

pbap: 同步電話本,好比聯繫人/通話記錄等

sap : 藍牙通話,主要和SIM卡相關

sdp: 藍牙服務發現/獲取相關

 

這12個包分別實現了12中藍牙功能,大多數以服務的形式存在,運行在Bluetooth.apk中。不只如此,還具備如下特色:

1,每個服務相互獨立,互相毫無任何影響, 繼承自 ProfileService,由

AdapterService服務統一管理。

2,每個服務在路徑1中都存在對應的客戶端類,經過Binder進行跨進程通訊。

3,每個服務在路徑3中都存在對應的C/C++類,經過JNI機制互相調用。

4,每個服務的啓動,對應的Binder以及JNI機制的調用原理,方法,流程幾乎都是同樣的。

下面以藍牙通話功能爲例來解析相關接口以及代碼實現框架圖。

 

 

2 藍牙通話框架
2.1 相關類的說明
藍牙通話上層代碼主要分爲3個部分:

1,藍牙api相關代碼, 路徑4: frameworks\base\core\java\android\bluetooth\

主要有2個類

 

BluetoothHeadsetClient.java主要負責藍牙通話的相關動做,好比接聽等等

BluetoothHeadsetClientCall.java主要負責藍牙通話的狀態,好比是來電仍是去電等等。

 

2,藍牙服務端的相關代碼,路徑5:

packages\apps\Bluetooth\src\com\android\bluetooth\hfpclient\

有3個類

 

HeadsetClientHalConstants.java類裏面只是定義了一些int/boolean 類型的值。

HeadsetClientService.java從名字就知道它是一個服務,它的設計頗有意思,裏面還有一個BluetoothHeadsetClientBinder內部類,該內部類主要負責和

BluetoothHeadsetClient進行跨進程通訊。另外,HeadsetClientService也是

BluetoothHeadsetClientBinder和HeadsetClientStateMachine之間的橋樑。

HeadsetClientStateMachine是一個狀態機,即管理鏈接的狀態也是通話時java和C/C++之間的橋樑,經過JNI機制和com_android_bluetooth_hfpclient 裏面的方法互相調用。

 

3,JNI相關代碼,路徑6: packages\apps\Bluetooth\jni\

有1個文件: 

 

com_android_bluetooth_hfpclient  藍牙通話動做,撥號/接聽/掛斷/拒接 實際的執行者。

 

DialerBTHfpService服務是開機以後啓動的。

 

 

 

2.2類圖

圖一 類圖
BluetoothHeadsetClient是一個api,由第三方apk直接調用,能夠進行撥號/接聽/拒接/掛斷操做,對應的方法依次爲dial()/acceptCall()/rejectCall()/terminateCall().

 

HeadsetClientService是一個服務, BluetoothHeadsetClientBinder是它的內部類, BluetoothHeadsetClientBinder是BluetoothHeadsetClient在HeadsetClientService中的代理,經過aidl進行方法的調用。

 

Connected(已鏈接狀態)是HeadsetClientStateMachine 的其中一種狀態,通話的相關操做都創建在已鏈接狀態之上,其它三種狀態爲Disconnected, Connecting,

AudioOn狀態。HeadsetClientService 根據不一樣的方法給狀態機發送不一樣的消息,最後經過HeadsetClientStateMachine根據JNI機制調用

com_android_bluetooth_hfpclient.cpp對應的方法,最後調用底層C/C++ 來真正的實現撥號/接聽/拒接/掛斷操做。

 

撥號/接聽/拒接/掛斷方法調用的流程徹底是如出一轍的,下小節給出接聽方法具體調用的完整流程圖。

 

 

 

2.3流程圖

圖二 接聽電話流程圖
除了dial 方法最後調用從C/C++ dialNative以外,其它的3個方法最後都是調用handleCallActionNative,只是參數不一樣而已。

撥號/接聽/拒接/掛斷都是主動完成的,那麼若是有來電,對方接通電話或者對方掛斷電話,咱們怎麼知道呢?這些都是com_android_bluetooth_hfpclient.cpp經過JNI機制調用通話狀態機的方法sendCallChangedIntent,將電話的狀態(包含在

BluetoothHeadsetClientCall.java中)經過廣播發送出來,第三方apk監聽狀態就能夠進行相應的操做了。具體的來電流程圖以下:

圖三 來電流程圖

3 藍牙通話apk說明
在本身的apk中,只須要作2件事情就能夠完成藍牙通話的幾乎全部動做,

1,根據上一小節的論述,註冊BluetoothHeadsetClientCall相關廣播,監聽來電/接通/對方掛斷的狀態,獲取藍牙電話的相關信息,好比號碼,設備信息等等。

好比,若是收到來電廣播,就能夠根據BluetoothHeadsetClientCall獲取來電的號碼等信息,而後顯示來電界面。

2,經過BluetoothAdapter 獲取而且初始化BluetoothHeadsetClient對象,而後就能夠直接調用dial()/acceptCall()/rejectCall()/terminateCall() 方法進行撥號/接聽/拒接/掛斷的操做了。

 

4, 小節
利用api實現藍牙通話不是很難,可是若是弄清楚具體的藍牙通話機制以及細節甚至藍牙相關功能,這就得下功夫了,關於藍牙,還能夠進一步研究的android知識點以及藍牙涉及的上層java要點以下:

1,基本藍牙功能:打開/關閉/掃描/配對/鏈接

2,藍牙功能:經過藍牙傳輸文件/藍牙鍵盤/藍牙醫療服務/藍牙同步聯繫人等等

3,android知識:跨進程通訊機制/JNI機制/反射機制/狀態機機制等等。  

相關文章
相關標籤/搜索