您的位置:首页 > 移动开发 > Android开发

Android电话拦截实现以及TelephonyManager监听的取消

2015-09-18 23:00 483 查看
由于毕业设计题目涉及到电话拦截这一块。所以鼓捣了一下。遇到了一些问题,总结一下,以免忘记,也希望能帮助其他新人们。

本篇博客目的:实现电话的拦截

会遇到的问题: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()    );
}
}
以上就是我的经验和总结,欢迎大家讨论。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: