1.短信拦截
首先需要声明的是,Android4.4版本以上,如果想做到短信拦截,必须成为default sms,把所有短信相关的功能都包揽了,然后再做短信拦截。但这种做法,适配性和兼容性的工作是非常巨大的,短信、wapush(多种)、彩信、单双卡等等,相当于要求短信拦截类的软件要集成一个功能非常完善的通讯录类应用的功能。但是即使拦截不到短信,同样是可以接收到短信的内容。4.4版本以前没有问题。
短信广播接收者就不用多说了,代码如下所示,业务逻辑一般通过数据库查询实现,通过继承SQLiteOpenHelper类构建数据库,再自定义一个提供数据库增删改查的Dao类即可。
private class InnerSmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Object[] objs = (Object[]) intent.getExtras().get("pdus");
for (Object obj : objs) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
String sender = smsMessage.getOriginatingAddress();
Log.i("InnerSmsReceiver","收到了来自这个人的短信:"+sender);
//通过业务逻辑判断是否拦截sender By abortBroadcast();
}
}
}
2.电话拦截/接听
2.1 拦截电话,首先需要监听电话的状态。这个我们最好还是写在服务里吧。
public class InterceptService extends Service{
private TelephonyManager tm;
private MyListener listener;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
//实例化电话监听器
listener = new MyListener();
tm =(TelephonyManager)getSystemService(TELEPHONY_SERVICE);
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
super.onCreate();
}
@Override
public void onDestroy() {
tm.listen(listener,PhoneStateListener.LISTEN_NONE);//什么也不监听
super.onDestroy();
}
private class MyListener extends PhoneStateListener{
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_RINGING: //零响状态
Log.i("InnerSmsReceiver",incomingNumber);
endCall(); //根据业务逻辑判断后调用挂断电话的逻辑
break;
}
}
}
}
2.1 拦截电话的逻辑可以仿照源码写。首先拿到Binder对象。
IBinder ibinder = ServiceManager.getService(TELEPHONY_SERVICE);
2.2 由于ServiceManager被系统隐藏了,所以可以用反射的方法拿到。
Class clazz = InterceptService.class.getClassLoader().loadClass("android.os.ServiceManager");
Method method = clazz.getDeclaredMethod("getService", String.class);
IBinder ibinder = (IBinder) method.invoke(null, TELEPHONY_SERVICE);
2.3 接着就可以调用Binder里的方法了。不仅可以拿到endCall()挂断电话的方法,也可以拿到answerRingCall()接听电话的方法。这样就完成了整个挂断电话的逻辑。
ITelephony.Stub.asInterface(ibinder).endCall();
//用于接听电话 ITelephony.Stub.asInterface(ibinder).answerRingingCall();