Android電話攔截實現以及TelephonyManager監聽的取消
本篇博客目的:實現電話的攔截
會遇到的問題:android studio下AIDL的使用,TelephonyManager.Listen()的監聽取消。
首先,電話狀態監聽需要涉及到系統服務TelephonyManager,我們需要獲取到他的實例
mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
之后我們就可以向他添加狀態改變的監聽,需要重寫監聽器PhoneStateListener
他的state值有如下幾種
TelephonyManager.CALL_STATE_IDLE: 空閑狀態
TelephonyManager.CALL_STATE_RINGING: 響鈴狀態
TelephonyManager.CALL_STATE_OFFHOOK: 掛掉電話
class MyPhoneListener extends PhoneStateListener{ @Override public void onCallStateChanged(int state, String incomingNumber) { if(state==TelephonyManager.CALL_STATE_RINGING){ endCall(); super.onCallStateChanged(state,incomingNumber); } } }這里我給他加了個模式來設置監聽與取消。
我們需要用一個FLAG : PhoneStateListener.LISTEN_NONE來取消監聽。如果新加監聽器,會同時監聽
private void setTelephonyListener(int mode){ if(mode==INTERRUPTED){ mTelephonyManager.listen(mMyPhoneListener,PhoneStateListener.LISTEN_CALL_STATE); }else{ mTelephonyManager.listen(mMyPhoneListener,PhoneStateListener.LISTEN_NONE); } }好了,以上就是狀態監聽的步驟。
那么如何實現電話的攔截呢?由于安卓隱藏了PHONE類的API,所以我們需要用AIDL將它的方法反射出來。
1,新建AIDL文件,ITelephony.aidl。注意包名為com.android.internal.telephony,不可更改,此時需要rebuild project才能正常使用。
內容如下:
package com.android.internal.telephony; /** * Interface used to interact with the phone. Mostly this is used by the * TelephonyManager class. A few places are still using this directly. * Please clean them up if possible and use TelephonyManager instead. * {@hide} */ interface ITelephony { /** * End call or go to the Home screen * @return whether it hung up */ boolean endCall(); /** * Answer the currently-ringing call. * * If there's already a current active call, that call will be * automatically put on hold. If both lines are currently in use, the * current active call will be ended. * * TODO: provide a flag to let the caller specify what policy to use * if both lines are in use. (The current behavior is hardwired to * "answer incoming, end ongoing", which is how the CALL button * is specced to behave.) * * TODO: this should be a oneway call (especially since it's called * directly from the key queue thread). */ void answerRingingCall(); /** * Allow mobile data connections. */ boolean enableDataConnectivity(); /** * Disallow mobile data connections. */ boolean disableDataConnectivity(); /** * Report whether data connectivity is possible. */ boolean isDataConnectivityPossible(); }之后來反射出來endcall方法,當來電的時候 即可對電話進行攔截
private void endCall() { Class<TelephonyManager> c = TelephonyManager.class; try { Method getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[]) null); getITelephonyMethod.setAccessible(true); ITelephony iTelephony = null; iTelephony = (ITelephony) getITelephonyMethod.invoke(mTelephonyManager, (Object[]) null); iTelephony.endCall(); Log.i("wing", "iTelePhony endcall"); } catch (Exception e) { Log.i("wing", "iTelePhony endcall failed"+e.getMessage() ); } }以上就是我的經驗和總結,歡迎大家討論。
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!