#############需求#############
最近我的一位同事大概是利用下面的方法監聽電話的狀態
https://blog.csdn.net/lyen2010/article/details/42590099
相關demo下載鏈接:https://download.csdn.net/download/weiyirong/6872889
本來我是將系統的ITelephony.aidl複製進去,但是編譯會報not fount the import class xx錯誤,於是看了一下上面的demo,對aidl作了簡化:
interface ITelephony { boolean endCall(); void answerRingingCall(); boolean enableDataConnectivity(); boolean disableDataConnectivity(); boolean isDataConnectivityPossible(); }
aidl文件及目錄建好,重新rebuild工程,就會在對應的build目錄下生成對應的java文件
然後我同事說遇到兩個問題
1.電話接通之後,無法掛斷
2.通話狀態無法正常顯示(準確的說是:通話中的狀態不顯示)
我寫了個測試demo
掛斷方法:
public void hangup_call(View view) { Log.e(TAG,"hangup_call START"); ... }
接通電話之後,點擊掛斷按鈕:無響應,日誌也沒有打。
我隱隱約約感覺線程阻塞了,果然接聽加上線程就解決了問題。上面的問題就是接聽電話阻塞了主線程,所以掛斷按鈕點擊不了,廣播也阻塞了。
#############源碼研究#############
撥號源碼詳解:
撥號源碼架構:
https://www.jianshu.com/p/ca4ab4e9817f/ (一個電話應用,實際由多個代碼模塊組成。由dialer下的Android.mk可以看出)
https://blog.csdn.net/wds1181977/article/details/61920067 (介紹各個模塊的作用)
一、撥號
假如我不想調用系統的INTENT來打電話(最直接的方法就是調用ITelephony,文章開頭已經介紹過),那麼就得對系統打電話的INTENT做一番探索了。
通過調用Intent.ACTION_CALL,會打開系統的撥號引用。
向外撥號,發現當前顯示的activity是(通過sdk工具):
InCallActivity.java
現在,我們需求是想自己實現撥號級來電接聽,不走系統UI 。
所以,我的思路是先確定Intent.ACTION_CALL是被誰處理了,怎麼處理的,如何調起InCallActivity,InCallActivity又幹了啥。
InCallActivity被誰打開的
在xref全局搜索,發現InCallPresenter.java這個類
通過官方的解釋,可以知道此類正是管理通話狀態, 開啓InCallActivity。
搜索InCallPresenter 又會被很多類調用,可見此類是集中處理通話狀態的核心類。其中有 InCallServiceImpl,InCallServiceImpl註冊在dialer的清單文件裏: