通过反射的方式挂断电话

思路:

要想挂断电话,必然会用到电话服务:getSystemService(TELEPHONY_SERVICE);

但查看源码时,发现

 

[java] view plaincopy
 
  1. @Override  
  2.    public Object getSystemService(String name) {  
  3.        return mBase.getSystemService(name);  
  4.  }  

 

 

继续查找:

 

[java] view plaincopy
 
  1. Context mBase;  
  2.   public ContextWrapper(Context base) {  
  3.       mBase = base;  
  4.   }  

 

 

 

接着查看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查找,一下就定位到来,往下看几行,一大串类似于下面的代码

 

[java] view plaincopy
 
  1. private AccountManager getAccountManager() {  
  2.        synchronized (mSync) {  
  3.            if (mAccountManager == null) {  
  4.                IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);  
  5.                IAccountManager service = IAccountManager.Stub.asInterface(b);  
  6.                mAccountManager = new AccountManager(this, service);  
  7.            }  
  8.            return mAccountManager;  
  9.        }  
  10.  }  
  11.    

 

 

 

从这就可以推断出,咱要想获取服务,就得使用ServiceManager,那么哦了,回到我们自己的代码中调用: ServiceManager.getService(TELEPHONY_SERVICE);

发现报错,原因是,该类是放在android.os.ServiceManager包中的,对于一些重要的服务,Android工程师是不希望我们自己直接拿到的,不让咱拿咱偏要拿,只好使用暴力了,这时候二话不说,上反射,使用反射得到了getService方法之后,根据上面的代码,照葫芦画瓢,很容易能写出下面的代码:

 

[java] view plaincopy
 
  1. Class ServiceManager = getClass().getClassLoader().loadClass(  
  2.                         "android.os.ServiceManager");  
  3.   
  4. Method getServiceMethod = ServiceManager.getMethod(  
  5.                         "getService"new String[] {String.class});  
  6.   
  7. IBinder ibinder = (IBinder) getServiceMethod.invoke(null,  
  8.                         new String[] { TELEPHONY_SERVICE });  
  9.   
  10. //TELEPHONY 比对 ACCOUNT_SERVICE,也可以去找到ITelephony   
  11. ITelephony itelephony = ITelephony.Stub.asInterface(ibinder);  
  12.                 itelephony.endCall();  

 

 

如果对AIDL不太了解的朋友,可以看看笔者的另一篇博客http://blog.csdn.net/xushuaic/article/details/8559022

 

通过ITelephony.Stub.asInterface 就能看出一定是AIDL的通信,那么必须使用到AIDL协议,而且该协议文件的名称就是ITelephony,那么easySearch Everything,又哦了,新建一个包,将ITelephony.aidl放进去,本以为这样就哦了,谁知道又报错,找到红叉叉,鼠标移上去

 


 

 

 

没问题,Search一把


 

 

找到,Ctrl+CCtrl+V一把,导入包,终于没有红叉叉了,大功告成

注意包的创建,如果你把两个两个文件放错包了,不好意思,eclipse可不客气

 

 

 

正解

 

 

 

又错喽

 

 

 

下面是结束电话的服务,只要在另一个Activity中开启该服务,那么就可以自动地挂断指定的电话了,这里有的朋友一定会发现,这不就是黑名单拦截么,哦了,黑名单拦截就是这样的原理,只要提供一个黑名单的数据库,当来电的时候,到数据库里去查找然后进行判断就可以

 

 

记得权限:

[html] view plaincopy
 
  1. <!-- 监听电话状态 -->  
  2.    <uses-permission android:name="android.permission.READ_PHONE_STATE" />  

 

注册服务 

[html] view plaincopy
 
  1. <service android:name="com.example.service.EndCallService" ></service>  

 

 

结束电话的服务

[java] view plaincopy
 
    1. import java.lang.reflect.InvocationTargetException;  
    2. import java.lang.reflect.Method;  
    3.   
    4. import com.android.internal.telephony.ITelephony;  
    5.   
    6. import android.app.Service;  
    7. import android.content.Intent;  
    8. import android.os.Handler;  
    9. import android.os.IBinder;  
    10. import android.os.RemoteException;  
    11. import android.provider.CallLog;  
    12. import android.telephony.PhoneStateListener;  
    13. import android.telephony.TelephonyManager;  
    14. import android.util.Log;  
    15.   
    16. public class EndCallService extends Service {  
    17.     private static final String TAG = "EndCallService";  
    18.     private TelephonyManager telephonyManager;  
    19.     private MyPhoneListener listener;  
    20.     private Intent callSmsSafeService;  
    21.   
    22.     @Override  
    23.     public IBinder onBind(Intent intent) {  
    24.         return null;  
    25.     }  
    26.   
    27.     @Override  
    28.     public void onCreate() {  
    29.         Log.i(TAG,"启动服务");  
    30.         // 开启电话拦截服务  
    31.         telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);  
    32.         listener = new MyPhoneListener();  
    33.         telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);  
    34.         super.onCreate();  
    35.     }  
    36.   
    37.     @Override  
    38.     public void onDestroy() {  
    39.         // 取消电话监听服务  
    40.         telephonyManager.listen(listener, PhoneStateListener.LISTEN_NONE);  
    41.         listener = null;  
    42.         super.onDestroy();  
    43.     }  
    44.   
    45.     // 自定义电话状态监听  
    46.     class MyPhoneListener extends PhoneStateListener {  
    47.   
    48.         @Override  
    49.             public void onCallStateChanged(int state, String incomingNumber) {  
    50.                 super.onCallStateChanged(state, incomingNumber);  
    51.   
    52.                 switch (state) {  
    53.                 case TelephonyManager.CALL_STATE_RINGING:  
    54.                     Log.i(TAG, "电话到来" + incomingNumber);  
    55.                   
    56.                     if ("10086".equals(incomingNumber)) {// 拦截电话  
    57.                         Log.i(TAG, "挂断电话" + incomingNumber);  
    58.                         endCall();  
    59.                     break;  
    60.                 }  
    61.             }  
    62.         }  
    63.   
    64.         // 挂断电话功能的API隐藏了,无法直接获取服务,通过反射  
    65.         private void endCall() {  
    66.   
    67.             // ServiceManager.getService(TELEPHONY_SERVICE);  
    68.             getSystemService(TELEPHONY_SERVICE);  
    69.             try {  
    70.   
    71. Class ServiceManager = getClass().getClassLoader().loadClass(  
    72.                         "android.os.ServiceManager");  
    73.                 Method getServiceMethod = ServiceManager.getMethod(  
    74.                         "getService", String.class);  
    75.   
    76. IBinder ibinder = (IBinder) getServiceMethod.invoke(null,  
    77.                         new String[] { TELEPHONY_SERVICE });  
    78.   
    79. ITelephony iTelephony = ITelephony.Stub.asInterface(ibinder);  
    80.                 iTelephony.endCall();  
    81.   
    82. Log.i(TAG, "end call-------------");  
    83.             } catch (ClassNotFoundException e) {  
    84.                 e.printStackTrace();  
    85.             } catch (NoSuchMethodException e) {  
    86.                 e.printStackTrace();  
    87.             } catch (IllegalArgumentException e) {  
    88.                 e.printStackTrace();  
    89.             } catch (IllegalAccessException e) {  
    90.                 e.printStackTrace();  
    91.             } catch (InvocationTargetException e) {  
    92.                 e.printStackTrace();  
    93.             } catch (RemoteException e) {  
    94.                 e.printStackTrace();  
    95.             }  
    96.         }  
    97.     }  
    98. }  
posted @ 2013-05-12 19:28  积小流,成江海  阅读(601)  评论(0编辑  收藏  举报