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添加以下两行代码,以获得权限:

<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项目开发有所帮助。

(0)

相关推荐

  • 安卓(Android)开发之统计App启动时间

    前言 作为 Android 开发者,想必多多少少要接触启动速度优化相关的事情,当用户越来越多,产品的功能也随着迭代越来越多,App 逐渐变得臃肿是一件很常见的现象,甚至可以说是不可避免的现象,随之而来的工作就是优化 App 性能,其中最主要的一项就是启动速度优化.但本文的主角并不是启动速度优化,而是启动时间统计. 一.启动类型 工欲善其事,必先利其器.想要优化 App 的启动速度,必须有准确衡量启动时间的方法,否则优化完之后效果怎样,自己都不知道,说出去别人也不信服不是.在做 App 启动时间统

  • Android中TelephonyManager类的用法案例详解

    本文以案例形式分析了Android中TelephonyManager类的用法.分享给大家供大家参考.具体如下: 目录结构: main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="ve

  • Android如何自定义按钮效果

    安卓原生的按钮是多么丑,效果是多么单调,大家也是有目共睹的. 要做一个APP少不了使用按钮,一个好看的按钮少不了好看的效果和外表,这次主要跟大家讲讲如何用drawable的xml文件弄一些好看的自定义样式. 首先是外表 在APP中四四方方,灰色底黑色字的按钮是很难看的,我们希望看到的是圆角,彩色,白字(根据你的个人审美也可以是其他样式). 首先是在layout里新建一个按钮 ,然后在drawable文件夹里新建一个drawable resource file ,不妨起名为shape ,加一个se

  • Android 应用更换皮肤实现方法

    Android应用更换皮肤功能的实现思路   我们可以将皮肤包做成一个apk文件,在应用apk中读取皮肤包中的数据.   应用apk读取皮肤包apk的数据的条件 1. 有相同签名 2. AndroidManifest.xml中配置android:sharedUserId有相同的属性值 满足以上条件,两个apk就能互相访问数据了.      Android应用更换皮肤功能的实现步骤 1.应用程序和皮肤程序的AndroidManifest.xml中配置 XML/HTML代码 android:shar

  • Android中TelephonyManager类的方法实例分析

    本文实例讲述了Android中TelephonyManager类的方法.分享给大家供大家参考.具体如下: TelephonyManager类主要提供了一系列用于访问与手机通讯相关的状态和信息的get方法.其中包括手机SIM的状态和信息.电信网络的状态及手机用户的信息.在应用程序中可以使用这些get方法获取相关数据. TelephonyManager类的对象可以通过Context.getSystemService(Context.TELEPHONY_SERVICE)方法来获得,需要注意的是有些通讯

  • Android TelephonyManager详解及实现代码

    JAVA的反射机制,探秘TelephonyManager在Framework里包含却在SDK隐藏的几项功能.先来看看本文程序运行的效果图: 本文程序演示了以下功能: 1.所有来电自动接听:        2.所有来电自动挂断:        3.开启/关闭Radio:        4.开启/关闭数据连接(WAP or NET的连接). 调用TelephonyManager的隐藏API是先参考Framework的/base/telephony/java/com/android/internal/

  • Android中TelephonyManager用法实例

    本文实例讲述了Android中TelephonyManager用法.分享给大家供大家参考,具体如下: 一.概述: TelephonyManager类主要提供了一系列用于访问与手机通讯相关的状态和信息的get方法.其中包括手机SIM的状态和信息.电信网络的状态及手机用户的信息.在应用程序中可以使用这些get方法获取相关数据. TelephonyManager类的对象可以通过Context.getSystemService(Context.TELEPHONY_SERVICE)方法来获得,需要注意的是

  • Android GPS详解及示例代码

    LBS(Location Based Services)直译的话就是基于地理位置的服务,这里面至少有两层意思,第一要能轻易的获取当前的地理位置,譬如经纬度海拔等,另一个就是在当前位置的基础上提供增值服务,譬如找附近的加油站.餐馆.酒店等.这里面的第一步:获取用户当前位置,我们就可以用Android的GPS定位服务来得到.Android提供了基于网络的定位服务和基于卫星的定位服务两种.在设置->位置和安全设置里面的前三项就是,最后一个增强型GPS是为了辅助快速找卫星的. 那么我们现在就写一个简单的

  • Android提高之TelephonyManager功能探秘

    前面文章介绍了如何使用JAVA的反射机制来调用蓝牙的隐藏API,本文继续来练习JAVA的反射机制,探秘TelephonyManager在Framework里包含却在SDK隐藏的几项功能. 先来看一下本文程序运行的效果图,如下所示: 本文程序演示了以下功能: 1.所有来电自动接听: 2.所有来电自动挂断: 3.开启/关闭Radio: 4.开启/关闭数据连接(WAP or NET的连接). 调用TelephonyManager的隐藏API是先参考Framework的/base/telephony/j

  • Android Studio常用快捷键功能说明

    Android Studio 是谷歌基于IntelliJ IDEA开发的安卓开发工具,有点类似 EcliPSe ADT,Android Studio 提供了集成的 Android 开发工具用于开发和调试,基于Gradle的构建支持. Android Studio常用快捷键 Ctrl+D: 集合了复制和粘贴两个操作,如果有选中的部分就复制选中的部分,并在选中部分的后面 粘贴出来,如果没有选中的部分,就复制光标所在的行,并在此行的下面粘贴出来. Ctrl+空格: 输入代码时按此组合键会列出与之相匹配

  • Android图片采样缩放功能实例代码

    为什么要对Android中的图片进行采样缩放呢? 是为了更加高效的加载Bitmap.假设通过imageView来显示图片,很多时候ImageView并没有图片的原始尺寸那么大,这时候把整张图片加载进来后再设给ImageView是没有必要的,因为ImagView并没有办法显示原始的图片. 所以我们可以使用BitmapFactory.Options按照一定的采样率加载缩小后的图片,将缩小后的图片在ImageView中显示,这样就能降低内存占用,在一定程度上避免OOM,提高bitma加载时候的性能.

  • Android中Activity常用功能设置小结(包括全屏、横竖屏等)

    本文实例讲述了Android中Activity常用功能设置小结(包括全屏.横竖屏等).分享给大家供大家参考,具体如下: Activity全屏设置 方式1:AndroidManifest.xml 复制代码 代码如下: <activity android:name="myAcitivty"  android:theme="@android:style/Theme.NoTitleBar.Fullscreen" /> 方式2:代码实现 复制代码 代码如下: re

  • Android 获取随机验证码功能示例

    验证码功能在各大网站都能用到,下面小编通过实例代码给大家分享Android 获取随机验证码功能,具体代码如下所示: package cn.hk.image; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; impo

  • Android仿外卖购物车功能

    先看看效果图: 知识点分析 效果图来看不复杂内容并没多少,值得介绍一下的知识点也就下面几个吧 - 列表标题悬停 - 左右列表滑动时联动 - 添加商品时的抛物线动画 - 底部弹出购物车清单 - 数据的同步 另外就是实现效果的时候可能会遇到的几个坑... 布局很简单直接进入代码 1:列表标题悬停 现在做项目列表什么的基本抛弃了ListView改用RecyclerView,上篇博客中的标题悬停也是使用了一个RecyclerView的开源项目sticky-headers-recyclerview,不过写

  • Android Camera开发手电筒功能

    这是一个简单的运用Android Camera开发手电筒功能,AndroidManifest.xml文件的入口是startapp,这个文件没上传上来,大家可以自己写. flashlight.java package com.android.app; import android.app.Activity; import android.hardware.Camera; import android.hardware.Camera.Parameters; import android.os.Bun

  • Android实现时间倒计时功能

    本文实例为大家分享了Android实现时间倒计时功能展示的具体代码,供大家参考,具体内容如下 效果展示 MainActivity(主页面代码) public class MainActivity extends Activity { private RelativeLayout countDown; // 倒计时 private TextView daysTv, hoursTv, minutesTv, secondsTv; private long mDay = 10; private long

  • Android中Listview点赞功能的实现

    最近这段时间一直在看Android,利用Listview去实现点赞功能,下面给大家介绍下基本思路. 基本思路: 进入界面–>获取数据–> 在Listview中显示–> 通过map集合(position,boolean)保存每一行是否被点击–> 利用实体类去保存相应的对象–> get/set方法进行相应值得改变–> 点击一次,相应的数量加1 只实现了点赞功能,踩和赞基本类似. 具体实现如下: 继承自BaseAdapter package com.gz.test_listv

  • Android实现微信支付功能

    开发Android APP微信支付功能,需要完成三个步骤:第一步生成预支付订单.第二步生成微信支付参数.第三步调起微信APP支付.除了需要审核通过的APP应用外,还需要获得微信支付接口权限,然后获取对应的商户号.API密钥,这两者缺一不可,并且在APP微信支付中使用 获得商户号.API密钥 在微信开放平台中查看审核通过的APP应用,是否申请支付功能,若已申请,登录微信支付|商户平台:http://pay.weixin.qq.com 查看对应的商户号.API密钥 >申请微信支付接口 >登录商户平

随机推荐