SMS检索器API Android系统无法将消息发送给广播接收器



我一直在尝试实现电话中的SMS retriever API从电话中收集传入的SMS,显然,当在电话上收到SMS时,广播听众在广播听众上的 onReceive()从未被调用。p> 客户端实现如下所述。

    private fun startSMSListener() {
    Log.d(TAG, "startSMSListener():")
    val client = SmsRetriever.getClient(this)
    val retriever = client.startSmsRetriever()
    retriever.addOnSuccessListener {
        Toast.makeText(this@MainActivity,"Listener started", Toast.LENGTH_SHORT).show()
        val otpListener = object : SMSBroadcastReceiver.OTPListener {
            override fun onOTPReceived(otp: String) {
                Log.d(TAG, "onOTPReceived(): $otp")
                tv_hash_code.text = otp
                Toast.makeText(this@MainActivity, otp , Toast.LENGTH_LONG).show()
            }
            override fun onOTPTimeOut() {
                Log.d(TAG, "onOTPTimeOut():")
                Toast.makeText(this@MainActivity,"TimeOut", Toast.LENGTH_SHORT).show()
            }
        }
        //smsBroadcastReceiver this is already initialized 
        smsBroadcastReceiver.injectOTPListener(otpListener)
        registerReceiver(smsBroadcastReceiver,
            IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION))
    }
    retriever.addOnFailureListener {
        Toast.makeText(this@MainActivity,"Problem to start listener", Toast.LENGTH_SHORT).show()
    }
}

广播接收器是

class SMSBroadcastReceiver : BroadcastReceiver() {

private var otpReceiver: OTPListener? = null
fun injectOTPListener(receiver: OTPListener?) {
    Log.d(TAG, "injectOTPListener is empty : ${receiver == null}")
    this.otpReceiver = receiver
}
override fun onReceive(context: Context, intent: Intent) {
    Log.d(TAG, intent.action)
    if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
        val extras = intent.extras
        val status = extras.get(SmsRetriever.EXTRA_STATUS) as Status
        when (status.statusCode) {
            CommonStatusCodes.SUCCESS -> {
                Log.d(TAG, "CommonStatusCodes.SUCCESS")
                Toast.makeText(context, "CommonStatusCodes.SUCCESS", Toast.LENGTH_LONG).show()
                val message = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String
                val pattern = Pattern.compile("\d{6}")
                val matcher = pattern.matcher(message)
                if (matcher.find()) {
                    otpReceiver?.onOTPReceived(matcher.group(0))
                    return
                }
            }
            CommonStatusCodes.TIMEOUT -> {
                Log.d(TAG, "CommonStatusCodes.TIMEOUT")
                Toast.makeText(context, "CommonStatusCodes.TIMEOUT", Toast.LENGTH_LONG).show()
                otpReceiver?.onOTPTimeOut()
            }
        }
    }
}
interface OTPListener {

    fun onOTPReceived(otp: String)
    fun onOTPTimeOut()
}
}

服务器实现

这就是我的消息

<#> Your SmsVerificationCOde code is: 123456
wPMABADKiiS

使用调试键生成的这个哈希代码,我尝试了三种不同的方法来生成哈希代码,这些方法都提供了相同的值。

  1. keytool

    KEYTOOL -EXPORTCERT -ALIAS ANDROIDDEBUGKEY -KEYSTORE〜/.ANDROID/DEBUG.KEYSTORE -STOREPASS ANDROID ANDROID -KEYPASS ANDROID |xxd -p |tr -d" [:space:]" |echo -n com.example.smsverification code cat |SHA256SUM |tr -d" [:space:] - " |XXD -R -P |base64 |剪切-C1-11

  2. 脚本

    ./sms_retriever_hash_v9.sh -package" com.example.smsverificationcode" - keystore〜/.android/debug.keystore

  3. AppSignatureHelper

所有这些似乎都提供了相同的哈希代码,这使我相信哈希代码还不错(我尝试过任何方式,所有方法为我提供了另一个"值",这对于所有方法都相同评估)

参考:https://developers.google.com/Indestity/sms-retriever/verifyhttps://medium.com/@wilderpereira/secure-android-android-otp-account-verification-with-the-the-sms-retriever-api-c395c1985fbf

我很肯定客户的实现是正确的,因为我在5分钟后遇到超时错误,但在短信到达时从未真正得到任何东西。

我相信Android系统无法弄清我的应用程序的应用程序,或者我的消息格式可能是错误的。

请看一下,纠正我可能错的地方。任何帮助都受到高度评价。

必须在全球广播的清单中注册广播接收器。SMS_Retriever是全球广播。在这种情况下,您的广播接收器不能动态。

请参阅您要寻找的解决方案的链接:https://medium.com/@wilderpereira/secure-android-android-otp-account-verification-with-the-sms-retriever-api-api-api-c395c1985c1985fbf <</p>

启动SmsRetriever后,您只在注册广播接收器

初始化SmsRetriever

时,广播接收器应已注册

进行更改后,您的代码应该看起来像这样:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)
        val smsBroadcastReceiver = SMSBroadcastReceiver()
        val otpListener = object : SMSBroadcastReceiver.OTPListener {
            override fun onOTPReceived(otp: String) {
                Toast.makeText(this@MainActivity, otp , Toast.LENGTH_LONG).show()
            }
            override fun onOTPTimeOut() {
                Toast.makeText(this@MainActivity,"TimeOut", Toast.LENGTH_SHORT).show()
            }
        }
        smsBroadcastReceiver.injectOTPListener(otpListener)
        registerReceiver(smsBroadcastReceiver,
                IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION))
        startSMSListener()
   }
    private fun startSMSListener() {
        Log.d("CodeVerification", "startSMSListener()")
        val client = SmsRetriever.getClient(this)
        val retriever = client.startSmsRetriever()
        retriever.addOnSuccessListener {
            Toast.makeText(this@MainActivity,"Listener started", Toast.LENGTH_SHORT).show()
        }
        retriever.addOnFailureListener {
            Toast.makeText(this@MainActivity,"Problem to start listener", Toast.LENGTH_SHORT).show()
        }
    }

我将您的代码与这些更改一起使用,并且效果很好!

另外,请确保您使用正确的密钥库来签署APK。

如果要确保使用正确的调试密钥库,则可以向您添加以下内容 build.gradle file。


android {
    ...
    signingConfigs {
        config {
            keyPassword 'android'
            storeFile file(<path to debug keystore>)
            storePassword 'android'
            keyAlias 'androiddebugkey'
        }
    }
    ... 
}

最新更新