Android拔高第十四篇之探秘TelephonyManager
Android提高第十四篇之探秘TelephonyManager上次介绍了如何使用JAVA的反射机制来调用蓝牙的隐藏API,这次继
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添加以下两行代码,以获得权限:?
Xml代码??
- <uses-permission?android:name="android.permission.CALL_PHONE"?/>????
- <uses-permission?android:name="android.permission.MODIFY_PHONE_STATE"?/>????
main.xml源码如下:?
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并返回,源码如下:?
Java代码??
- 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种电话控制功能,源码如下:?
Java代码??
- 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);????
- ????????}????
- ????}????
- } ? ?
1 楼 dagf113225 2012-01-29 调用TelephonyManager的隐藏API是先参考Framework的\base\telephony\java\com\android\internal\telephony\ITelephony.aidl,然后自己实现一个ITelephony.aidl,最后在TelephonyManager中通过反射机制实例化自定义的ITelephony,实例化之后就可以调用ITelephony里面的函数了。
请指教,这步如何实现,能贴出完整的代码和工程吗?谢谢