You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 06:24:47