前段时间做了一个简单的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中注册:
12 3 74 5 6
增加权限:
12 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 Classc = 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 }
网上这种方法介绍的有很多,我这里记录一下,方便以后自己查找。有不足之处,欢迎指正!