拦截关键:
短信广播为有序广播,按优先级依次接收,如果接收器有abort操作,则后面接收器就收不到广播了。
1、要动态注册短信接收广播监听器。如果把监听配置在清单文件中,拦截效果不如动态注册好
2、设置接收优先级最高,可保证最先接到广播。
广播接收优先级 :谁的权限大谁先收到;先动态后静态;都是动态优先级也相同的,谁先注册谁先收到。
如果还收不到,那估计就是被360 或者金山给拦了,不清楚他们是那种方式拦截的,反正比这个高。
权限
<uses-permission android:name="android.permission.RECEIVE_SMS" />
public class SmsInterceptor {
private final static String ACTION_SMS_BROADCAST="android.provider.Telephony.SMS_RECEIVED";
String [] interceptNumber;
String [] interceptWords;
MySmsReceiver myReceiver;
public SmsInterceptor (Context _context){
this.context = _context;
}
* 注册短信广播拦截
*/
public void regInterceptSms(){
IntentFilter filter = new IntentFilter(ACTION_SMS_BROADCAST);
filter.setPriority(2147483647);//Integer.MAX_VALUE);
filter.addCategory("android.intent.category.DEFAULT");
myReceiver= new MySmsReceiver ();
Log.v(TAG,"启动短信拦截监听 ,权限"+Integer.MAX_VALUE);
Intent localIntent = context.registerReceiver(myReceiver, filter);
}
/**
* 取消短信广播拦截注册
*/
public void unregisterListen() {
Log.d(TAG,"注销短信广播拦截");
if(myReceiver!=null)context.unregisterReceiver(myReceiver);
myReceiver= null;
}
* 短信广播拦截类
* @author Administrator
*
*/
public class MySmsReceiver extends BroadcastReceiver {
private String TAG = "MySmsReceiver ";
@Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "拦截处理");
//拦截短信
if(ACTION_SMS_BROADCAST.equalsIgnoreCase(intent.getAction())){
// 第一步、获取短信的内容和发件人
StringBuilder body = new StringBuilder();// 短信内容
StringBuilder number = new StringBuilder();// 短信发件人
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] _pdus = (Object[]) bundle.get("pdus");
SmsMessage[] message = new SmsMessage[_pdus.length];
for (int i = 0; i < _pdus.length; i++) {
message[i] = SmsMessage.createFromPdu((byte[]) _pdus[i]);
}
for (SmsMessage currentMessage : message) {
body.append(currentMessage.getDisplayMessageBody());
number.append(currentMessage.getDisplayOriginatingAddress());
}
String smsBody = body.toString();
String smsNumber = number.toString();
if (smsNumber.contains("+86")) {
smsNumber = smsNumber.substring(3);
}
// 第二步:确认该短信内容是否满足过滤条件
boolean flags_filter ;
Log.d(TAG,"短信"+smsNumber+smsBody);
flags_filter = handleSms(smsNumber,smsBody);
/* // 第三步:取消广播
if (flags_filter) {
Log.d(TAG, "拦截到短信");
this.abortBroadcast();
} */
}
}
Log.v(TAG, "拦截处理结束");
}
public void abort(){
this.abortBroadcast();
}
}
/**
* 判断是否拦截。判断是否在拦截号码或关键字中
* @param phoneNumber
* @param smsContent
* @return
*/
private boolean handleSms(String phoneNumber,String smsContent){
if(isNeedIntercept(phoneNumber, smsContent)){
//取消广播
Log.d(TAG, "拦截处理-取消广播");
if(ylSmsService !=null)ylSmsService.abortBroadcast();
return true;
}else {
return false;
}
}
/**
* 设置拦截规则
*/
public void setInterceptRule( String [] number ,String [] keywords){
this.interceptNumber=number;
this.interceptWords=keywords;
}
/**
* 是否在拦截关键字中
* @param phoneNumber
* @param smsContent
* @return
*/
private boolean isNeedIntercept(String phoneNumber,String smsContent){
boolean isIn = false;
if(isContains(interceptNumber,phoneNumber ,true)){
isIn = true;
break;
}else if (isContains(interceptWords,smsContent ,false)){
isIn = true;
break;
}
return isIn;
}
/**
* 判断数组是否包含 查找字符串 ,其中 isEqual 为true 表示源字符串字符串和查找字符串完全一样才算匹配,false表示源字符串包含查找字符串就算匹配。
* @param src
* @param target
* @param isEqual
* @return
*/
private boolean isContains(String [] src ,String target){
return isContains(src,target,true);
}
private boolean isContains(String [] src ,String target ,boolean isEqual){
boolean isIn = false;
if(target ==null || src ==null || src.length==0)return isIn;
for(String tmp:src){
if(isEqual && tmp.equalsIgnoreCase(target)){
isIn =true ;
break;
} else if(!isEqual && target.indexOf(tmp) != -1 ){
isIn = true;
break;
}
}
return isIn;
}
}