前段时间做了一个简单的Demo,拦截电话并拒接。其中遇到一个小问题,拦截会有延迟,偶尔会响一声或者两声,之后才能拒接成功。那么怎么解决响一两声的问题呢?确实还费了点时间呢!谁叫咱的技术不行呢?这里记录一下拦截来电并拒接以及响铃声的问题的处理。

  1,拦截电话需要接收来电的广播,android.intent.action.PHONE_STATE。写一个Receiver来接收广播。

 1 import android.content.BroadcastReceiver;
 2 import android.content.ComponentName;
 3 import android.content.Context;
 4 import android.content.Intent;
 5 import android.net.Uri;
 6 import android.util.Log;
 7
 8 public class PhoneBroadcastReceiver  extends BroadcastReceiver{
 9
10     private static final String TAG = "PhoneBroadcastReceiver";
11
12     @Override
13     public void onReceive(Context context, Intent intent) {
14         String action = intent.getAction();
15         Log.i(TAG, "zjq action:"+ action);
16         String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
17         //如果是去电
18         if((Intent.ACTION_NEW_OUTGOING_CALL).equals(action)){
19             Log.i(TAG, "call out:"+ phoneNumber);
20             Intent i = new Intent(Intent.ACTION_CALL,Uri.parse("tel:" + phoneNumber));
21             i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
22             context.startActivity(i);
23         }else if("android.intent.action.PHONE_STATE".equals(action)){
24             //ACTION_PHONE_STATE_CHANGED
25             //监听电话状态的改变
26             Log.i(TAG, "phone state changed");
27
28             //来电,判定是否拒接等操作,在这里处理:
29             Intent inte = new Intent();
30             inte.setComponent(new ComponentName("com.zjq.calldemo"
31                     ,"com.zjq.calldemo.PhoneHangUpService"));
32             inte.setAction("yd.calldemo.action.PhoneHangUpService");
33             context.startService(inte);
34         }
35     }
36 }

2,广播需要在Manifest.xml中注册:

1 <receiver android:name=".PhoneBroadcastReceiver">
2             <intent-filter >
3                 <action android:name="android.intent.action.BOOT_COMPLETED" />
4                 <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
5                 <action android:name="android.intent.action.PHONE_STATE"/>
6             </intent-filter>
7         </receiver>

增加权限:

1  <uses-permission android:name="android.permission.CALL_PHONE" >
2  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
3 <uses-permission android:name="android.permission.READ_PHONE_STATE" />  

3,接下来处理广播,拦截到的来电,放在service中处理,监听来电的三种状态:

CALL_STATE_RINGING   正在响铃,电话进来时

CALL_STATE_IDLE   已挂断,无任何状态时

CALL_STATE_OFFHOOK  接听,接起电话时

延时导致的响一声问题,通过切换声音模式来处理,当判断来电为需要拒接的电话时,将铃声设置为静音,不让其响铃,待成功拒接后,回复为普通模式(回复声音)这样就规避了铃声的问题。当然方法有很多,可能我这种比较投机,通过尝试来看,这种相对简单一些。代码如下:

  1 import android.app.Service;
  2 import android.content.Context;
  3 import android.content.Intent;
  4 import android.media.AudioManager;
  5 import android.os.Handler;
  6 import android.os.IBinder;
  7 import android.os.Message;
  8 import android.os.RemoteException;
  9 import android.telephony.PhoneStateListener;
 10 import android.telephony.SmsManager;
 11 import android.telephony.TelephonyManager;
 12 import android.text.TextUtils;
 13 import android.util.Log;
 14
 15 import com.android.internal.telephony.ITelephony;
 16
 17 import java.lang.reflect.InvocationTargetException;
 18 import java.lang.reflect.Method;
 19 import java.util.List;
 20
 21 public class PhoneHangUpService extends Service {
 22     private static final String TAG = "PhoneHangUpService";
 23     private static final int MSG_DELETE_CALL_LOG = 1;
 24
 25     private MyPhoneStateListener mPhoneStateListener;
 26     private TelephonyManager mTelephonyManager;
 27     private Context context;
 28     public AudioManager am ;
 29     private Handler mHandler = new Handler() {
 30         @Override
 31         public void dispatchMessage(Message msg) {
 32             switch (msg.what) {
 33                 case MSG_DELETE_CALL_LOG:
 34                     String number = (String) msg.obj;
 35 //
 36                     break;
 37             }
 38         }
 39
 40     };
 41
 42     @Override
 43     public void onCreate() {
 44         super.onCreate();
 45         Log.i(TAG, "onCreate");
 46         context = this;
 47         //声明监听类,在监听类中实现具体处理
 48         mPhoneStateListener = new MyPhoneStateListener();
 49         mTelephonyManager = (TelephonyManager) getSystemService(Service.TELEPHONY_SERVICE);
 50         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
 51
 52         am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
 53     }
 54
 55     @Override
 56     public void onDestroy() {
 57         super.onDestroy();
 58         mTelephonyManager.listen(mPhoneStateListener, 0);
 59     }
 60
 61     @Override
 62     public int onStartCommand(Intent intent, int flags, int startId) {
 63         return super.onStartCommand(intent, flags, startId);
 64     }
 65
 66     @Override
 67     public IBinder onBind(Intent intent) {
 68         return null;
 69     }
 70
 71     //挂断电话方法
 72     private boolean hangUp() {
 73         Class<TelephonyManager> c = TelephonyManager.class;
 74         ITelephony iTelephony = null;
 75         Method getITelephonyMethod = null;
 76         try {
 77             getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[]) null);
 78             getITelephonyMethod.setAccessible(true);
 79         } catch (SecurityException e) {
 80             e.printStackTrace();
 81         } catch (NoSuchMethodException e) {
 82             e.printStackTrace();
 83         }
 84         try {
 85             iTelephony = (ITelephony)
 86                     getITelephonyMethod.invoke(mTelephonyManager, (Object[]) null);
 87         } catch (IllegalArgumentException e) {
 88             e.printStackTrace();
 89         } catch (IllegalAccessException e) {
 90             e.printStackTrace();
 91         } catch (InvocationTargetException e) {
 92             e.printStackTrace();
 93         }
 94         if (iTelephony != null) {
 95             boolean isSuccess = false;
 96             try {
 97                 isSuccess = iTelephony.endCall();
 98                 am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);//恢复会普通模式,恢复声音
 99
100             } catch (RemoteException e) {
101                 e.printStackTrace();
102             }
103             return isSuccess;
104         }
105         return true;
106     }
107
108     //监听类,监听来电
109     private final class MyPhoneStateListener extends android.telephony.PhoneStateListener {
110         @Override
111         public void onCallStateChanged(int state, String incomingNumber) {
112             super.onCallStateChanged(state, incomingNumber);
113             Log.i(TAG, "zjq Number:" + incomingNumber);
114             if (TelephonyManager.CALL_STATE_RINGING == state) {
115                 Log.i(TAG, "zhangjieqiong state:CALL_STATE_RINGING:" + incomingNumber);
116                 if (!TextUtils.isEmpty(incomingNumber) && PhoneUtils.isPhoneNumber(incomingNumber)) {
117                     //拒接电话 当号码为135*****182时拒接
118                     if ("135*****182".equals(incomingNumber)) {
119                         am.setRingerMode(AudioManager.RINGER_MODE_SILENT);//设置为静音模式,解决延迟导致的响铃问题
120                         Log.i(TAG, "zjq:the number is endcallnumber:"+incomingNumber);
121                         if (hangUp()) {
122                             Log.i(TAG, "zjq end call success ");
123                             Message msg = mHandler.obtainMessage(MSG_DELETE_CALL_LOG);
124                             msg.obj = incomingNumber;
125                             mHandler.sendMessageDelayed(msg, 2000);
126                             //发送一条短信,提示拒接成功
127                             handleSetSystemParamSms(incomingNumber, incomingNumber +" endcall success");
128                         }
129                     }
130                 }
131             }else if(TelephonyManager.CALL_STATE_IDLE == state){
132                 //挂断
133                 //挂断电话可以在这里处理
134                 Log.i(TAG, "zjq state: hang up(endcall)");
135             }else if(TelephonyManager.CALL_STATE_OFFHOOK == state){
136                 //接听
137                 Log.i(TAG, "zjq state: answer:"+ incomingNumber);
138             }
139         }
140
141     }
142
143
144     //发送短信方法
145     private void handleSetSystemParamSms(String phone, String body) {
146         Log.d(TAG, "user get location");
147         String msg = body ;
148         if (msg != null) {
149             Log.d(TAG, "msgBody lenth = " + msg.length());
150             SmsManager sms = SmsManager.getDefault();
151             List<String> texts = sms.divideMessage(msg);
152             for (String text : texts) {
153                 Log.d(TAG, "zjq send sms to:" + phone);
154                 sms.sendTextMessage(phone, null, text, null, null);
155             }
156         }
157     }
158 }

4,不能忘记增加aidl,通过调用系统接口来拒接电话,方法:iTelephony.endCall():

其中ITelephony.aidl中内容如下(加入常用的几种方法即可,这个不是自己写的,手机系统的接口类,直接拿来用了,嘿嘿)

 1 package com.android.internal.telephony;
 2
 3 import android.os.Bundle;
 4 import java.util.List;
 5
 6 /**
 7  * Interface used to interact with the phone.  Mostly this is used by the
 8  * TelephonyManager class.  A few places are still using this directly.
 9  * Please clean them up if possible and use TelephonyManager insteadl.
10  *
11  * {@hide}
12  */
13 interface ITelephony {
14
15     /**
16      * End call or go to the Home screen
17      *
18      * @return whether it hung up
19      */
20     boolean endCall();
21
22      /**
23      * Check if the phone is idle.
24      * @return true if the phone state is IDLE.
25      */
26     boolean isIdle();
27 }

网上这种方法介绍的有很多,我这里记录一下,方便以后自己查找。有不足之处,欢迎指正!

转载于:https://www.cnblogs.com/zjqlogs/p/5505314.html

Android学习小记-----拦截电话/拒接电话,规避拒接电话前响一声或者两声的问题...相关推荐

  1. Android学习小记-----监听并保存传感器数据,让service后台运行(保持CPU运转

    最近做了一个Demo,监听手机中传感器的数据,并将数据保存到手机文件中,发现数据会有丢失的现象. 经过多次测试,发现系统进入深度休眠了,之后service会停止,虽然增加了service自动启动的功能 ...

  2. android学习笔记---38_采用广播接收者拦截外拔电话,实现原理以及实例源码

    38_采用广播接收者拦截外拔电话及其特性 这个程序是在原来的基础上进行的: 用到了,上一个工程SMSListener 首先在清单文件中添加,外拨电话的广播接受者 <receiver androi ...

  3. Android项目:手机安全卫士(13)—— 通讯卫士之电话拦截与挂断

    Android项目:手机安全卫士(13)-- 通讯卫士之电话拦截与挂断 1 介绍 上一节我们讲了黑名单数据的存储等 CRUD 操作,今天,就到了它们发挥作用的时候了,通讯卫士功法终于要练成了.我们实现 ...

  4. Android项目:手机安全卫士(12)—— 通讯卫士之电话短信黑名单设置与拦截

    版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] Android项目:手机安全卫士(12)-- 通讯卫士之电话.短信黑名单设置与拦截 1 介绍 今天进入新的功能开发了:通讯卫士, ...

  5. Android学习——实现简单的电话拨号

    Android学习--实现简单的电话拨号 新建工程 1.编辑界面 2.编辑MainActivity 3.编辑权限 新建工程 1.编辑界面 设置为线性布局.输入框提示(输入类型为数字).添加图片按钮 & ...

  6. android 关闭蓝牙打电话功能,Android蓝牙开发【八】hfp接听、挂断电话

    继续研究hfp相关功能.蓝牙耳机可以控制手机接听.拒接.挂断电话,拨打电话等功能.本文主要分析下起这些操作的大致流程. 在系统应用Bluetooth中com_android_bluetooth.cpp ...

  7. Android 蓝牙开发(八)hfp接听、挂断电话

    转载请注明出处:http://blog.csdn.net/vnanyesheshou/article/details/71429860 本文已授权微信公众号 fanfan程序媛 独家发布 扫一扫文章底 ...

  8. 设置小米5手机拒接中介骚扰标志的电话

    iamlaosong文 设置中的防打扰可以设置某段时间内(或者所有时间)拒接电话,防打扰期间可以设置接听某些电话,如通信录中的电话.3分钟内重复来电等,但这个不能达到防骚扰的目的,黑名单可以拦截一些指 ...

  9. android学习笔记1

    adb 常用命令 adb device  adb kill-server adb start-server adb install adb uninstall adb pull  adb push  ...

最新文章

  1. 清华 CVer 对自监督学习的一些思考
  2. 隐式转换和显式转换及强制转换的区别
  3. 如何对单手和双手协同运动方向进行神经表征和解码?北理工研究团队给出了相关方案
  4. HDU 2564 饭卡
  5. TCP连接的建立(二)
  6. 与登录shell相关的文件
  7. wps的计算机在哪里设置密码,wps文件怎么设置和取消密码 wps文件密码设置和取消的步骤方法...
  8. 【OpenCV 例程200篇】64. 图像锐化——Sobel 算子
  9. verilog实现多周期处理器之——(零)GUN工具链的安装
  10. MySQL8.0.14 - 新特性 - InnoDB Parallel Read简述 1
  11. Android内存优化之——static使用篇
  12. Kepware与C#
  13. 2022年蓝桥杯基础题目合集C语言
  14. AUTOCAD——矩形命令
  15. 内存不能为read或written的解决方案
  16. python数据框提取子集_pandas 数据子集的获取
  17. 申宝在线炒股医药板块大涨
  18. 《空号》:聊聊我在阿里外包3个月学到了什么。。。
  19. 当Docker运行碰上“连接被重置”
  20. TLE5012B_SPI通讯+零点矫正思路总结

热门文章

  1. 【技术解析】模型量化压缩
  2. 【python3数据结构】Dijkstra’s算法(搜索最短路径问题)
  3. Qt使用poppler读取pdf
  4. matlab周群益,MATLAB可视化大学物理学
  5. Stone的txl数
  6. 前端实现一个简单的计算器
  7. 此计算机核心参数,如何看懂电脑CPU的性能参数?看完这篇就会了
  8. 数据分析体系是什么,该如何搭建?
  9. 程序运行时崩溃生成崩溃文件(Windows Linux)
  10. 华为nova3e怎么分屏_华为荣耀8x怎么分屏华为荣耀8x分屏教程