Android - 电话拦截
2016-02-15 18:02
429 查看
拦截电话
这里,我们要实现黑名单中电话拦截的功能,为了侦听电话状态,我们需要获得系统的电话管理器等
这是我们自定义的一个电话状态监听
了挂断电话的服务方法,因此要实现挂断电话的操作只能通过反射获取底层服务。
然后通过该字节码获取 getService()方法,该方法接收一个 String 类型的参数,然后通过 invoke()执行
getService()方法,由于 getService()方法是静态的,因此 invoke()的第一个参数可以为 null,第二个参数是
TELEPHONY_SERVICE。由于 getService()方法的返回值是一个 IBinder 对象(远程服务的代理类),因此
需要使用 AIDL 的规则将其转化为接口类型,由于我们的操作是挂断电话,因此需要使用与电话相关的
ITelephony.aidl,然后调用接口中的 endCall()方法将电话挂断即可。
需要注意的是,与电话相关的操作一般都使用 TelephonyManager 类,但是由于挂断电话的方法在
ITelephony 接口中,而这个接口是隐藏的(@hide)在开发时看不到,因此需要使用 ITelephony.aidl。在使
用 ITelephony.aidl 时,需要创建一个与它包名一致的包 com.android.internal.telephony 然后把系统的
ITelephony.aidl 文件拷贝进来,同时 ITelephony.aidl 接口关联了 NeighboringCellInfo.aidl,所以也需要一并
拷贝进来。不过要注意的是,NeighboringCellInfo.aidl 所在的的包名是 android.telephony,因此需要新建一
个 android.telephony 包,然后把 NeighboringCellInfo.aidl 放到包该包中。
这里,我们要实现黑名单中电话拦截的功能,为了侦听电话状态,我们需要获得系统的电话管理器等
// 获取到电话管理者 mTelephonyManager = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE); // 初始化电话状态监听 listener = new MyPhoneStateListener(); // 设置电话监听 // 第一个参数:表示电话状态的监听 // 第二个参数:表示打电话的状态 mTelephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
这是我们自定义的一个电话状态监听
private class MyListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_RINGING:// 响铃状态。 String result = dao.findmode(incomingNumber); if ("1".equals(result) || "3".equals(result)) { Log.i(TAG, "挂断电话。。。。"); endCall(); } break; } super.onCallStateChanged(state, incomingNumber); } }当电话铃响时需要挂断电话并且不让该记录显示在界面上,而 Google 工程师为了手机的安全性隐藏
了挂断电话的服务方法,因此要实现挂断电话的操作只能通过反射获取底层服务。
public void endCall() { // IBinder iBinder = ServiceManager.getService(TELEPHONY_SERVICE); try { // 加载servicemanager的字节码 Class clazz = CallBlackSmsService.class.getClassLoader().loadClass( "android.os.ServiceManager"); Method method = clazz.getDeclaredMethod("getService", String.class); IBinder ibinder = (IBinder) method.invoke(null, TELEPHONY_SERVICE); ITelephony.Stub.asInterface(ibinder).endCall(); } catch (Exception e) { e.printStackTrace(); } }endCall()方法用于挂断黑名单的呼入电话,该段代码中首先通过反射获取到 ServiceManager 字节码,
然后通过该字节码获取 getService()方法,该方法接收一个 String 类型的参数,然后通过 invoke()执行
getService()方法,由于 getService()方法是静态的,因此 invoke()的第一个参数可以为 null,第二个参数是
TELEPHONY_SERVICE。由于 getService()方法的返回值是一个 IBinder 对象(远程服务的代理类),因此
需要使用 AIDL 的规则将其转化为接口类型,由于我们的操作是挂断电话,因此需要使用与电话相关的
ITelephony.aidl,然后调用接口中的 endCall()方法将电话挂断即可。
需要注意的是,与电话相关的操作一般都使用 TelephonyManager 类,但是由于挂断电话的方法在
ITelephony 接口中,而这个接口是隐藏的(@hide)在开发时看不到,因此需要使用 ITelephony.aidl。在使
用 ITelephony.aidl 时,需要创建一个与它包名一致的包 com.android.internal.telephony 然后把系统的
ITelephony.aidl 文件拷贝进来,同时 ITelephony.aidl 接口关联了 NeighboringCellInfo.aidl,所以也需要一并
拷贝进来。不过要注意的是,NeighboringCellInfo.aidl 所在的的包名是 android.telephony,因此需要新建一
个 android.telephony 包,然后把 NeighboringCellInfo.aidl 放到包该包中。
相关文章推荐
- 简介Android应用中sharedPreferences类存储数据的用法
- Android传感器及使用方法
- Android蓝牙应用开发
- android 实现有阻尼下拉/上拉刷新列表
- android.support.design
- 我在Mac OS X 操作系统上搭建Android开发环境的经历
- android 自定义View Caused by: java.lang.ClassNotFoundException: Didn't find class
- 手机高温警告提示内容不匹配的分析【多次调用PendingIntent.getBroadcast,intent数据不更新】
- android ImageView布局时出现警告的解决
- 解决android.view.AbsSavedState$1 cannot be cast to android.widget.CompoundButton$SavedState
- Android数据存储(一)----SharedPreferences详解
- Android(监听+回调=观察者)模式从Dialog到Activity传递数据
- Android 驱动USB摄像头
- git 发布android 系统版本 修改版本型号 查看指定文件的修改记录
- 最全Android开发常用工具类
- 性能优化之Java(Android)代码优化
- 监听ScrollView滑到底部
- android 多进程之 Messenger
- Android RxJava学习
- Android图片的三级缓存和AsyncTask的使用的研究学习