蓝牙电话通话机制原理

本文主要论述基于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机制/反射机制/状态机机制等等。  

相关文章
相关标签/搜索