Система Android Retriever API не может отправить сообщение в Broadcast Receiver - PullRequest
2 голосов
/ 22 марта 2019

Я пытался реализовать 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

    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 |cut -c1-11

  2. Script

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

  3. AppSignatureHelper

все они, кажется, предоставляют один и тот же хэш-код, который делаетЯ считаю, что хеш-код в порядке (я пытался это для типа выпуска любым способом, все методы предоставляют мне другое "значение", которое одинаково для всех методов оценки)

Ссылка: https://developers.google.com/identity/sms-retriever/verifyhttps://medium.com/@wilderpereira/secure-android-otp-account-verification-with-the-sms-retriever-api-c395c1985fbf

Я уверен, что реализация клиента правильная, так как я получаю ошибку TimeOut через 5 минут, но на самом деле ничего не получаю во время прихода смс.

Я считаю, что система Androidне могу определить мое приложение на основе хеш-кода или формат моего сообщения может быть неправильным.

Пожалуйста, посмотрите и исправьте меня, где я мог ошибаться.любая помощь высоко ценится.

Ответы [ 2 ]

0 голосов
/ 10 июня 2019

Вы должны зарегистрировать получателя вещания в манифесте для глобальных рассылок.SMS_RETRIEVER - это глобальная трансляция.В этом случае ваш широковещательный приемник не может быть динамическим.

Пожалуйста, перейдите по следующей ссылке для решения, которое вы ищете: https://medium.com/@wilderpereira/secure-android-otp-account-verification-with-the-sms-retriever-api-c395c1985fbf

0 голосов
/ 22 марта 2019

Вы регистрируете вас только Broadcast Receiver после запуска SmsRetriever.

Broadcast Receiver уже должен быть зарегистрирован при инициализации 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 следующее.


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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...