3

From Jan 9th, 2019 Google will remove apps from Playstore with permissions READ SMS AND CALL LOG, if they don’t explain the necessity.

Google introduced SMS Retriever API to automatically fetch a verification code sent via SMS within the app.

But those APIs are not clearly expressed and is very confusing. I don't know if it's me who thinks it is confusing. Anyhow, here is what I have looked into to read SMS but I could understand nothing.

I am not sure if this is the correct link to read SMS automatically.

https://developers.google.com/identity/sms-retriever/request

I used these dependencies

implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.0.0'

There is one good tutorial to implement auto-read SMS but some of the APIs are deprecated so I'm trying to find any simple explanation to implement auto-read SMS in Android.

Here is the link to that tutorial

https://androidwave.com/automatic-sms-verification-android/

ravi
  • 2,722
  • 7
  • 25
  • 42

1 Answers1

6

You should use sms retriever api for reading otp messages. Here is how you can do that.

You need below 2 dependencies for sms retrieval code

implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.1.0'

Define few variables like this in your activity/fragment

private val SMS_CONSENT_REQUEST = 2
private lateinit var smsVerificationReceiver: BroadcastReceiver

In your onCreate() method start SMS retriever

 SmsRetriever.getClient(this).startSmsUserConsent(null)
 smsReceiver()
 val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
 registerReceiver(smsVerificationReceiver, intentFilter)

Below is the method for broadcast receiver

 private fun smsReceiver() {
    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 -> {
                        // Get consent intent
                        val consentIntent =
                            extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
                        try {
                            // Start activity to show consent dialog to user, activity must be started in
                            // 5 minutes, otherwise you'll receive another TIMEOUT intent
                            startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
                        } catch (e: ActivityNotFoundException) {
                            // Handle the exception ...
                        }
                    }
                    CommonStatusCodes.TIMEOUT -> {
                        // Time out occurred, handle the error.
                    }
                }
            }
        }
    }
}

And then in onActivityResult() you can get the verification code

public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        // ...
        SMS_CONSENT_REQUEST ->
            // Obtain the phone number from the result
            if (resultCode == Activity.RESULT_OK && data != null) {
                // Get SMS message content
                val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
                // Extract one-time code from the message and complete verification
                // `message` contains the entire text of the SMS message, so you will need
                // to parse the string.
                val oneTimeCode = parseOneTimeCode(message) // define this function
                et_otp.setText(oneTimeCode.toString())
                // send one time code to the server
            } else {
                // Consent denied. User can type OTC manually.
            }
    }
}

Also don't forget to unregister receiver in onDestroy() method

 unregisterReceiver(smsVerificationReceiver)
Vivek Mishra
  • 5,669
  • 9
  • 46
  • 84
  • For more details, take a look at Google's Documentation. https://developers.google.com/identity/sms-retriever/user-consent/request – Morgan Koh Jul 14 '20 at 07:05