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

SMSRetriever API广播接收器仅触发一次,后续消息无响应问题咨询

SMS Retriever API 接收器单次触发后的重新注册方案

是的,SMS Retriever API的广播接收器在成功接收第一条符合格式的短信后,会自动注销——这是API的设计逻辑,它本身是为单次OTP验证场景设计的,并非持续监听短信。要处理后续消息,只需在每次接收完成后主动重新注册监听会话即可,无需重启应用。

具体实现步骤

  1. 封装监听启动逻辑
    把注册SMS Retriever和广播接收器的逻辑封装成可复用的方法,方便重复调用:
// 在Activity或ViewModel中封装(示例为Activity)
private fun startSmsRetrieverSession() {
    val smsClient = SmsRetriever.getClient(this)
    val task = smsClient.startSmsRetriever()

    task.addOnSuccessListener {
        // 动态注册广播接收器(Android 12+需指定export属性)
        val receiver = SMSBroadcastReceiver()
        val filter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
        registerReceiver(receiver, filter, RECEIVER_EXPORTED)
        Log.d("SMSRetriever", "新监听会话已启动")
    }

    task.addOnFailureListener {
        Log.e("SMSRetriever", "监听会话启动失败: ${it.localizedMessage}")
    }
}
  1. 接收短信后自动重启监听
    在你的SMSBroadcastReceiver的onReceive方法中,处理完OTP解析逻辑后,调用上面的方法重新启动监听:
class SMSBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        intent ?: return
        if (SmsRetriever.SMS_RETRIEVED_ACTION != intent.action) return

        val status = intent.extras?.get(SmsRetriever.EXTRA_STATUS) as? Status ?: return
        when (status.statusCode) {
            CommonStatusCodes.SUCCESS -> {
                // 解析并处理OTP短信
                val smsContent = intent.extras?.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String
                val otp = extractOtpFromSms(smsContent) // 自定义解析方法
                fillOtpToInputField(otp) // 填充到输入框

                // 重启监听会话,准备接收下一条短信
                (context as YourActivity).startSmsRetrieverSession()
            }
            CommonStatusCodes.TIMEOUT -> {
                // 超时也可以重启监听,避免用户需要手动触发
                (context as YourActivity).startSmsRetrieverSession()
            }
        }
    }

    // 示例OTP解析方法
    private fun extractOtpFromSms(sms: String): String {
        val pattern = Regex("\\d{6}") // 匹配6位数字OTP
        return pattern.find(sms)?.value ?: ""
    }
}
  1. 生命周期适配(可选)
    为了避免内存泄漏和确保页面可见时监听有效,可在Activity的生命周期方法中补充逻辑:
override fun onResume() {
    super.onResume()
    // 页面恢复时重启监听,确保监听状态正常
    startSmsRetrieverSession()
}

override fun onPause() {
    super.onPause()
    // 页面暂停时注销接收器,避免内存泄漏
    try {
        unregisterReceiver(SMSBroadcastReceiver())
    } catch (e: IllegalArgumentException) {
        // 接收器未注册时忽略异常
        Log.d("SMSRetriever", "接收器已注销")
    }
}

关键注意事项

  • 优先使用动态注册接收器,静态注册的接收器在API自动注销后无法通过简单调用重新激活,灵活性不足。
  • 每次调用startSmsRetriever()都会创建一个新的5分钟有效期监听会话,超时后会触发TIMEOUT回调,可在此时重新启动。
  • 确保每条短信都包含符合要求的应用哈希码,否则无法被API识别。

内容的提问来源于stack exchange,提问作者tallTrees

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:50:03