本文来自http://blog.youkuaiyun.com/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-permissionandroid:name="android.permission.CALL_PHONE"/>
- <uses-permissionandroid:name="android.permission.MODIFY_PHONE_STATE"/>
main.xml源码如下:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <RadioGroupandroid:layout_height="wrap_content"
- android:layout_width="fill_parent"android:id="@+id/rGrpSelect">
- <RadioButtonandroid:layout_height="wrap_content"
- android:layout_width="fill_parent"android:id="@+id/rbtnAutoAccept"
- android:text="所有来电自动接听"></RadioButton>
- <RadioButtonandroid:layout_height="wrap_content"
- android:layout_width="fill_parent"android:id="@+id/rbtnAutoReject"
- android:text="所有来电自动挂断"></RadioButton>
- </RadioGroup>
- <ToggleButtonandroid: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>
- <ToggleButtonandroid: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并返回,源码如下:
- packagecom.testTelephony;
- importjava.lang.reflect.Field;
- importjava.lang.reflect.Method;
- importcom.android.internal.telephony.ITelephony;
- importandroid.telephony.TelephonyManager;
- importandroid.util.Log;
- publicclassPhoneUtils{
- /**
- *从TelephonyManager中实例化ITelephony,并返回
- */
- staticpublicITelephonygetITelephony(TelephonyManagertelMgr)throwsException{
- MethodgetITelephonyMethod=telMgr.getClass().getDeclaredMethod("getITelephony");
- getITelephonyMethod.setAccessible(true);//私有化函数也能使用
- return(ITelephony)getITelephonyMethod.invoke(telMgr);
- }
- staticpublicvoidprintAllInform(ClassclsShow){
- try{
- //取得所有方法
- Method[]hideMethod=clsShow.getDeclaredMethods();
- inti=0;
- for(;i<hideMethod.length;i++){
- Log.e("methodname",hideMethod[i].getName());
- }
- //取得所有常量
- Field[]allFields=clsShow.getFields();
- for(i=0;i<allFields.length;i++){
- Log.e("Fieldname",allFields[i].getName());
- }
- }catch(SecurityExceptione){
- //thrownewRuntimeException(e.getMessage());
- e.printStackTrace();
- }catch(IllegalArgumentExceptione){
- //thrownewRuntimeException(e.getMessage());
- e.printStackTrace();
- }catch(Exceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }
- }
- }
testTelephony.java是主类,使用PhoneStateListener监听通话状态,以及实现上述4种电话控制功能,源码如下:
- packagecom.testTelephony;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.telephony.PhoneStateListener;
- importandroid.telephony.TelephonyManager;
- importandroid.util.Log;
- importandroid.view.View;
- importandroid.widget.RadioGroup;
- importandroid.widget.ToggleButton;
- publicclasstestTelephonyextendsActivity{
- /**Calledwhentheactivityisfirstcreated.*/
- RadioGrouprg;//来电操作单选框
- ToggleButtontbtnRadioSwitch;//Radio开关
- ToggleButtontbtnDataConn;//数据连接的开关
- TelephonyManagertelMgr;
- CallStateListenerstateListner;
- intcheckedId=0;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- telMgr=(TelephonyManager)getSystemService(TELEPHONY_SERVICE);
- telMgr.listen(newCallStateListener(),CallStateListener.LISTEN_CALL_STATE);
- PhoneUtils.printAllInform(TelephonyManager.class);
- rg=(RadioGroup)findViewById(R.id.rGrpSelect);
- rg.setOnCheckedChangeListener(newCheckEvent());
- tbtnRadioSwitch=(ToggleButton)this.findViewById(R.id.tbtnRadioSwitch);
- tbtnRadioSwitch.setOnClickListener(newClickEvent());
- try{
- tbtnRadioSwitch.setChecked(PhoneUtils.getITelephony(telMgr).isRadioOn());
- }catch(Exceptione){
- Log.e("error",e.getMessage());
- }
- tbtnDataConn=(ToggleButton)this.findViewById(R.id.tbtnDataConn);
- tbtnDataConn.setOnClickListener(newClickEvent());
- try{
- tbtnDataConn.setChecked(PhoneUtils.getITelephony(telMgr).isDataConnectivityPossible());
- }catch(Exceptione){
- Log.e("error",e.getMessage());
- }
- }
- /**
- *来电时的操作
- *@authorGV
- *
- */
- publicclassCheckEventimplementsRadioGroup.OnCheckedChangeListener{
- @Override
- publicvoidonCheckedChanged(RadioGroupgroup,intcheckedId){
- testTelephony.this.checkedId=checkedId;
- }
- }
- /**
- *Radio和数据连接的开关
- *@authorGV
- *
- */
- publicclassClickEventimplementsView.OnClickListener{
- @Override
- publicvoidonClick(Viewv){
- if(v==tbtnRadioSwitch){
- try{
- PhoneUtils.getITelephony(telMgr).setRadio(tbtnRadioSwitch.isChecked());
- }catch(Exceptione){
- Log.e("error",e.getMessage());
- }
- }
- elseif(v==tbtnDataConn){
- try{
- if(tbtnDataConn.isChecked())
- PhoneUtils.getITelephony(telMgr).enableDataConnectivity();
- elseif(!tbtnDataConn.isChecked())
- PhoneUtils.getITelephony(telMgr).disableDataConnectivity();
- }catch(Exceptione){
- Log.e("error",e.getMessage());
- }
- }
- }
- }
- /**
- *监视电话状态
- *@authorGV
- *
- */
- publicclassCallStateListenerextendsPhoneStateListener{
- @Override
- publicvoidonCallStateChanged(intstate,StringincomingNumber){
- if(state==TelephonyManager.CALL_STATE_IDLE)//挂断
- {
- Log.e("IDLE",incomingNumber);
- }
- elseif(state==TelephonyManager.CALL_STATE_OFFHOOK)//接听
- {
- Log.e("OFFHOOK",incomingNumber);
- }
- elseif(state==TelephonyManager.CALL_STATE_RINGING)//来电
- {
- if(testTelephony.this.checkedId==R.id.rbtnAutoAccept)
- {
- try{
- //需要<uses-permissionandroid:name="android.permission.MODIFY_PHONE_STATE"/>
- PhoneUtils.getITelephony(telMgr).silenceRinger();//静铃
- PhoneUtils.getITelephony(telMgr).answerRingingCall();//自动接听
- }catch(Exceptione){
- Log.e("error",e.getMessage());
- }
- }
- elseif(testTelephony.this.checkedId==R.id.rbtnAutoReject)
- {
- try{
- PhoneUtils.getITelephony(telMgr).endCall();//挂断
- PhoneUtils.getITelephony(telMgr).cancelMissedCallsNotification();//取消未接显示
- }catch(Exceptione){
- Log.e("error",e.getMessage());
- }
- }
- }
- super.onCallStateChanged(state,incomingNumber);
- }
- }
- }