热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Android提高之TelephonyManager功能探秘

这篇文章主要介绍了Android的TelephonyManager功能,可以帮助读者更好的理解Java反射机制,需要的朋友可以参考下

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




main.xml源码如下:

<&#63;xml version="1.0" encoding="utf-8"&#63;>

 
 
 
 
 
 


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 

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


推荐阅读
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 本文介绍如何通过SQL查询从JDE(JD Edwards)系统中提取所有字典数据,涵盖关键表的关联和字段选择。具体包括F0004和F0005系列表的数据提取方法。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 本文详细介绍了如何通过命令行启动MySQL服务,包括打开命令提示符窗口、进入MySQL的bin目录、输入正确的连接命令以及注意事项。文中还提供了更多相关命令的资源链接。 ... [详细]
  • 本文介绍如何使用 NSTimer 实现倒计时功能,详细讲解了初始化方法、参数配置以及具体实现步骤。通过示例代码展示如何创建和管理定时器,确保在指定时间间隔内执行特定任务。 ... [详细]
  • 本文介绍了在Windows环境下使用pydoc工具的方法,并详细解释了如何通过命令行和浏览器查看Python内置函数的文档。此外,还提供了关于raw_input和open函数的具体用法和功能说明。 ... [详细]
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
  • 高效解决应用崩溃问题!友盟新版错误分析工具全面升级
    友盟推出的最新版错误分析工具,专为移动开发者设计,提供强大的Crash收集与分析功能。该工具能够实时监控App运行状态,快速发现并修复错误,显著提升应用的稳定性和用户体验。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文详细介绍了Git分布式版本控制系统中远程仓库的概念和操作方法。通过具体案例,帮助读者更好地理解和掌握如何高效管理代码库。 ... [详细]
author-avatar
烂在心底
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有