博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android学习小记-----拦截电话/拒接电话,规避拒接电话前响一声或者两声的问题...
阅读量:6802 次
发布时间:2019-06-26

本文共 9173 字,大约阅读时间需要 30 分钟。

  前段时间做了一个简单的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     @Override13     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_CHANGED25             //监听电话状态的改变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 
2
3
4
5
6
7

增加权限:

1  
2
3

 

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
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 @Override111 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
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 screen17      *18      * @return whether it hung up19      */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

你可能感兴趣的文章
智能家居监控移动手机组态现实生活中的应用
查看>>
笔试题、面试题
查看>>
shell 数组
查看>>
Linux操作系统的安装
查看>>
服务器RAID
查看>>
python函数是引用传递(对可变对象而言)
查看>>
Cisco ASA防火墙简易配置与调试手册
查看>>
Node.js搭建聊天室
查看>>
Rob Pike的5个编程原则
查看>>
Expression Blend实例中文教程(7) - 动画基础快速入门Animation
查看>>
《第一行代码》1day~了解全貌
查看>>
复习javaIO 之File类
查看>>
How to install snmpwalk snmpget on CentOS 6.4 6.3 5.9 Redhat RHEL Fedora
查看>>
最小生成树
查看>>
Mybatis中配置Mapper的方法
查看>>
Java基础学习总结(19)——Java环境变量配置
查看>>
Mvc5+Entity Framework6 之二----在MVC中用Entity Framework实现基本的CRUD
查看>>
我的友情链接
查看>>
大型网站技术架构(四)网站的高性能架构
查看>>
linux系统修改SSH最大连接数,修改nofile,nproc参数方法
查看>>