通過監聽短信和正則表達式實現自動填寫短信驗證碼


 

實現短信監聽要用到廣播,這里我在Service里面注冊這個廣播

 

在activity里面啟動service

intent = new Intent(MainActivity.this, SmsService.class);

intent.putExtra("cmd", 1);
startService(intent);

 

 

接下來看 service

在service的onCreate方法中 通過startForeground  讓服務前台運行

在 onStartCommand方法中 接受到 activity 啟動監聽的指令,注冊接收者

要注意優先級要盡量設高, Action為

android.provider.Telephony.SMS_RECEIVED

在廣播接受者的 onReceive方法  9-19行 取出需要的短信信息

拿到短信內容后,就可以進行驗證碼匹配

 

舉兩個驗證碼短信例子

【百度】您在百度開發者中心進行的手機驗證的驗證碼為:313253,請輸入后進行驗證,謝謝![百度開發者中心]
【嗶哩嗶哩】951422 為你的手機綁定驗證碼,請在5分鍾內完成手機綁定。如非本人操作,請忽略或回復T退訂。

 

通常手機接受到的驗證碼都是 4位或者6位的純數字

可以用  \d{4,6}(?!\d)   , 紅色部分 表示 4到6位的數字,粉色表示后面不能為數字,其實這個可有可無

 

如果遇到的是 數字字母混合的

可以用 [A-Za-z0-9]{4,}(?![A-Za-z0-9])   紅色部分表示符合 A到Z a到z 0到9的這個類型 的字符,粉色表示四位以上 ,后面同上

沒有使用\w 是因為\w 還可以代表漢字

 

^((https|http)?:\/\/)[^\s]+[jpg]

圖片地址例子 

 

對於不同的短信驗證碼模板,肯定有不同的方法,我寫的只是一種思路,不可能所有都適用,如果收到一條國外的驗證碼短信,就不是上面那么簡單了

 

  1 public class SmsService extends Service {
  2 
  3     private NotificationManager manger;
  4     public static NotificationCompat.Builder builder;
  5     private BroadcastReceiver receiver = new BroadcastReceiver() {
  6         @Override
  7         public void onReceive(Context context, Intent intent) {
  8 
  9             SmsMessage msg = null;
 10             Bundle bundle = intent.getExtras();
 11             if (bundle != null) {
 12                 Object[] pdusObj = (Object[]) bundle.get("pdus");
 13                 for (Object p : pdusObj) {
 14                     msg = SmsMessage.createFromPdu((byte[]) p);
 15                     String msgTxt = msg.getMessageBody();//得到消息的內容
 16                     Date date = new Date(msg.getTimestampMillis());//時間
 17                     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 18                     String receiveTime = format.format(date);
 19                     String senderNumber = msg.getOriginatingAddress();
 20                     //Toast.makeText(context, "發送人:" + senderNumber + "  短信內容:" + msgTxt + "接受時間:" + receiveTime, Toast.LENGTH_LONG).show();
 21 
 22 
 23                     //   \d{4,6}(?!\d)
 24                     // [A-Za-z0-9]{4,}(?![A-Za-z0-9])
 25                     Pattern pattern=Pattern.compile("[A-Za-z0-9]{4,}(?![A-Za-z0-9])");
 26                     Matcher matcher=pattern.matcher(msgTxt);
 27                     if (matcher.find()){
 28                         String code=matcher.group(0);
 29                         Toast.makeText(context,"驗證碼是 "+code,Toast.LENGTH_LONG).show();
 30                         context.sendBroadcast(new Intent().setAction("yzm").putExtra("code",code));
 31                         createNotification(code);
 32                     }
 33                     return;
 34                 }
 35                 return;
 36             }
 37         }
 38     };
 39 
 40     private void createNotification(String code) {
 41         NotificationCompat.Builder builder=new NotificationCompat.Builder(this);
 42         builder.setSmallIcon(R.mipmap.ic_launcher);
 43         builder.setAutoCancel(true);
 44         builder.setContentTitle("收到驗證碼 "+code);
 45 
 46         Intent[] intents = new Intent[2];
 47         intents[0]=Intent.makeRestartActivityTask(new ComponentName(this,MainActivity.class));
 48         intents[1]=new Intent(this,CodeActivity.class);
 49         intents[1].putExtra("code",code);
 50 
 51         PendingIntent pendingIntent = PendingIntent.getActivities(this, 0, intents, PendingIntent.FLAG_UPDATE_CURRENT);
 52         builder.setContentIntent(pendingIntent);
 53 
 54         Notification notification = builder.build();
 55         manger.notify(666, notification);
 56     }
 57 
 58 
 59     @Nullable
 60     @Override
 61     public IBinder onBind(Intent intent) {
 62         return null;
 63     }
 64 
 65     @Override
 66     public void onCreate() {
 67         super.onCreate();
 68         manger = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
 69         builder = new NotificationCompat.Builder(this);
 70 
 71         builder.setSmallIcon(R.mipmap.ic_launcher);
 72         builder.setAutoCancel(true);
 73         builder.setContentTitle("sms listening");
 74 
 75         Intent intent = new Intent(this, MainActivity.class);
 76         PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
 77         builder.setContentIntent(pendingIntent);
 78 
 79         Notification notification = builder.build();
 80         //manger.notify(333, notification);
 81         startForeground(333, notification);
 82 
 83     }
 84 
 85     @Override
 86     public int onStartCommand(Intent intent, int flags, int startId) {
 87         int i = intent.getExtras().getInt("cmd");
 88         if (1 == i) {
 89             initReceiver();
 90         } else {
 91             stopForeground(true);
 92         }
 93         return super.onStartCommand(intent, flags, startId);
 94     }
 95 
 96 
 97     private void initReceiver() {
 98         IntentFilter intentFilter = new IntentFilter();
 99         intentFilter.setPriority(1000);
100         intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
101         registerReceiver(receiver, intentFilter);
102     }
103 
104     @Override
105     public void onDestroy() {
106         super.onDestroy();
107         unregisterReceiver(receiver);
108         stopForeground(true);
109     }
110 }

 

最后拿到驗證碼之后,從service里面發送廣播,activity里面注冊接收者,拿到驗證碼,填充給 EditText,當然也可以用EventBus

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            switch (intent.getAction()) {
                case "yzm":
                    editText.setText(intent.getExtras().getString("code"));
                    break;
            }
        }
    };

 

如果想停止service,應該在service的onDestroy方法中

unregisterReceiver    注銷短信接收者

stopForeground      停止服務前台運行

 

正則學習       調試網址

 

github


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM