實現短信監聽要用到廣播,這里我在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 停止服務前台運行
