实现短信验证功能需要完成以下核心流程:
<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" />
// 在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(); } }
服务商 | 调用方式 | 备注 |
---|---|---|
阿里云短信服务 | 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 { // 处理验证结果... } }); }
SmsManager
替代直接读取短信数据库的方式Q1:为什么在Android 13+设备上无法读取短信内容?
A1:从Android 13开始,系统加强了隐私保护,默认情况下应用无法直接读取其他应用的短信内容,解决方案:
SmsManager
的createAppSpecificSmsToken
方法申请专用令牌SmsCallback
机制接收短信(需运营商支持)Q2:如何提高验证码自动填充的成功率?
A2:可采取以下优化措施: