`

Android提高第十四篇之探秘TelephonyManager

 
阅读更多

上次介绍了如何使用JAVA的反射机制来调用蓝牙的隐藏API,这次继续练习JAVA的反射机制,探秘TelephonyManager在Framework里包含却在SDK隐藏的几项功能。先来看看本文程序运行的效果图: 

 
本文程序演示了以下功能: 

1.所有来电自动接听; 

2.所有来电自动挂断; 

3.开启/关闭Radio; 

4.开启/关闭数据连接(WAP or NET的连接)。 

调用TelephonyManager的隐藏API是先参考Framework的\base\telephony\java\com\android\internal\telephony\ITelephony.aidl,然后自己实现一个ITelephony.aidl,最后在TelephonyManager中通过反射机制实例化自定义的ITelephony,实例化之后就可以调用ITelephony里面的函数了。 

本文程序需要在AndroidManifest.xml添加以下两行代码,以获得权限: 

Xml代码  收藏代码
  1. <uses-permission android:name="android.permission.CALL_PHONE" />    
  2. <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />    

main.xml源码如下: 
Xml代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>    
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
  3.     android:orientation="vertical" android:layout_width="fill_parent"    
  4.     android:layout_height="fill_parent">    
  5.     <RadioGroup android:layout_height="wrap_content"    
  6.         android:layout_width="fill_parent" android:id="@+id/rGrpSelect">    
  7.         <RadioButton android:layout_height="wrap_content"    
  8.             android:layout_width="fill_parent" android:id="@+id/rbtnAutoAccept"    
  9.             android:text="所有来电自动接听"></RadioButton>    
  10.         <RadioButton android:layout_height="wrap_content"    
  11.             android:layout_width="fill_parent" android:id="@+id/rbtnAutoReject"    
  12.             android:text="所有来电自动挂断"></RadioButton>    
  13.     </RadioGroup>    
  14.     <ToggleButton android:layout_height="wrap_content"    
  15.         android:layout_width="fill_parent" android:id="@+id/tbtnRadioSwitch"    
  16.         android:textOn="Radio已经启动" android:textOff="Radio已经关闭"    
  17.         android:textSize="24dip" android:textStyle="normal"></ToggleButton>    
  18.     <ToggleButton android:layout_height="wrap_content"    
  19.         android:layout_width="fill_parent" android:id="@+id/tbtnDataConn"    
  20.         android:textSize="24dip" android:textStyle="normal" android:textOn="允许数据连接"    
  21.         android:textOff="禁止数据连接"></ToggleButton>    
  22. </LinearLayout>    

PhoneUtils.java是手机功能类,从TelephonyManager中实例化ITelephony并返回,源码如下: 
Java代码  收藏代码
  1. package com.testTelephony;    
  2.     
  3. import java.lang.reflect.Field;    
  4. import java.lang.reflect.Method;    
  5. import com.android.internal.telephony.ITelephony;    
  6. import android.telephony.TelephonyManager;    
  7. import android.util.Log;    
  8.     
  9. public class PhoneUtils {    
  10.     /**  
  11.      * 从TelephonyManager中实例化ITelephony,并返回  
  12.      */    
  13.     static public ITelephony getITelephony(TelephonyManager telMgr) throws Exception {    
  14.         Method getITelephonyMethod = telMgr.getClass().getDeclaredMethod("getITelephony");    
  15.         getITelephonyMethod.setAccessible(true);//私有化函数也能使用    
  16.         return (ITelephony)getITelephonyMethod.invoke(telMgr);    
  17.     }    
  18.         
  19.     static public void printAllInform(Class clsShow) {      
  20.         try {      
  21.             // 取得所有方法      
  22.             Method[] hideMethod = clsShow.getDeclaredMethods();      
  23.             int i = 0     
  24.             for (; i < hideMethod.length; i++) {      
  25.                 Log.e("method name", hideMethod[i].getName());      
  26.             }      
  27.             // 取得所有常量      
  28.             Field[] allFields = clsShow.getFields();      
  29.             for (i = 0; i < allFields.length; i++) {      
  30.                 Log.e("Field name", allFields[i].getName());      
  31.             }      
  32.         } catch (SecurityException e) {      
  33.             // throw new RuntimeException(e.getMessage());      
  34.             e.printStackTrace();      
  35.         } catch (IllegalArgumentException e) {      
  36.             // throw new RuntimeException(e.getMessage());      
  37.             e.printStackTrace();      
  38.         } catch (Exception e) {      
  39.             // TODO Auto-generated catch block      
  40.             e.printStackTrace();      
  41.         }      
  42.     }      
  43. }    

testTelephony.java是主类,使用PhoneStateListener监听通话状态,以及实现上述4种电话控制功能,源码如下: 
Java代码  收藏代码
  1. package com.testTelephony;    
  2.     
  3. import android.app.Activity;    
  4. import android.os.Bundle;    
  5. import android.telephony.PhoneStateListener;    
  6. import android.telephony.TelephonyManager;    
  7. import android.util.Log;    
  8. import android.view.View;    
  9. import android.widget.RadioGroup;    
  10. import android.widget.ToggleButton;    
  11.     
  12. public class testTelephony extends Activity {    
  13.     /** Called when the activity is first created. */    
  14.     RadioGroup rg;//来电操作单选框    
  15.     ToggleButton tbtnRadioSwitch;//Radio开关    
  16.     ToggleButton tbtnDataConn;//数据连接的开关    
  17.     TelephonyManager telMgr;    
  18.     CallStateListener stateListner;    
  19.     int checkedId=0;    
  20.     @Override    
  21.     public void onCreate(Bundle savedInstanceState) {    
  22.         super.onCreate(savedInstanceState);    
  23.         setContentView(R.layout.main);    
  24.             
  25.         telMgr= (TelephonyManager)getSystemService(TELEPHONY_SERVICE);    
  26.         telMgr.listen(new CallStateListener(), CallStateListener.LISTEN_CALL_STATE);    
  27.             
  28.         PhoneUtils.printAllInform(TelephonyManager.class);    
  29.             
  30.         rg = (RadioGroup)findViewById(R.id.rGrpSelect);    
  31.         rg.setOnCheckedChangeListener(new CheckEvent());    
  32.         tbtnRadioSwitch=(ToggleButton)this.findViewById(R.id.tbtnRadioSwitch);    
  33.         tbtnRadioSwitch.setOnClickListener(new ClickEvent());    
  34.         try {    
  35.             tbtnRadioSwitch.setChecked(PhoneUtils.getITelephony(telMgr).isRadioOn());    
  36.         }  catch (Exception e) {    
  37.             Log.e("error",e.getMessage());    
  38.         }    
  39.         tbtnDataConn=(ToggleButton)this.findViewById(R.id.tbtnDataConn);    
  40.         tbtnDataConn.setOnClickListener(new ClickEvent());    
  41.         try {    
  42.             tbtnDataConn.setChecked(PhoneUtils.getITelephony(telMgr).isDataConnectivityPossible());    
  43.         }  catch (Exception e) {    
  44.             Log.e("error",e.getMessage());    
  45.         }    
  46.     }    
  47.         
  48.     /**  
  49.      * 来电时的操作  
  50.      * @author GV  
  51.      *  
  52.      */    
  53.     public class CheckEvent implements RadioGroup.OnCheckedChangeListener{    
  54.     
  55.         @Override    
  56.         public void onCheckedChanged(RadioGroup group, int checkedId) {    
  57.             testTelephony.this.checkedId=checkedId;    
  58.         }    
  59.     }    
  60.         
  61.     /**  
  62.      * Radio和数据连接的开关  
  63.      * @author GV  
  64.      *  
  65.      */    
  66.     public class ClickEvent implements View.OnClickListener{    
  67.     
  68.         @Override    
  69.         public void onClick(View v) {    
  70.             if (v == tbtnRadioSwitch) {    
  71.                 try {    
  72.                     PhoneUtils.getITelephony(telMgr).setRadio(tbtnRadioSwitch.isChecked());    
  73.                 } catch (Exception e) {    
  74.                     Log.e("error", e.getMessage());    
  75.                 }    
  76.             }    
  77.             else if(v==tbtnDataConn){    
  78.                 try {    
  79.                     if(tbtnDataConn.isChecked())    
  80.                         PhoneUtils.getITelephony(telMgr).enableDataConnectivity();    
  81.                     else if(!tbtnDataConn.isChecked())    
  82.                         PhoneUtils.getITelephony(telMgr).disableDataConnectivity();    
  83.                 } catch (Exception e) {    
  84.                     Log.e("error", e.getMessage());    
  85.                 }       
  86.             }    
  87.         }    
  88.     }    
  89.         
  90.     /**  
  91.      * 监视电话状态  
  92.      * @author GV  
  93.      *  
  94.      */    
  95.     public class CallStateListener extends PhoneStateListener {    
  96.         @Override    
  97.         public void onCallStateChanged(int state, String incomingNumber) {    
  98.             if(state==TelephonyManager.CALL_STATE_IDLE)//挂断    
  99.             {    
  100.                 Log.e("IDLE",incomingNumber);    
  101.             }    
  102.             else if(state==TelephonyManager.CALL_STATE_OFFHOOK)//接听    
  103.             {    
  104.                 Log.e("OFFHOOK",incomingNumber);    
  105.             }    
  106.             else if(state==TelephonyManager.CALL_STATE_RINGING)//来电    
  107.             {    
  108.                 if(testTelephony.this.checkedId==R.id.rbtnAutoAccept)    
  109.                 {    
  110.                     try {    
  111.                         //需要<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />     
  112.                         PhoneUtils.getITelephony(telMgr).silenceRinger();//静铃    
  113.                         PhoneUtils.getITelephony(telMgr).answerRingingCall();//自动接听    
  114.                             
  115.                     } catch (Exception e) {    
  116.                         Log.e("error",e.getMessage());    
  117.                     }       
  118.                 }    
  119.                 else if(testTelephony.this.checkedId==R.id.rbtnAutoReject)    
  120.                 {    
  121.                     try {    
  122.                         PhoneUtils.getITelephony(telMgr).endCall();//挂断    
  123.                         PhoneUtils.getITelephony(telMgr).cancelMissedCallsNotification();//取消未接显示    
  124.                     } catch (Exception e) {    
  125.                         Log.e("error",e.getMessage());      
  126.                     }    
  127.                 }    
  128.             }    
  129.             super.onCallStateChanged(state, incomingNumber);    
  130.         }    
  131.     }    
  132. }    
分享到:
评论
1 楼 dagf113225 2012-01-29  
调用TelephonyManager的隐藏API是先参考Framework的\base\telephony\java\com\android\internal\telephony\ITelephony.aidl,然后自己实现一个ITelephony.aidl,最后在TelephonyManager中通过反射机制实例化自定义的ITelephony,实例化之后就可以调用ITelephony里面的函数了。

请指教,这步如何实现,能贴出完整的代码和工程吗?谢谢

相关推荐

Global site tag (gtag.js) - Google Analytics