Android提高之TelephonyManager功能探秘

作者:shichen2014 时间:2021-06-11 01:19:12 

前面文章介绍了如何使用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添加以下两行代码,以获得权限:


<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);
}
}
}

感兴趣的读者可以测试一下本文实例代码,希望能够对大家的Android项目开发有所帮助。

标签:Android
0
投稿

猜你喜欢

  • Android 微信摇一摇功能实现详细介绍

    2023-06-21 21:00:09
  • WinForm实现仿视频播放器左下角滚动新闻效果的方法

    2021-11-04 19:43:41
  • ReentrantLock源码详解--条件锁

    2023-01-01 15:36:22
  • Java抽象类和接口的区别详情

    2023-05-23 20:09:59
  • 基于selenium-java封装chrome、firefox、phantomjs实现爬虫

    2022-04-07 19:04:28
  • C#队列的简单使用

    2022-01-21 03:05:42
  • 分析HashMap 的 JDK 源码

    2022-01-17 06:29:54
  • Java基于分治算法实现的棋盘覆盖问题示例

    2021-07-17 14:05:16
  • 比较2个datatable内容是否相同的方法

    2022-11-25 08:27:04
  • MyBatis中${} 和 #{} 有什么区别小结

    2021-09-21 14:42:35
  • C#/VB.NET 实现在PDF表格中添加条形码

    2022-12-25 19:58:16
  • Java安全之Tomcat6 Filter内存马问题

    2022-11-20 07:29:23
  • Android序列化接口Parcelable与Serializable接口对比

    2023-03-24 17:48:59
  • Android 将本地资源图片转换成Drawable,进行设置大小操作

    2023-06-19 17:38:55
  • Android实现界面左右滑动切换功能

    2022-08-30 02:00:58
  • 如何利用Java输出链表中倒数第k个结点

    2022-11-29 10:13:28
  • java中的session对象及其常用方法小结

    2023-11-25 02:31:33
  • Android DownloadMananger管理器实现下载图片功能

    2022-05-06 03:20:24
  • VS2019打包WPF安装程序最新教程(图文详解)

    2021-11-18 15:52:08
  • Android客户端实现图片轮播控件

    2023-08-12 17:01:57
  • asp之家 软件编程 m.aspxhome.com