通过反射的方式挂断电话
来源:互联网 发布:文本转语音源码 编辑:程序博客网 时间:2024/05/01 05:52
思路:
要想挂断电话,必然会用到电话服务:getSystemService(TELEPHONY_SERVICE);
但查看源码时,发现
@Override public Object getSystemService(String name) { return mBase.getSystemService(name); }
继续查找:
Context mBase; public ContextWrapper(Context base) { mBase = base; }
接着查看Context的源码
public abstract class Context {........}
崩溃了,经常使用的Context,竟然是个抽象类,那么它的具体实现呢?
这时采用断点的方式进行查找:
随便弄个测试代码,获取到要查找的对象,在下面打个断点
Debug之后
哦了,接着就是去找到ContextImpl类了,这个时候用到了一个搜索神器:search everything,很强大,只要你的电脑里有什么,就可以搜到什么。
本人已经在CSDN上传了该工具,这里是链接,想下的朋友可以去瞅瞅http://download.csdn.net/detail/xushuaic/5346268
右键open path,就可以找到了。
打开ContextImpl,接着又开始犯愁了,该从哪找起呢,两千多行代码,疯了,
既然咱们是要找Service的,只是跟踪的时候跟到了ContextImpl,那么它一定有getSystemService()的方法,Ctrl+F查找,一下就定位到来,往下看几行,一大串类似于下面的代码
private AccountManager getAccountManager() { synchronized (mSync) { if (mAccountManager == null) { IBinder b = ServiceManager.getService(ACCOUNT_SERVICE); IAccountManager service = IAccountManager.Stub.asInterface(b); mAccountManager = new AccountManager(this, service); } return mAccountManager; } }
从这就可以推断出,咱要想获取服务,就得使用ServiceManager,那么哦了,回到我们自己的代码中调用: ServiceManager.getService(TELEPHONY_SERVICE);
发现报错,原因是,该类是放在android.os.ServiceManager包中的,对于一些重要的服务,Android工程师是不希望我们自己直接拿到的,不让咱拿咱偏要拿,只好使用暴力了,这时候二话不说,上反射,使用反射得到了getService方法之后,根据上面的代码,照葫芦画瓢,很容易能写出下面的代码:
Class ServiceManager = getClass().getClassLoader().loadClass("android.os.ServiceManager");Method getServiceMethod = ServiceManager.getMethod("getService", new String[] {String.class});IBinder ibinder = (IBinder) getServiceMethod.invoke(null,new String[] { TELEPHONY_SERVICE });//TELEPHONY 比对 ACCOUNT_SERVICE,也可以去找到ITelephony ITelephony itelephony = ITelephony.Stub.asInterface(ibinder);itelephony.endCall();
如果对AIDL不太了解的朋友,可以看看笔者的另一篇博客http://blog.csdn.net/xushuaic/article/details/8559022
通过ITelephony.Stub.asInterface 就能看出一定是AIDL的通信,那么必须使用到AIDL协议,而且该协议文件的名称就是ITelephony,那么easy,Search Everything,又哦了,新建一个包,将ITelephony.aidl放进去,本以为这样就哦了,谁知道又报错,找到红叉叉,鼠标移上去
没问题,Search一把
找到,Ctrl+C、Ctrl+V一把,导入包,终于没有红叉叉了,大功告成
注意包的创建,如果你把两个两个文件放错包了,不好意思,eclipse可不客气
正解
又错喽
下面是结束电话的服务,只要在另一个Activity中开启该服务,那么就可以自动地挂断指定的电话了,这里有的朋友一定会发现,这不就是黑名单拦截么,哦了,黑名单拦截就是这样的原理,只要提供一个黑名单的数据库,当来电的时候,到数据库里去查找然后进行判断就可以
记得权限:
<!-- 监听电话状态 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
注册服务
<service android:name="com.example.service.EndCallService" ></service>
结束电话的服务
import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import com.android.internal.telephony.ITelephony;import android.app.Service;import android.content.Intent;import android.os.Handler;import android.os.IBinder;import android.os.RemoteException;import android.provider.CallLog;import android.telephony.PhoneStateListener;import android.telephony.TelephonyManager;import android.util.Log;public class EndCallService extends Service {private static final String TAG = "EndCallService";private TelephonyManager telephonyManager;private MyPhoneListener listener;private Intent callSmsSafeService;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {Log.i(TAG,"启动服务");// 开启电话拦截服务telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);listener = new MyPhoneListener();telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);super.onCreate();}@Overridepublic void onDestroy() {// 取消电话监听服务telephonyManager.listen(listener, PhoneStateListener.LISTEN_NONE);listener = null;super.onDestroy();}// 自定义电话状态监听class MyPhoneListener extends PhoneStateListener {@Overridepublic void onCallStateChanged(int state, String incomingNumber) {super.onCallStateChanged(state, incomingNumber);switch (state) {case TelephonyManager.CALL_STATE_RINGING:Log.i(TAG, "电话到来" + incomingNumber);if ("10086".equals(incomingNumber)) {// 拦截电话Log.i(TAG, "挂断电话" + incomingNumber);endCall();break;}}}// 挂断电话功能的API隐藏了,无法直接获取服务,通过反射private void endCall() {// ServiceManager.getService(TELEPHONY_SERVICE);getSystemService(TELEPHONY_SERVICE);try {Class ServiceManager = getClass().getClassLoader().loadClass("android.os.ServiceManager");Method getServiceMethod = ServiceManager.getMethod("getService", String.class);IBinder ibinder = (IBinder) getServiceMethod.invoke(null,new String[] { TELEPHONY_SERVICE });ITelephony iTelephony = ITelephony.Stub.asInterface(ibinder);iTelephony.endCall();Log.i(TAG, "end call-------------");} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (RemoteException e) {e.printStackTrace();}}}}
- 通过反射的方式挂断电话
- Android--通过AIDL+反射,调用android内部隐藏的服务实现挂断电话
- 通过AIDL及反射机制,使用隐藏API挂断电话
- 通过AIDL及反射机制,使用隐藏API挂断电话
- 通过AIDL及反射机制,使用隐藏API挂断电话
- 通过AIDL及反射机制,使用隐藏API挂断电话
- 通过aidl实现挂断电话
- android 自动拨打电话和挂断电话(反射和intent方式)
- android 自动拨打电话和挂断电话(反射和intent方式)
- 67_反射servicemanager挂断电话
- 挂断电话的代码片段
- 关于电话挂断的流程
- android挂断电话的功能
- 通过AIDL实现挂断电话功能
- Android通过程序接听或者挂断电话
- Android通过程序接听或者挂断电话
- 来电拦截、来电挂断,通过反射实现一键挂断
- 挂断电话
- xCode4里面设置NSZombieEnabled
- CURL 入门
- Oil Deposits poj1562 + Counting sheep hdu2952
- OMCS 傲瑞多媒体连接系统
- POJ 3264 Balanced Lineup
- 通过反射的方式挂断电话
- labview 调用labview生成的动态链接库
- JS跨域 JSONP
- SQL Server 2005 在局域网中共享数据库
- java的Timer定时器中获取数据库连接报错
- 深入探讨超越设计模式之外的设计原则
- 教你1分钟学会傻瓜式的GitHub项目托管
- U_boot 的 bootcmd 和bootargs参数详解
- AC自动机算法