Android提高第十四篇之探秘TelephonyManager

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

上次介绍了如何使用JAVA的反射机制来调用蓝牙的隐藏API,这次继续练习JAVA的反射机制,探秘TelephonyManager在Framework里包含却在SDK隐藏的几项功能。先来看看本文程序运行的效果图:

Android提高第十四篇之探秘TelephonyManager

本文程序演示了以下功能:

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-permissionandroid:name="android.permission.CALL_PHONE"/>
  2. <uses-permissionandroid:name="android.permission.MODIFY_PHONE_STATE"/>

main.xml源码如下:

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <RadioGroupandroid:layout_height="wrap_content"
  6. android:layout_width="fill_parent"android:id="@+id/rGrpSelect">
  7. <RadioButtonandroid:layout_height="wrap_content"
  8. android:layout_width="fill_parent"android:id="@+id/rbtnAutoAccept"
  9. android:text="所有来电自动接听"></RadioButton>
  10. <RadioButtonandroid:layout_height="wrap_content"
  11. android:layout_width="fill_parent"android:id="@+id/rbtnAutoReject"
  12. android:text="所有来电自动挂断"></RadioButton>
  13. </RadioGroup>
  14. <ToggleButtonandroid:layout_height="wrap_content"
  15. android:layout_width="fill_parent"android:id="@+id/tbtnRadioSwitch"
  16. android:textOn="Radio已经启动"android:textOff="Radio已经关闭"
  17. android:textSize="24dip"android:textStyle="normal"></ToggleButton>
  18. <ToggleButtonandroid:layout_height="wrap_content"
  19. android:layout_width="fill_parent"android:id="@+id/tbtnDataConn"
  20. android:textSize="24dip"android:textStyle="normal"android:textOn="允许数据连接"
  21. android:textOff="禁止数据连接"></ToggleButton>
  22. </LinearLayout>

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

  1. packagecom.testTelephony;
  2. importjava.lang.reflect.Field;
  3. importjava.lang.reflect.Method;
  4. importcom.android.internal.telephony.ITelephony;
  5. importandroid.telephony.TelephonyManager;
  6. importandroid.util.Log;
  7. publicclassPhoneUtils{
  8. /**
  9. *从TelephonyManager中实例化ITelephony,并返回
  10. */
  11. staticpublicITelephonygetITelephony(TelephonyManagertelMgr)throwsException{
  12. MethodgetITelephonyMethod=telMgr.getClass().getDeclaredMethod("getITelephony");
  13. getITelephonyMethod.setAccessible(true);//私有化函数也能使用
  14. return(ITelephony)getITelephonyMethod.invoke(telMgr);
  15. }
  16. staticpublicvoidprintAllInform(ClassclsShow){
  17. try{
  18. //取得所有方法
  19. Method[]hideMethod=clsShow.getDeclaredMethods();
  20. inti=0;
  21. for(;i<hideMethod.length;i++){
  22. Log.e("methodname",hideMethod[i].getName());
  23. }
  24. //取得所有常量
  25. Field[]allFields=clsShow.getFields();
  26. for(i=0;i<allFields.length;i++){
  27. Log.e("Fieldname",allFields[i].getName());
  28. }
  29. }catch(SecurityExceptione){
  30. //thrownewRuntimeException(e.getMessage());
  31. e.printStackTrace();
  32. }catch(IllegalArgumentExceptione){
  33. //thrownewRuntimeException(e.getMessage());
  34. e.printStackTrace();
  35. }catch(Exceptione){
  36. //TODOAuto-generatedcatchblock
  37. e.printStackTrace();
  38. }
  39. }
  40. }

testTelephony.java是主类,使用PhoneStateListener监听通话状态,以及实现上述4种电话控制功能,源码如下:

  1. packagecom.testTelephony;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.telephony.PhoneStateListener;
  5. importandroid.telephony.TelephonyManager;
  6. importandroid.util.Log;
  7. importandroid.view.View;
  8. importandroid.widget.RadioGroup;
  9. importandroid.widget.ToggleButton;
  10. publicclasstestTelephonyextendsActivity{
  11. /**Calledwhentheactivityisfirstcreated.*/
  12. RadioGrouprg;//来电操作单选框
  13. ToggleButtontbtnRadioSwitch;//Radio开关
  14. ToggleButtontbtnDataConn;//数据连接的开关
  15. TelephonyManagertelMgr;
  16. CallStateListenerstateListner;
  17. intcheckedId=0;
  18. @Override
  19. publicvoidonCreate(BundlesavedInstanceState){
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.main);
  22. telMgr=(TelephonyManager)getSystemService(TELEPHONY_SERVICE);
  23. telMgr.listen(newCallStateListener(),CallStateListener.LISTEN_CALL_STATE);
  24. PhoneUtils.printAllInform(TelephonyManager.class);
  25. rg=(RadioGroup)findViewById(R.id.rGrpSelect);
  26. rg.setOnCheckedChangeListener(newCheckEvent());
  27. tbtnRadioSwitch=(ToggleButton)this.findViewById(R.id.tbtnRadioSwitch);
  28. tbtnRadioSwitch.setOnClickListener(newClickEvent());
  29. try{
  30. tbtnRadioSwitch.setChecked(PhoneUtils.getITelephony(telMgr).isRadioOn());
  31. }catch(Exceptione){
  32. Log.e("error",e.getMessage());
  33. }
  34. tbtnDataConn=(ToggleButton)this.findViewById(R.id.tbtnDataConn);
  35. tbtnDataConn.setOnClickListener(newClickEvent());
  36. try{
  37. tbtnDataConn.setChecked(PhoneUtils.getITelephony(telMgr).isDataConnectivityPossible());
  38. }catch(Exceptione){
  39. Log.e("error",e.getMessage());
  40. }
  41. }
  42. /**
  43. *来电时的操作
  44. *@authorGV
  45. *
  46. */
  47. publicclassCheckEventimplementsRadioGroup.OnCheckedChangeListener{
  48. @Override
  49. publicvoidonCheckedChanged(RadioGroupgroup,intcheckedId){
  50. testTelephony.this.checkedId=checkedId;
  51. }
  52. }
  53. /**
  54. *Radio和数据连接的开关
  55. *@authorGV
  56. *
  57. */
  58. publicclassClickEventimplementsView.OnClickListener{
  59. @Override
  60. publicvoidonClick(Viewv){
  61. if(v==tbtnRadioSwitch){
  62. try{
  63. PhoneUtils.getITelephony(telMgr).setRadio(tbtnRadioSwitch.isChecked());
  64. }catch(Exceptione){
  65. Log.e("error",e.getMessage());
  66. }
  67. }
  68. elseif(v==tbtnDataConn){
  69. try{
  70. if(tbtnDataConn.isChecked())
  71. PhoneUtils.getITelephony(telMgr).enableDataConnectivity();
  72. elseif(!tbtnDataConn.isChecked())
  73. PhoneUtils.getITelephony(telMgr).disableDataConnectivity();
  74. }catch(Exceptione){
  75. Log.e("error",e.getMessage());
  76. }
  77. }
  78. }
  79. }
  80. /**
  81. *监视电话状态
  82. *@authorGV
  83. *
  84. */
  85. publicclassCallStateListenerextendsPhoneStateListener{
  86. @Override
  87. publicvoidonCallStateChanged(intstate,StringincomingNumber){
  88. if(state==TelephonyManager.CALL_STATE_IDLE)//挂断
  89. {
  90. Log.e("IDLE",incomingNumber);
  91. }
  92. elseif(state==TelephonyManager.CALL_STATE_OFFHOOK)//接听
  93. {
  94. Log.e("OFFHOOK",incomingNumber);
  95. }
  96. elseif(state==TelephonyManager.CALL_STATE_RINGING)//来电
  97. {
  98. if(testTelephony.this.checkedId==R.id.rbtnAutoAccept)
  99. {
  100. try{
  101. //需要<uses-permissionandroid:name="android.permission.MODIFY_PHONE_STATE"/>
  102. PhoneUtils.getITelephony(telMgr).silenceRinger();//静铃
  103. PhoneUtils.getITelephony(telMgr).answerRingingCall();//自动接听
  104. }catch(Exceptione){
  105. Log.e("error",e.getMessage());
  106. }
  107. }
  108. elseif(testTelephony.this.checkedId==R.id.rbtnAutoReject)
  109. {
  110. try{
  111. PhoneUtils.getITelephony(telMgr).endCall();//挂断
  112. PhoneUtils.getITelephony(telMgr).cancelMissedCallsNotification();//取消未接显示
  113. }catch(Exceptione){
  114. Log.e("error",e.getMessage());
  115. }
  116. }
  117. }
  118. super.onCallStateChanged(state,incomingNumber);
  119. }
  120. }
  121. }

你可能感兴趣的:(android)