上一篇
安卓实现 短信验证功能
- 行业动态
- 2025-04-21
- 5
功能需求分析
实现短信验证功能需要完成以下核心流程:
- 用户输入手机号并点击获取验证码
- 前端向服务器发送请求生成验证码
- 服务器通过短信网关发送验证码到用户手机
- 自动读取短信中的验证码并填充到输入框
- 用户提交验证码进行校验
实现步骤与代码示例
配置AndroidManifest权限
<uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
动态申请运行时权限(Android 6.0+)
// 在Activity中添加权限申请逻辑 if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECEIVE_SMS}, REQUEST_CODE); }
创建验证码获取按钮(带倒计时)
public class SmsVerifyActivity extends AppCompatActivity { private Button btnGetCode; private EditText etPhone, etCode; private CountDownTimer timer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化视图组件... btnGetCode.setOnClickListener(v -> { String phone = etPhone.getText().toString(); if (validatePhone(phone)) { startCountdown(); sendVerificationCode(phone); } }); } private void startCountdown() { timer = new CountDownTimer(60000, 1000) { @Override public void onTick(long millisUntilFinished) { btnGetCode.setText(millisUntilFinished / 1000 + "s"); btnGetCode.setEnabled(false); } @Override public void onFinish() { btnGetCode.setText("重新获取"); btnGetCode.setEnabled(true); } }.start(); } }
发送验证码请求(集成第三方SDK示例)
服务商 | 调用方式 | 备注 |
---|---|---|
阿里云短信服务 | AliyunSmsClient.sendSms(...) |
需配置AccessKey |
酷盾安全短信 | QCloudSmsClient.sendVerifyCode(...) |
支持模板短信 |
第三方SDK(如Mob) | MobSDK.getVerificationCode(...) |
集成多家通道 |
// 通用HTTP请求示例(以OkHttp为例) private void sendVerificationCode(String phone) { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.yourservice.com/sms/send?phone="+phone) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { runOnUiThread(() -> Toast.makeText(..., "发送失败", ...).show()); } @Override public void onResponse(Call call, Response response) throws IOException { // 处理响应结果... } }); }
自动读取短信验证码
// 定义BroadcastReceiver public class SmsReceiver extends BroadcastReceiver { private SmsVerifyActivity activity; public SmsReceiver(SmsVerifyActivity activity) { this.activity = activity; } @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Telephony.Sms.Intents.GET_SMS_RECEIVER_ACTION.equals(action)) { Bundle bundle = intent.getExtras(); Object[] pdus = (Object[]) bundle.get("pdus"); for (Object pdu : pdus) { SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu); String message = sms.getMessageBody(); // 解析短信内容提取验证码(需根据实际短信格式调整正则) String code = extractCodeFromMessage(message); if (code != null) { activity.runOnUiThread(() -> activity.etCode.setText(code)); } } } } private String extractCodeFromMessage(String message) { // 示例正则表达式(需根据实际情况调整) Pattern pattern = Pattern.compile("\d{6}"); Matcher matcher = pattern.matcher(message); return matcher.find() ? matcher.group() : null; } }
注册短信接收器
// 在Activity的onStart方法中注册 @Override protected void onStart() { super.onStart(); IntentFilter filter = new IntentFilter(Telephony.Sms.Intents.GET_SMS_RECEIVER_ACTION); registerReceiver(new SmsReceiver(this), filter); } // 在onStop中注销 @Override protected void onStop() { super.onStop(); unregisterReceiver(smsReceiver); }
验证验证码(提交到服务器)
private void verifyCode(String phone, String code) { OkHttpClient client = new OkHttpClient(); RequestBody body = new FormBody.Builder() .add("phone", phone) .add("code", code) .build(); Request request = new Request.Builder() .url("https://api.yourservice.com/sms/verify") .post(body) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { runOnUiThread(() -> Toast.makeText(..., "验证失败", ...).show()); } @Override public void onResponse(Call call, Response response) throws IOException { // 处理验证结果... } }); }
注意事项与优化建议
- 权限处理:Android 13+需要特别注意短信读取权限的变化,建议使用
SmsManager
替代直接读取短信数据库的方式 - 安全措施:
- 限制验证码有效时间(如5分钟)
- 限制重试次数(如每天最多10次)
- 后端校验IP/设备指纹防好评
- 兼容性处理:不同厂商短信格式差异大,建议同时支持正则匹配和关键词截取两种方式提取验证码
- 用户体验优化:
- 显示短信发送进度条
- 自动聚焦到验证码输入框
- 提供语音验证码选项
- 错误处理:需处理以下异常场景:
- 网络不可用时的本地提示
- 短信网关返回错误码(如余额不足)
- 多次快速获取验证码的去重处理
相关问题与解答
Q1:为什么在Android 13+设备上无法读取短信内容?
A1:从Android 13开始,系统加强了隐私保护,默认情况下应用无法直接读取其他应用的短信内容,解决方案:
- 使用
SmsManager
的createAppSpecificSmsToken
方法申请专用令牌 - 引导用户在设置中为应用开启”允许访问高级短信权限”
- 改用官方推荐的
SmsCallback
机制接收短信(需运营商支持)
Q2:如何提高验证码自动填充的成功率?
A2:可采取以下优化措施:
- 多规则匹配:同时使用正则表达式、关键词定位、时间窗口过滤等多种方式提取验证码校验:验证提取内容是否符合预期格式(如纯数字6位)
- 防抖处理:在收到短信后延迟2秒再执行填充操作,避免信号延迟导致的漏检
- 多通道监听:同时监听短信广播和剪贴板变化(部分用户会手动复制验证码