2020-07-07蓝牙电话apk的实现及源码分析(1)

蓝牙电话apk实现

只需要两步:

1.注册 BluetoothHeadsetClientCall 相关广播监听来电/接通/挂断的状态,获取蓝牙电话的相关信息,比如号码、设备信息等。

code:

BroadcastReceiver broadcastReceiver =newBroadcastReceiver(){

@Override

publicvoidonReceive(Context arg0, Intent intent){

// hide掉了

if(intent.getAction().equals(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED)){// 连接远程设备广播

// 0:disconneted 1:connecting 2:connected 3:disconnecting

intstate = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);

Log.e(TAG,"ACTION_CONNECTION_STATE_CHANGED:: state = "+ String.valueOf(state) +"\n");

}elseif(intent.getAction().equals(BluetoothHeadsetClient.ACTION_CALL_CHANGED)){// 接通状态广播:来电、去电、挂断等

Log.e(TAG," action = BluetoothHeadsetClient.ACTION_CALL_CHANGED");

Object state = intent.getExtra(BluetoothHeadsetClient.EXTRA_CALL);// 注:getExtra()返回Object类型

BluetoothHeadsetClientCall ss = (BluetoothHeadsetClientCall)state;// 类型转换

Log.e(TAG," Object = "+ String.valueOf(state));

Log.e(TAG,"ss.mId = "+ String.valueOf(ss.getId()));

/*state:: CALL_STATE_ACTIVE =0; CALL_STATE_HELD = 1; CALL_STATE_DIALING =2*/

Log.e(TAG,"ss.mState = "+ String.valueOf(ss.getState()));// 获取来电/去电/接通/挂断等状态

Log.e(TAG,"ss.mNumber = "+ String.valueOf(ss.getNumber()));// 获取来电/去电的电话号码

Log.e(TAG," ss.mOutgoing = "+ String.valueOf(ss.isOutgoing()));

Log.e(TAG,"ss.mMultiParty = "+ String.valueOf(ss.isMultiParty()));

}elseif(intent.getAction().equals(BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED)){// 音频流接通或断开广播

Log.e(TAG," action = BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED");

// state: 0:audio disconnected; 1:conneting; 2:connected

intstate = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);

Log.e(TAG,"ACTION_AUDIO_STATE_CHANGED:: state = "+ String.valueOf(state));

        }

    }

};

publicvoidRegister(){

IntentFilter filter =newIntentFilter();

    filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);

    filter.addAction(BluetoothHeadsetClient.ACTION_CALL_CHANGED);

    filter.addAction(BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED);

    registerReceiver(broadcastReceiver, filter);

}


2.通过 BluetoothAdapter 获取并且初始化 BluetoothHeadsetClient 对象,然后就可以调用 api:

dial()/acceptCall()/rejectCall()/terminateCall()方法进行拨号/接通/拒接的操作了

code:

bluetoothAdapter.getProfileProxy(MainActivity.this,newBluetoothProfile.ServiceListener() {

@Override

publicvoidonServiceConnected(intprofile, BluetoothProfile proxy){

// 连接后,拿到蓝牙电话客户端的代理 mHeadsetClient

// Api 接口: IBluetoothHeadsetClient.aidl

        mHeadsetClient = (BluetoothHeadsetClient) proxy;

    }

@Override

publicvoidonServiceDisconnected(intprofile){

    }

}, BluetoothProfile.HEADSET);

// 给110打电话

mHeadsetClient.dial(mDevice,"110")


蓝牙电话 Api 相关源码分析

路径1: frameworks\base\core\java\android\bluetooth\

蓝牙相关接口,蓝牙各种功能的发起点。

路径2:packages\apps\Bluetooth\src\com\android\bluetooth\

独立的Bluetooth.apk,里面包含蓝牙相关的各种服务,是java层和C/C++层的桥梁。

路径3: packages\apps\Bluetooth\jni\

调用底层C/C++实现各种蓝牙功能,并且反馈给java层。


蓝牙协议

.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机制的调用原理,方法,流程几乎都是一样的。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。