上次介绍了如何使用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添加以下两行代码,以获得权限:
- < uses-permission android:name = "android.permission.CALL_PHONE" />
- < uses-permission android:name = "android.permission.MODIFY_PHONE_STATE" />
main.xml源码如下:
- <? xml version = "1.0" encoding = "utf-8" ?>
- < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
- android:orientation = "vertical" android:layout_width = "fill_parent"
- android:layout_height = "fill_parent" >
- < RadioGroup android:layout_height = "wrap_content"
- android:layout_width = "fill_parent" android:id = "@+id/rGrpSelect" >
- < RadioButton android:layout_height = "wrap_content"
- android:layout_width = "fill_parent" android:id = "@+id/rbtnAutoAccept"
- android:text = "所有来电自动接听" > </ RadioButton >
- < RadioButton android:layout_height = "wrap_content"
- android:layout_width = "fill_parent" android:id = "@+id/rbtnAutoReject"
- android:text = "所有来电自动挂断" > </ RadioButton >
- </ RadioGroup >
- < ToggleButton android:layout_height = "wrap_content"
- android:layout_width = "fill_parent" android:id = "@+id/tbtnRadioSwitch"
- android:textOn = "Radio已经启动" android:textOff = "Radio已经关闭"
- android:textSize = "24dip" android:textStyle = "normal" > </ ToggleButton >
- < ToggleButton android:layout_height = "wrap_content"
- android:layout_width = "fill_parent" android:id = "@+id/tbtnDataConn"
- android:textSize = "24dip" android:textStyle = "normal" android:textOn = "允许数据连接"
- android:textOff = "禁止数据连接" > </ ToggleButton >
- </ LinearLayout >
PhoneUtils.java是手机功能类,从TelephonyManager中实例化ITelephony并返回,源码如下:
- package com.testTelephony;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import com.android.internal.telephony.ITelephony;
- import android.telephony.TelephonyManager;
- import android.util.Log;
- public class PhoneUtils {
- /**
- * 从TelephonyManager中实例化ITelephony,并返回
- */
- static public ITelephony getITelephony(TelephonyManager telMgr) throws Exception {
- Method getITelephonyMethod = telMgr.getClass().getDeclaredMethod("getITelephony" );
- getITelephonyMethod.setAccessible(true ); //私有化函数也能使用
- return (ITelephony)getITelephonyMethod.invoke(telMgr);
- }
- static public void printAllInform(Class clsShow) {
- try {
- // 取得所有方法
- Method[] hideMethod = clsShow.getDeclaredMethods();
- int i = 0 ;
- for (; i < hideMethod.length; i++) {
- Log.e("method name" , hideMethod[i].getName());
- }
- // 取得所有常量
- Field[] allFields = clsShow.getFields();
- for (i = 0 ; i < allFields.length; i++) {
- Log.e("Field name" , allFields[i].getName());
- }
- } catch (SecurityException e) {
- // throw new RuntimeException(e.getMessage());
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- // throw new RuntimeException(e.getMessage());
- e.printStackTrace();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
testTelephony.java是主类,使用PhoneStateListener监听通话状态,以及实现上述4种电话控制功能,源码如下:
- package com.testTelephony;
- import android.app.Activity;
- import android.os.Bundle;
- import android.telephony.PhoneStateListener;
- import android.telephony.TelephonyManager;
- import android.util.Log;
- import android.view.View;
- import android.widget.RadioGroup;
- import android.widget.ToggleButton;
- public class testTelephony extends Activity {
- /** Called when the activity is first created. */
- RadioGroup rg;//来电操作单选框
- ToggleButton tbtnRadioSwitch;//Radio开关
- ToggleButton tbtnDataConn;//数据连接的开关
- TelephonyManager telMgr;
- CallStateListener stateListner;
- int checkedId= 0 ;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super .onCreate(savedInstanceState);
- setContentView(R.layout.main);
- telMgr= (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
- telMgr.listen(new CallStateListener(), CallStateListener.LISTEN_CALL_STATE);
- PhoneUtils.printAllInform(TelephonyManager.class );
- rg = (RadioGroup)findViewById(R.id.rGrpSelect);
- rg.setOnCheckedChangeListener(new CheckEvent());
- tbtnRadioSwitch=(ToggleButton)this .findViewById(R.id.tbtnRadioSwitch);
- tbtnRadioSwitch.setOnClickListener(new ClickEvent());
- try {
- tbtnRadioSwitch.setChecked(PhoneUtils.getITelephony(telMgr).isRadioOn());
- } catch (Exception e) {
- Log.e("error" ,e.getMessage());
- }
- tbtnDataConn=(ToggleButton)this .findViewById(R.id.tbtnDataConn);
- tbtnDataConn.setOnClickListener(new ClickEvent());
- try {
- tbtnDataConn.setChecked(PhoneUtils.getITelephony(telMgr).isDataConnectivityPossible());
- } catch (Exception e) {
- Log.e("error" ,e.getMessage());
- }
- }
- /**
- * 来电时的操作
- * @author GV
- *
- */
- public class CheckEvent implements RadioGroup.OnCheckedChangeListener{
- @Override
- public void onCheckedChanged(RadioGroup group, int checkedId) {
- testTelephony.this .checkedId=checkedId;
- }
- }
- /**
- * Radio和数据连接的开关
- * @author GV
- *
- */
- public class ClickEvent implements View.OnClickListener{
- @Override
- public void onClick(View v) {
- if (v == tbtnRadioSwitch) {
- try {
- PhoneUtils.getITelephony(telMgr).setRadio(tbtnRadioSwitch.isChecked());
- } catch (Exception e) {
- Log.e("error" , e.getMessage());
- }
- }
- else if (v==tbtnDataConn){
- try {
- if (tbtnDataConn.isChecked())
- PhoneUtils.getITelephony(telMgr).enableDataConnectivity();
- else if (!tbtnDataConn.isChecked())
- PhoneUtils.getITelephony(telMgr).disableDataConnectivity();
- } catch (Exception e) {
- Log.e("error" , e.getMessage());
- }
- }
- }
- }
- /**
- * 监视电话状态
- * @author GV
- *
- */
- public class CallStateListener extends PhoneStateListener {
- @Override
- public void onCallStateChanged( int state, String incomingNumber) {
- if (state==TelephonyManager.CALL_STATE_IDLE) //挂断
- {
- Log.e("IDLE" ,incomingNumber);
- }
- else if (state==TelephonyManager.CALL_STATE_OFFHOOK) //接听
- {
- Log.e("OFFHOOK" ,incomingNumber);
- }
- else if (state==TelephonyManager.CALL_STATE_RINGING) //来电
- {
- if (testTelephony. this .checkedId==R.id.rbtnAutoAccept)
- {
- try {
- //需要<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
- PhoneUtils.getITelephony(telMgr).silenceRinger();//静铃
- PhoneUtils.getITelephony(telMgr).answerRingingCall();//自动接听
- } catch (Exception e) {
- Log.e("error" ,e.getMessage());
- }
- }
- else if (testTelephony. this .checkedId==R.id.rbtnAutoReject)
- {
- try {
- PhoneUtils.getITelephony(telMgr).endCall();//挂断
- PhoneUtils.getITelephony(telMgr).cancelMissedCallsNotification();//取消未接显示
- } catch (Exception e) {
- Log.e("error" ,e.getMessage());
- }
- }
- }
- super .onCallStateChanged(state, incomingNumber);
- }
- }
- }