藍(lán)牙電話apk實(shí)現(xiàn)
只需要兩步:
1.注冊(cè) BluetoothHeadsetClientCall 相關(guān)廣播監(jiān)聽(tīng)來(lái)電/接通/掛斷的狀態(tài),獲取藍(lán)牙電話的相關(guān)信息,比如號(hào)碼、設(shè)備信息等。
code:
BroadcastReceiver broadcastReceiver =newBroadcastReceiver(){
@Override
publicvoidonReceive(Context arg0, Intent intent){
// hide掉了
if(intent.getAction().equals(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED)){// 連接遠(yuǎn)程設(shè)備廣播
// 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)){// 接通狀態(tài)廣播:來(lái)電、去電、掛斷等
Log.e(TAG," action = BluetoothHeadsetClient.ACTION_CALL_CHANGED");
Object state = intent.getExtra(BluetoothHeadsetClient.EXTRA_CALL);// 注:getExtra()返回Object類型
BluetoothHeadsetClientCall ss = (BluetoothHeadsetClientCall)state;// 類型轉(zhuǎn)換
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()));// 獲取來(lái)電/去電/接通/掛斷等狀態(tài)
Log.e(TAG,"ss.mNumber = "+ String.valueOf(ss.getNumber()));// 獲取來(lái)電/去電的電話號(hào)碼
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)){// 音頻流接通或斷開(kāi)廣播
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.通過(guò) BluetoothAdapter 獲取并且初始化 BluetoothHeadsetClient 對(duì)象,然后就可以調(diào)用 api:
dial()/acceptCall()/rejectCall()/terminateCall()方法進(jìn)行撥號(hào)/接通/拒接的操作了
code:
bluetoothAdapter.getProfileProxy(MainActivity.this,newBluetoothProfile.ServiceListener() {
@Override
publicvoidonServiceConnected(intprofile, BluetoothProfile proxy){
// 連接后,拿到藍(lán)牙電話客戶端的代理 mHeadsetClient
// Api 接口: IBluetoothHeadsetClient.aidl
? ? ? ? mHeadsetClient = (BluetoothHeadsetClient) proxy;
? ? }
@Override
publicvoidonServiceDisconnected(intprofile){
? ? }
}, BluetoothProfile.HEADSET);
// 給110打電話
mHeadsetClient.dial(mDevice,"110")
藍(lán)牙電話 Api 相關(guān)源碼分析
路徑1: frameworks\base\core\java\android\bluetooth\
藍(lán)牙相關(guān)接口,藍(lán)牙各種功能的發(fā)起點(diǎn)。
路徑2:packages\apps\Bluetooth\src\com\android\bluetooth\
獨(dú)立的Bluetooth.apk,里面包含藍(lán)牙相關(guān)的各種服務(wù),是java層和C/C++層的橋梁。
路徑3: packages\apps\Bluetooth\jni\
調(diào)用底層C/C++實(shí)現(xiàn)各種藍(lán)牙功能,并且反饋給java層。
藍(lán)牙協(xié)議
.a2dp: 和藍(lán)牙耳機(jī),音頻有關(guān),比如聽(tīng)歌等。
.avrcp: 音頻/視頻通過(guò)連接的藍(lán)牙控制,比如放歌時(shí)控制暫停等。
.gatt:低功耗BLE有關(guān),比如藍(lán)牙按鍵。
.hdp: 藍(lán)牙醫(yī)療有關(guān)
.hfp和hfpclient : 藍(lán)牙通話有關(guān),比如藍(lán)牙通話的相關(guān)操作
.hid: 藍(lán)牙鍵盤(pán)鍵盤(pán)/鼠標(biāo)
.map: 同步藍(lán)牙短信相關(guān)
.opp: 藍(lán)牙傳輸,比如傳輸文件等
.pan: 個(gè)人局域網(wǎng).
.pbap: 同步電話本,比如聯(lián)系人/通話記錄等
.sap : 藍(lán)牙通話,主要和SIM卡相關(guān)
.sdp: 藍(lán)牙服務(wù)發(fā)現(xiàn)/獲取相關(guān)
這12個(gè)包分別實(shí)現(xiàn)了12中藍(lán)牙功能,大多數(shù)以服務(wù)的形式存在,運(yùn)行在 Bluetooth.apk 中。不僅如此,還具有以下特點(diǎn):
1,每一個(gè)服務(wù)相互獨(dú)立,互相毫無(wú)任何影響, 繼承自 ProfileService,由 AdapterService 服務(wù)統(tǒng)一管理。
2,每一個(gè)服務(wù)在路徑1中都存在對(duì)應(yīng)的客戶端類,通過(guò)Binder進(jìn)行跨進(jìn)程通信。
3,每一個(gè)服務(wù)在路徑3中都存在對(duì)應(yīng)的C/C++類,通過(guò)JNI機(jī)制互相調(diào)用。
4,每一個(gè)服務(wù)的啟動(dòng),對(duì)應(yīng)的Binder以及JNI機(jī)制的調(diào)用原理,方法,流程幾乎都是一樣的。