Android提高第十四篇之探秘TelephonyManager

晨曦之光 发布于 2012/03/14 18:57
阅读 647
收藏 1

本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!

       上次介绍了如何使用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);
		}
	}
}


原文链接:http://blog.csdn.net/hellogv/article/details/6065983
加载中
返回顶部
顶部