Using SMS Retriever API, you can perform SMS-based verification in your app automatically, without requiring the user to manually type verification codes, and without requiring any extra app permissions. The Google Play Services SDK(10.2 and newer) offering you to enable read the phone number and the verification SMS automatically without requiring these extra permissions.

1.Phone Selector API


Phone Selector API provides the Phone number to your app with a much better user experience and no extra permissions.Using this API, you can launch a dialogue, which shows the phone numbers on the device to the user. First, you create a hint request object and set the phone number identifier supported field to true.

HintRequest hintRequest = new HintRequest.Builder()
                         .setHintPickerConfig(newCredentialPickerConfig.Builder().setShowCancelButton(true).build())
                         .setPhoneNumberIdentifierSupported(true)
                         .build();

Then, you get a pending intent from that hint request for the phone number selector dialogue.

GoogleApiClient apiClient = new GoogleApiClient.Builder(getContext())
               .addApi(Auth.CREDENTIALS_API).enableAutoManage(getActivity(), GoogleApiHelper
               .getSafeAutoManageId(), new GoogleApiClient.OnConnectionFailedListener() {
                         @Override
                         public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                             Log.e(TAG, "Client connection failed: " + connectionResult.getErrorMessage());
                         }
             }).build();
 PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent(
            apiClient, hintRequest);
 startIntentSenderForResult(intent.getIntentSender(),
                            RESOLVE_HINT, null, 0, 0, 0);

Once the user selects the phone number, that phone number is returned to your app in the onActivityResult().

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == RC_PHONE_HINT) {
       if (data != null) {
          Credential cred = data.getParcelableExtra(Credential.EXTRA_KEY);
            if (cred != null) {
               final String unformattedPhone = cred.getId();
            }
       }
    }
}

2.Reading the verification code automatically using SMS retriever API


SMS Retriever API provides you the message content to your app without requiring any extra permissions.The key part is that it provides you only the message targeted your app.You have to verification code in your SMS message and include app-specific hash.This app-specific hash is a static hash that you can just include in the SMS template without requiring many code changes. SMS Retriever API

Start the SMS retriever

This makes it wait for one matching SMS, which includes the app-specific hash.

SmsRetrieverClient client = SmsRetriever.getClient(mContext);
// Starts SmsRetriever, waits for ONE matching SMS message until timeout
// (5 minutes).
Task<Void> task = client.startSmsRetriever();
// Listen for success/failure of the start Task.
task.addOnSuccessListener(new OnSuccessListener<Void>() {
  @Override
  public void onSuccess(Void aVoid) {
    // Log.d(TAG,"Successfully started retriever");
  }
});
task.addOnFailureListener(new OnFailureListener() {
  @Override
  public void onFailure(@NonNull Exception e) {
    Log.e(TAG,"Failed to start retriever");
  });
);

Once the SMS with the app-specific hash is received on the device, it is provided to your app via broadcast.

public class MySMSBroadcastReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
    if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
      Bundle extras = intent.getExtras();
      Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
      switch(status.getStatusCode()) {
        case CommonStatusCodes.SUCCESS:
          // Get SMS message contents
          String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
          break;
        case CommonStatusCodes.TIMEOUT:
          Log.d(TAG,"timed out (5 minutes)"
          break;
      }
    }
  }
}

In your broadcast receiver, you can get the message content from the extras.Once you have the message content, you can extract the verification code, and verify the code just like you would normally do. Register this BroadcastReceiver with the intent filter.

<receiver android:name=".MySMSBroadcastReceiver" android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
    </intent-filter>
</receiver>

After starting the SMS retriever, you can just send the SMS with the verification code and the app-specific hash to the phone using any backend infrastructure of yours.

3.Construct a verification message


Construct the verification message that you will send to the user’s device. This message must:

  • Be no longer than 140 bytes
  • Begin with one of the following strings:
    • [#]
    • Two consecutive zero-width space characters (U+200B)
  • End with an 11-character hash string that identifies your app

Otherwise, the contents of the verification message can be whatever you choose. It is helpful to create a message from which you can easily extract the one-time code later on. For example, a valid verification message might look like the following:

[#] Your ExampleApp code is: 123ABC78
FA+9qCX9VSu

Computing your app’s hash string


You can get your app’s hash string with the AppSignatureHelper class from the SMS retriever sample app. However, if you use the helper class, be sure to remove it from your app after you get the hash string. Do not use hash strings dynamically computed on the client in your verification messages.