這段時間太忙了,以至于一直沒有時間更新博客。正好今天公司項目需要加入自動識別驗證碼的功能,所以特此記錄一下
現(xiàn)在幾乎任何App注冊都離不開手機號,如果選擇使用手機號注冊,必定會接收并填入驗證碼進行注冊。一些注重用戶體驗的App會在收到驗證碼后自動幫用戶填入,免去了用戶手動輸入驗證碼的煩惱,整個注冊過程用戶是非常Happy的。
下面我們來實現(xiàn)這個功能,其實邏輯流程很簡單:
- 創(chuàng)建廣播接收器,攔截短信
- 判斷是不是本應用需要的驗證碼短信,若是便繼續(xù),否則忽略
- 提取驗證碼,通過回調接口返回給Activity/Fragment
第一步:創(chuàng)建廣播接收器
由于我們只需要在注冊界面對短信進行攔截,因此采用動態(tài)注冊的方式。首先編寫廣播接收器:
public class SMSBroadcastReceiver extends BroadcastReceiver {
public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
//回調接口
private OnAuthCodeReceiver mOnAuthCodeReceiver;
//利用正則表達式預編譯功能
private static final Pattern AUTH_CODE_PATTERN = Pattern.compile("\\d{6}");
//識別是否是本APP需要的驗證碼短信的關鍵字
private final String SMS_KEYWORD = "小豬科技";
@Override
public void onReceive(Context context, Intent intent) {
if (SMS_RECEIVED_ACTION.equals(intent.getAction()) &&
intent.getExtras() != null) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
String format = intent.getStringExtra("format");
SmsMessage smsMessage = null;
for (Object pdu : pdus) {
if (Build.VERSION.SDK_INT < 23) {
smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
} else {
smsMessage = SmsMessage.createFromPdu((byte[]) pdu, format);
}
}
if (smsMessage == null) {
return;
}
String content = smsMessage.getDisplayMessageBody();
if (content.contains(SMS_KEYWORD) && mOnAuthCodeReceiver != null) {
mOnAuthCodeReceiver.onReceiver(getAuthCode(content));
abortBroadcast();
}
}
}
private String getAuthCode(String content) {
Matcher matcher = AUTH_CODE_PATTERN.matcher(content);
if (matcher.find()) {
return matcher.group();
} else {
return "";
}
}
public void setOnAuthCodeReceiverListener(OnAuthCodeReceiver receiver) {
this.mOnAuthCodeReceiver = receiver;
}
public interface OnAuthCodeReceiver {
void onReceiver(String code);
}
}
以上代碼都是一些常規(guī)獲取短信內容的操作,沒有什么技術含量,唯一注意一下就是這個正則獲取的是6位數(shù)的驗證碼。
第二步:動態(tài)注冊廣播
在注冊界面,動態(tài)注冊廣播,并在注冊界面銷毀時,解除注冊:
public class RegisterActivity extends AppCompatActivity {
private EditText etAuthCode;
private SMSBroadcastReceiver mSMSBroadcastReceiver = new SMSBroadcastReceiver();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
etAuthCode = findViewById(R.id.et_auth_code);
registerSMSReceiver();
}
private void registerSMSReceiver() {
IntentFilter intentFilter =
new IntentFilter(SMSBroadcastReceiver.SMS_RECEIVED_ACTION);
intentFilter.setPriority(Integer.MAX_VALUE);
registerReceiver(mSMSBroadcastReceiver, intentFilter);
mSMSBroadcastReceiver.setOnAuthCodeReceiverListener(
code -> etAuthCode.setText(code)
);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mSMSBroadcastReceiver);
}
}
最后別忘了在清單文件中加入權限:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>