项目中需要在接收到来电之后把电话挂断,再做一些事情,在研究了Android源码以及参考了网络资料之后得出了如下方法:
1、定义并注册广播:
public void onReceive(final Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
//去电,可以用定时挂断
} else {
//来电
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)) {
Log.d(TAG, "--------coming call , end call!!!");
endCall(context);
}
}
}
注册广播:
<receiver
android:name="com.jerome.util.TelInternal"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
增加权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
完成如上操作就可以监听来电和去电了,很简单的。
2、挂断电话:
在研究了电话源码之后发现要挂断电话,需要调用ITelephony的endCall方法,可是ITelephony是拿到不的,怎么办呢?首先想到的是反射,网上的参考资料也是用反射,
先来看网上的方法:
private static ITelephony getITelephony(Context context) {
ITelephony iTelephony = null;
TelephonyManager mTelephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
Class<TelephonyManager> c = TelephonyManager.class;
Method getITelephonyMethod = null;
Method[] m = c.getMethods();
for (int i = 0; i < m.length; i++) {
Log.i("jerome", "" + m[i].getName() + "____"
+ m[i].getReturnType().getName());
}
try {
//这种方法没有测试成功,直接将源码拷贝过来了;
getITelephonyMethod =c.getDeclaredMethod("getITelephony",(Class[])null); // 获取声明的方法
getITelephonyMethod.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
}
return iTelephony;
}
可是我在Android4.2版本上没有编译成功,就是用反射拿不到拿不到getITelephony方法,进源码看一下getITelephony():
private ITelephony getITelephony() {
return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
}
里面就一句话,好吧,那句直接把这句话拷贝过来,看能不能调用,但结果是不行,因为ServiceManager你是无法拿到的。好吧,上绝招,见图:
没错,就是引入ServiceManager类。
实现如下:
private ITelephony getITelephony(Context context) {
ITelephony iTelephony = null;
try {
iTelephony = ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
} catch (Exception e) {
e.printStackTrace();
}
return iTelephony;
}
这样就可以拿到ITelephony对象了。注意我是引入了ITelephony.aidl和NeighboringCellInfo.aidl。
private void endCall(Context context) {
AudioManager mAudioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
// 先静音处理
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
try {
ITelephony iTelephony = getITelephony(context);
if (null != iTelephony) {
iTelephony.endCall(); // 挂断电话
}
} catch (Exception e) {
e.printStackTrace();
}
// 再恢复正常铃声
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
好了,这样就可以拦截并挂断电话了,再根据你记录的黑名单,就可以实现指定电话拦截功能了。祝你好运~!
有什么问题可以留言给我。
- 大小: 9.6 KB
分享到:
相关推荐
android中有很多隐藏接口,即手机中有而SDK中没有开放的接口,这些接口可以通过反射获取并使用。本文主要介绍ITelephony的获取方法,附代码。
Android黑名单拦截核心代码实现,这是实现必须的两个接口文件。博客链接:
Android拒绝来电的实现Android拒绝来电的实现Android拒绝来电的实现Android拒绝来电的实现Android拒绝来电的实现Android拒绝来电的实现Android拒绝来电的实现Android拒绝来电的实现
Android挂断电话
在android手机上实现自动接听电话,2.3以下依靠的是对ITelephony的反射调用来实现,2.3-4.0是通过对耳机的模拟操作来实现,4.1以上有了一些变动,在这个demo中我没有对2.3进行处理,请朋友们自己去搜下2.3的处理方式
NeighboringCellInfo.aidl ITelephony.aidl压缩包,
挂电话需要用到系统的ITelephony类,但是Google从Android2.1 SDK版本后,屏蔽了ITelephony类,在此附上2.2版本 ITelephony.aidl文件
ITelephony和NeighboringCellInfo这两个文件是android源码文件,在实现接听电话时需要拷贝这两个文件到aidl目录下,代码实现可以看我的博客
ITelephony.aidl和NeighboringCellInfo.aidl
ITelephony.aidl NeighboringCellInfo.aidl
实现了根据黑白名单及不同的策略对来电进行拦截,符合拦截条件的可以直接挂断
安卓开发黑名单时必须的两个aidl文件 最重要的ITelephony 类
电话号码拦截功能时需要用到endCall(),需要使用该文件 注意:此文件需要放到包com.android.internal.telephony下,同时还需将NeighboringCellInfo.aidl文件放到android.telephony包下
学习传智播客的手机安全卫士用到的aidl文件 包含 ITelephony.aidl NeighboringCellInfo.aidl两个文件
完整的功能 能自动接听和挂断电话 里面包含必备的NeighboringCellInfo.aidl文件和ITelephony.aidl文件 兼容4.1以上系统 欢迎交流
Android呼叫拦截器 步骤1: 在Android Studio中创建一个新项目 第2步: 创建一个AIDL文件夹 ... 现在是时候阻止所有来电 创建一个BroadcastReceiver class 将该代码添加到类中 package jovial.callbloc