我们来详细讲解“Android自定义控件实现短信验证码自动填充”的完整攻略。本攻略带有两条示例说明。
1. 实现思路
实现短信验证码自动填充的思路如下:
-
创建一个自定义控件,继承自EditText。
-
在该控件中添加一个倒计时按钮,用于触发发送短信验证码。
-
在控件通过监听短信的方式自动填充短信验证码到EditText中。
-
控制短信验证码填充后,自动跳转到下一个输入框。
2. 示例一
这里提供一种基于 BroadcastReceiver 实现自动填充短信验证码的示例。
2.1 创建自定义控件
首先创建一个自定义控件,继承自EditText,添加倒计时按钮:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/et_code"
android:textSize="20sp"
android:hint="输入验证码"
android:inputType="number"
android:textColorHint="@color/color_code_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"/>
<Button
android:id="@+id/btn_code"
android:text="获取验证码"
android:textSize="20sp"
android:textColor="@color/color_code_btn"
android:background="@drawable/btn_bg_code"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"/>
</RelativeLayout>
2.2 注册 BroadcastReceiver
在自定义控件中注册 BroadcastReceiver,用于监听短信:
private void registerReceiver() {
IntentFilter intentFilter = new IntentFilter(SMS_RECEIVED_ACTION);
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SMS_RECEIVED_ACTION)) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
String code = getCodeFromMessage(pdus);
if (!TextUtils.isEmpty(code)) {
etCode.setText(code);
etCode.setSelection(code.length());
clearFocus();
etCode.clearFocus();
}
}
}
}
};
getContext().registerReceiver(broadcastReceiver, intentFilter);
}
2.3 解析收到的短信
在 BroadcastReceiver 中解析收到的短信中的验证码:
private String getCodeFromMessage(Object[] pdus) {
String code = "";
for (Object pdu : pdus) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
String body = smsMessage.getMessageBody();
Pattern pattern = Pattern.compile("\\d{6}");
Matcher matcher = pattern.matcher(body);
if (matcher.find()) {
code = matcher.group(0);
}
}
return code;
}
2.4 发送短信验证码
在控件中添加倒计时按钮并实现发送短信验证码功能:
btnCode.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
countDown();
sendCode();
}
});
private void sendCode() {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNumber, null, messageContent, null, null);
}
2.5 注销 BroadcastReceiver
最后在自定义控件销毁时注销 BroadcastReceiver:
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (broadcastReceiver != null) {
getContext().unregisterReceiver(broadcastReceiver);
}
}
3. 示例二
这里提供一种基于 Service 实现自动填充短信验证码的示例,相对来说比 BroadcastReceiver 适用范围更广。
3.1 创建Service
首先创建一个继承自 Service 的类,用于监听短信并通过广播发送给自定义控件:
public class SmsService extends Service {
private SmsReceiver smsReceiver;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
smsReceiver = new SmsReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsReceiver, intentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(smsReceiver);
}
private class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
if (pdus != null) {
for (Object pdu : pdus) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
String body = smsMessage.getMessageBody();
String sender = smsMessage.getOriginatingAddress();
if (sender.equals("106xxxxxxx")) {
Intent codeIntent = new Intent("code");
codeIntent.putExtra("code", getCodeFromMessage(body));
sendBroadcast(codeIntent);
}
}
}
}
}
private String getCodeFromMessage(String body) {
String code = "";
Pattern pattern = Pattern.compile("\\d{6}");
Matcher matcher = pattern.matcher(body);
if (matcher.find()) {
code = matcher.group(0);
}
return code;
}
}
}
3.2 执行 Service
在自定义控件中执行 Service:
btnCode.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
countDown();
Intent intent = new Intent(getContext(), SmsService.class);
startService(intent);
}
});
3.3 监听广播
在自定义控件中监听广播并填充短信验证码:
private BroadcastReceiver codeReceiver;
private void registerReceiver() {
codeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String code = intent.getStringExtra("code");
if (!TextUtils.isEmpty(code)) {
etCode.setText(code);
etCode.setSelection(code.length());
clearFocus();
etCode.clearFocus();
}
}
};
IntentFilter filter = new IntentFilter("code");
getContext().registerReceiver(codeReceiver, filter);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (codeReceiver != null) {
getContext().unregisterReceiver(codeReceiver);
}
}
4. 总结
本文给出了两种示例,分别是基于 BroadcastReceiver 和 Service 实现自动填充短信验证码。其中,基于 BroadcastReceiver 的实现比较简单,但是仅能在应用前台或者 Activity 可见时使用;基于 Service 的实现比较复杂,但是可以在应用后台或者 Activity 不可见时使用。根据项目需求和实现难度的不同,选择合适的方式实现自动填充短信验证码。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android自定义控件实现短信验证码自动填充 - Python技术站