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

Android提高21篇之十四:探秘TelephonyManager

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

       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/HTML代码
  1. <uses-permission android:name="android.permission.CALL_PHONE" />  
  2. <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />  

       main.xml源码如下:

XML/HTML代码
  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. }  
本文发布:Android开发网
本文地址:http://www.jizhuomi.com/android/course/480.html
2015年10月15日
发布:鸡啄米 分类:Android开发教程 浏览: 评论:0