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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!