There are two new APIs in Google Play Services that will help you get a phone number and check it using SMS without device permission: Phone selector and SMS relay.
Using the phone selector to get a number
The first step is for the user to initiate sending SMS from in your application. Your application may prompt the user to enter a phone number, and you can use the phone selector to make it easier using a code like this:
// Construct a request for phone numbers and show the picker private void requestHint() { HintRequest hintRequest = new HintRequest.Builder() .setPhoneNumberIdentifierSupported(true) .build(); PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent( apiClient, hintRequest); startIntentSenderForResult(intent.getIntentSender(), RESOLVE_HINT, null, 0, 0, 0); }
The HintRequest builder tells Play Services that a phone number is required identifier. This is then used to create and start an intention that displays the Service Services dialog allowing them to select their phone number to share it with the application. This API does not require any permissions and displays the number (number) available on the phone or Google account for the user.
When a user selects a phone number, he will be returned to the application in onActivityResult in E164 format on devices running the latest version of Play Services. Please note that in some cases, depending on your phone, you cannot get a phone number, so be sure to check that the credentials are not zero. If you do not have a number, you will need to provide the user with the opportunity to enter it manually.
// Obtain the phone number from the result @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RESOLVE_HINT) { if (resultCode == RESULT_OK) { Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY); // credential.getId(); <-- E.164 format phone number on 10.2.+ devices } } }
At this point you will have a line of phone number for your user. While this is useful, you will probably want to verify that the user owns this particular number, for example, to allow them to send or receive a message with other users or to identify themselves with this number.
Using SMS Verification API to Verify Number
An easy way to verify ownership of a phone number is to send an SMS message to a number containing a one-time verification code and having them enter this into your application. The SMS verification API gives you the ability of the application to listen to incoming SMS messages, from which it can analyze the code automatically.
To get started, your application will be SmsRetrieverClient with code like this:
SmsRetrieverClient client = SmsRetriever.getClient(this ); Task<Void> task = client.startSmsRetriever(); task.addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) {
It is quite simple - you get the SMS Retriever client, and then you start the task for it. The task has the ability of the Success listener, as well as the Refusal of redefinition. After starting SMS Retriever, you should send the phone number of the user to your server and start his workflow to generate a message and send it to this number.
A message must be constructed in a certain way. The message must correspond to the SMS message, so it cannot exceed 140 bytes. This should start with a specific prefix: '<#>' or two consecutive mileage symbols of zero width (U + 200B). See the documentation for your additional information. It should end with an 11-character hash that defines your application, described below.
Example:
<#> Use the code 123456 as a confirmation code in the sample application!
FA + 9qCX9VSu
A one-time verification code can be any string: you can just generate a random number. The message should end with a hash, which is determined in accordance with the procedures here. Google Play Services will use this hash to determine which application the verification applies to. You only need to create this hash once for your application package and a signature certificate: it will not change and the client application should not.
Then your server can send a message to the phone using the existing SMS infrastructure or service. When this message is received, Google Play Services broadcasts the intent, which contains the text of the message. Here is the code:
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: String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE); break; case CommonStatusCodes.TIMEOUT: break; } } } }
In the onReceive broadcast receiver, you get extra features and pull the status from there. If the status indicates that the message was successfully received, you can pull the message from the additional functions. From here, you can parse the verification code and send it back to your server to verify ownership of the phone number.