One-Tap短信验证异常:SmsBroadcastReceiver未收到SMS回调
一键短信验证SmsBroadcastReceiver未触发问题排查
我参照官方文档实现一键短信验证功能,发送短信后自定义的SmsBroadcastReceiver的onReceive方法未被触发。使用Android模拟器测试,不确定Receiver配置、手机号格式是否合规,或是存在其他遗漏配置。需求是无需在Manifest中添加额外权限,实现接收短信验证码并完成解析、传递的功能。
排查要点
- Receiver注册权限:动态注册时传入的
SmsRetriever.SEND_PERMISSION需确保正确,该权限为系统特殊权限,无需在Manifest声明,但注册参数不能出错。 - 发送方号码格式:
startSmsUserConsent传入的号码必须符合E.164标准(如+16505556789,不能包含空格、横杠),测试时要保证发送短信的号码与传入值完全匹配,也可传null接收所有号码的短信。 - 短信内容规范:短信必须以
<#>开头,以[你的应用包名]结尾,例如:<#> 你的验证码是123456 [com.example.yourapp],不符合格式的短信不会被SmsRetriever识别。 - 模拟器测试限制:需在调用
startSmsUserConsent后的5分钟内发送短信,超时会触发TIMEOUT;部分模拟器对SmsRetriever支持有延迟,可适当等待或重启模拟器。 - Receiver生命周期:动态注册的Receiver需在Activity销毁时调用
unregisterReceiver避免内存泄漏,当前代码在onCreate注册,需确保注册状态正常。
实现代码
class MainActivity : AppCompatActivity() { object Constants { const val RESOLVE_HINT = 0 const val CREDENTIAL_PICKER_REQUEST = 1 const val SMS_CONSENT_REQUEST = 2 } private val smsVerificationReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) { val extras = intent.extras val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as Status when (smsRetrieverStatus.statusCode) { CommonStatusCodes.SUCCESS -> { // 获取授权意图 val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT) try { // 启动授权弹窗,需在5分钟内启动,否则会触发TIMEOUT startActivityForResult(consentIntent, SMS_CONSENT_REQUEST) } catch (e: ActivityNotFoundException) { // 处理异常 } } CommonStatusCodes.TIMEOUT -> { // 处理超时错误 } } } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION) registerReceiver( smsVerificationReceiver, intentFilter, SmsRetriever.SEND_PERMISSION, Handler(Looper.getMainLooper()) ) } override fun onResume() { super.onResume() startSMSRetreiver(this) } private fun startSMSRetreiver(activity: Activity) { val smsRetreiver = SmsRetriever.getClient(activity) smsRetreiver.startSmsUserConsent("+16505556789") // +1-555-521-5554 模拟器手机号 // +16505556789 发送方号码(E.164格式) // 传null可接收任意号码的短信 } // 处理授权结果 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { SMS_CONSENT_REQUEST -> if (resultCode == Activity.RESULT_OK && data != null) { // 获取短信内容 val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE) // 解析一次性验证码 val oneTimeCode = parseOneTimeCode(message) // 将验证码发送到服务器 } else { // 用户拒绝授权,可引导手动输入验证码 } } } private fun parseOneTimeCode(message: String?): String? { return message } }
内容的提问来源于stack exchange,提问作者Vancore
相关产品推荐
相关产品推荐

