下面这个代码实现的功能是进行通话拦截,在写代码的时候了解了下面的知识:
1)JAVA的反射机制。因为安卓隐藏了endcall的方法,所以要想实现拦截电话必须要用到反射机制。关于反射机制详情请看我的前几篇博客。
2)安卓的AIDL和IPC机制。进程间的通信这部分内容非常重要,在broadcastreceiver里面要调用系统的电话服务才能拦截通话。
3)一个重要的知识点:广播接收者只有在相应的进程中才能接受消息。这句话怎么理解呢?也就是说如果你的APP一次都没有启动起来你的广播接收者是没法接收到相应的广播的。下面的类似的事情也会出现在下面的场景上:你的activity有一个图标,但是如果你的APP一次都没起来的话你的图标是没有创立的。因为这个原因我调了很久的BUG,哎悲剧。
下面是代码,没有写界面没有写数据库,这些都和我前面的短信拦截器差不多。代码参考了很多人的,主要参考下面的博客:http://blog.csdn.net/wangfayinn/article/details/8004023
package com.example.mytest;
import java.lang.reflect.Method;
import com.android.internal.telephony.ITelephony;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.widget.Toast;
public class DianHuaLanJie extends BroadcastReceiver {
private TelephonyManager telMgr;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
System.out.println(intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER));
Toast.makeText(context, intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)+"", 0).show();
telMgr = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
switch (telMgr.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING:
String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
if (number.equals("641232")) {
System.out.println("hah");
endCall();
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
case TelephonyManager.CALL_STATE_IDLE:
break;
}
}
/**
* 挂断电话
*/
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(telMgr, (Object[]) null);
iTelephony.endCall();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}