SMS Retriever API android系统无法将消息发送到广播接收器

时间:2019-03-22 14:31:57

标签: android kotlin sms

我一直在尝试实现SMS Retriever API来从电话上的服务器收集传入的短信,显然,当电话上收到短信时,广播侦听器上的onReceive()永远不会被调用。

客户实施如下。

    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 -exportcert -alias androiddebugkey -keystore〜/ .android / debug.keystore -storepass android -keypass android | xxd -p | tr -d“ [:space:]” | echo -n com.example.smsverificationcode cat | sha256sum | tr -d“ [:space:]-” | xxd -r -p | base64 |切-c1-11

  2. Script

    ./ sms_retriever_hash_v9.sh-打包“ com.example.smsverificationcode” --keystore〜/ .android / debug.keystore

  3. AppSignatureHelper

他们似乎都提供了相同的哈希码,这使我相信哈希码还可以(我以任何方式尝试了这种发布类型,所有方法都为我提供了另一个“值”,该值对于评估)

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

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

我认为Android系统无法基于哈希码来确定我的应用程序,否则我的消息格式可能是错误的。

请看看并纠正我可能会出错的地方。任何帮助都受到高度重视。

2 个答案:

答案 0 :(得分:0)

启动<tr><td><br></td></tr> 后,您只需注册广播接收器

初始化SmsRetriever

时,应该已经注册了广播接收器。

进行更改后,您的代码应如下所示:

SmsRetriever

我将您的代码用于这些更改,并且效果很好!

此外,请确保使用正确的密钥库对APK进行签名。

如果要确保使用正确的调试密钥库,可以在 build.gradle 文件中添加以下内容。

    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()
        }
    }

答案 1 :(得分:0)

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

请查看以下链接以找到所需的解决方案:https://medium.com/@wilderpereira/secure-android-otp-account-verification-with-the-sms-retriever-api-c395c1985fbf