Android提高第十四篇之探秘TelephonyManager

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添加以下两行代码,以获得权限:

  1. <uses-permission android:name="android.permission.CALL_PHONE" />  
  2. <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
复制代码

main.xml源码如下:


  1. <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" 
  2.         android:orientation="vertical" android:layout_width="fill_parent"
  3.         android:layout_height="fill_parent">
  4.         <radiogroup android:layout_height="wrap_content" 
  5.                 android:layout_width="fill_parent" android:id="@+id/rGrpSelect">
  6.                 <radiobutton android:layout_height="wrap_content" 
  7.                         android:layout_width="fill_parent" android:id="@+id/rbtnAutoAccept"
  8.                         android:text="所有来电自动接听">
  9.                 <radiobutton android:layout_height="wrap_content" 
  10.                         android:layout_width="fill_parent" android:id="@+id/rbtnAutoReject"
  11.                         android:text="所有来电自动挂断">
  12.         
  13.         <togglebutton android:layout_height="wrap_content" 
  14.                 android:layout_width="fill_parent" android:id="@+id/tbtnRadioSwitch"
  15.                 android:textOn="Radio已经启动" android:textOff="Radio已经关闭"
  16.                 android:textSize="24dip" android:textStyle="normal">
  17.         <togglebutton android:layout_height="wrap_content" 
  18.                 android:layout_width="fill_parent" android:id="@+id/tbtnDataConn"
  19.                 android:textSize="24dip" android:textStyle="normal" android:textOn="允许数据连接"
  20.                 android:textOff="禁止数据连接">

复制代码
PhoneUtils.java是手机功能类,从TelephonyManager中实例化ITelephony并返回,源码如下:

  1. package com.testTelephony;

  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. import com.android.internal.telephony.ITelephony;
  5. import android.telephony.TelephonyManager;
  6. import android.util.Log;

  7. public class PhoneUtils {
  8.         /**
  9.          * 从TelephonyManager中实例化ITelephony,并返回
  10.          */
  11.         static public ITelephony getITelephony(TelephonyManager telMgr) throws Exception {
  12.                 Method getITelephonyMethod = telMgr.getClass().getDeclaredMethod("getITelephony");
  13.                 getITelephonyMethod.setAccessible(true);//私有化函数也能使用
  14.                 return (ITelephony)getITelephonyMethod.invoke(telMgr);
  15.         }
  16.         
  17.         static public void printAllInform(Class clsShow) {  
  18.             try {  
  19.                 // 取得所有方法  
  20.                 Method[] hideMethod = clsShow.getDeclaredMethods();  
  21.                 int i = 0;  
  22.                 for (; i < hideMethod.length; i++) {  
  23.                     Log.e("method name", hideMethod[i].getName());  
  24.                 }  
  25.                 // 取得所有常量  
  26.                 Field[] allFields = clsShow.getFields();  
  27.                 for (i = 0; i < allFields.length; i++) {  
  28.                     Log.e("Field name", allFields[i].getName());  
  29.                 }  
  30.             } catch (SecurityException e) {  
  31.                 // throw new RuntimeException(e.getMessage());  
  32.                 e.printStackTrace();  
  33.             } catch (IllegalArgumentException e) {  
  34.                 // throw new RuntimeException(e.getMessage());  
  35.                 e.printStackTrace();  
  36.             } catch (Exception e) {  
  37.                 // TODO Auto-generated catch block  
  38.                 e.printStackTrace();  
  39.             }  
  40.         }  
  41. }
复制代码
testTelephony.java是主类,使用PhoneStateListener监听通话状态,以及实现上述4种电话控制功能,源码如下:

  1. package com.testTelephony;

  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.telephony.PhoneStateListener;
  5. import android.telephony.TelephonyManager;
  6. import android.util.Log;
  7. import android.view.View;
  8. import android.widget.RadioGroup;
  9. import android.widget.ToggleButton;

  10. public class testTelephony extends Activity {
  11.     /** Called when the activity is first created. */
  12.         RadioGroup rg;//来电操作单选框
  13.         ToggleButton tbtnRadioSwitch;//Radio开关
  14.         ToggleButton tbtnDataConn;//数据连接的开关
  15.         TelephonyManager telMgr;
  16.         CallStateListener stateListner;
  17.         int checkedId=0;
  18.         @Override
  19.         public void onCreate(Bundle savedInstanceState) {
  20.                 super.onCreate(savedInstanceState);
  21.                 setContentView(R.layout.main);
  22.                 
  23.                 telMgr= (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
  24.             telMgr.listen(new CallStateListener(), CallStateListener.LISTEN_CALL_STATE);
  25.             
  26.                 PhoneUtils.printAllInform(TelephonyManager.class);
  27.                 
  28.                 rg = (RadioGroup)findViewById(R.id.rGrpSelect);
  29.                 rg.setOnCheckedChangeListener(new CheckEvent());
  30.                 tbtnRadioSwitch=(ToggleButton)this.findViewById(R.id.tbtnRadioSwitch);
  31.                 tbtnRadioSwitch.setOnClickListener(new ClickEvent());
  32.                 try {
  33.                         tbtnRadioSwitch.setChecked(PhoneUtils.getITelephony(telMgr).isRadioOn());
  34.                 }  catch (Exception e) {
  35.                         Log.e("error",e.getMessage());
  36.                 }
  37.                 tbtnDataConn=(ToggleButton)this.findViewById(R.id.tbtnDataConn);
  38.                 tbtnDataConn.setOnClickListener(new ClickEvent());
  39.                 try {
  40.                         tbtnDataConn.setChecked(PhoneUtils.getITelephony(telMgr).isDataConnectivityPossible());
  41.                 }  catch (Exception e) {
  42.                         Log.e("error",e.getMessage());
  43.                 }
  44.         }
  45.         
  46.         /**
  47.          * 来电时的操作
  48.          * @author GV
  49.          *
  50.          */
  51.         public class CheckEvent implements RadioGroup.OnCheckedChangeListener{

  52.                 @Override
  53.                 public void onCheckedChanged(RadioGroup group, int checkedId) {
  54.                         testTelephony.this.checkedId=checkedId;
  55.                 }
  56.         }
  57.         
  58.         /**
  59.          * Radio和数据连接的开关
  60.          * @author GV
  61.          *
  62.          */
  63.         public class ClickEvent implements View.OnClickListener{

  64.                 @Override
  65.                 public void onClick(View v) {
  66.                         if (v == tbtnRadioSwitch) {
  67.                                 try {
  68.                                         PhoneUtils.getITelephony(telMgr).setRadio(tbtnRadioSwitch.isChecked());
  69.                                 } catch (Exception e) {
  70.                                         Log.e("error", e.getMessage());
  71.                                 }
  72.                         }
  73.                         else if(v==tbtnDataConn){
  74.                                 try {
  75.                                         if(tbtnDataConn.isChecked())
  76.                                                 PhoneUtils.getITelephony(telMgr).enableDataConnectivity();
  77.                                         else if(!tbtnDataConn.isChecked())
  78.                                                 PhoneUtils.getITelephony(telMgr).disableDataConnectivity();
  79.                                 } catch (Exception e) {
  80.                                         Log.e("error", e.getMessage());
  81.                                 }        
  82.                         }
  83.                 }
  84.         }
  85.         
  86.         /**
  87.          * 监视电话状态
  88.          * @author GV
  89.          *
  90.          */
  91.         public class CallStateListener extends PhoneStateListener {
  92.                 @Override
  93.                 public void onCallStateChanged(int state, String incomingNumber) {
  94.                         if(state==TelephonyManager.CALL_STATE_IDLE)//挂断
  95.                         {
  96.                                 Log.e("IDLE",incomingNumber);
  97.                         }
  98.                         else if(state==TelephonyManager.CALL_STATE_OFFHOOK)//接听
  99.                         {
  100.                                 Log.e("OFFHOOK",incomingNumber);
  101.                         }
  102.                         else if(state==TelephonyManager.CALL_STATE_RINGING)//来电
  103.                         {
  104.                                 if(testTelephony.this.checkedId==R.id.rbtnAutoAccept)
  105.                                 {
  106.                                         try {
  107.                                                 //需要 
  108.                                                 PhoneUtils.getITelephony(telMgr).silenceRinger();//静铃
  109.                                                 PhoneUtils.getITelephony(telMgr).answerRingingCall();//自动接听
  110.                                             
  111.                                         } catch (Exception e) {
  112.                                                 Log.e("error",e.getMessage());
  113.                                         }        
  114.                                 }
  115.                                 else if(testTelephony.this.checkedId==R.id.rbtnAutoReject)
  116.                                 {
  117.                                         try {
  118.                                                 PhoneUtils.getITelephony(telMgr).endCall();//挂断
  119.                                                 PhoneUtils.getITelephony(telMgr).cancelMissedCallsNotification();//取消未接显示
  120.                                         } catch (Exception e) {
  121.                                                 Log.e("error",e.getMessage());        
  122.                                         }
  123.                                 }
  124.                         }
  125.                         super.onCallStateChanged(state, incomingNumber);
  126.                 }
  127.         }
  128. }
复制代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值