Для автоматической проверки телефонных номеров необходимо реализовать как клиентскую, так и серверную части процесса проверки. В этом документе описано, как реализовать клиентскую часть в приложении для Android.
Для запуска процесса проверки номера телефона в приложении Android необходимо отправить номер телефона на сервер проверки и вызвать API SMS Retriever, чтобы начать ожидание SMS-сообщения, содержащего одноразовый код для вашего приложения. После получения сообщения необходимо отправить одноразовый код обратно на сервер для завершения процесса проверки.
Для подготовки приложения выполните действия, описанные в следующих разделах.
Предварительные требования к приложению
Убедитесь, что в файле сборки вашего приложения используются следующие значения:
- Минимальная версия SDK: 19 или выше.
- compileSdkVersion 28 или выше
Настройте свое приложение
В файле build.gradle на уровне проекта укажите репозиторий Maven от Google и центральный репозиторий Maven как в разделе buildscript , так и в разделе allprojects :
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
Добавьте зависимость от сервисов Google Play для API SMS Retriever в файл сборки Gradle вашего модуля , который обычно находится по адресу app/build.gradle :
dependencies {
implementation 'com.google.android.gms:play-services-auth:21.5.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:18.3.0'
}
Получите номер телефона пользователя.
Вы можете получить номер телефона пользователя любым удобным для вашего приложения способом. Зачастую наилучшим вариантом для пользователя является использование подсказки, предлагающей выбрать номер из сохраненных на устройстве номеров, что позволяет избежать ручного ввода номера. Чтобы использовать подсказку:
// 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);
}
// 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(); <-- will need to process phone number string
}
}
}
Запустите программу для получения SMS-сообщений.
Когда вы будете готовы проверить номер телефона пользователя, получите экземпляр объекта SmsRetrieverClient , вызовите startSmsRetriever и прикрепите обработчики успешного и неудачного выполнения к задаче получения SMS-сообщений:
// Get an instance of SmsRetrieverClient, used to start listening for a matching
// SMS message.
SmsRetrieverClient client = SmsRetriever.getClient(this /* context */);
// Starts SmsRetriever, which waits for ONE matching SMS message until timeout
// (5 minutes). The matching SMS message will be sent using a Broadcast Intent
// with action SmsRetriever#SMS_RETRIEVED_ACTION.
Task<Void> task = client.startSmsRetriever();
// Listen for success/failure of the start Task. If in a background thread, this
// can be made blocking using Tasks.await(task, [timeout]);
task.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
// Successfully started retriever, expect broadcast intent
// ...
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Failed to start retriever, inspect Exception for more details
// ...
}
});
Задача получения SMS-сообщений ожидает до пяти минут сообщения, содержащего уникальную строку, идентифицирующую ваше приложение.
Отправьте номер телефона на свой сервер.
После получения номера телефона пользователя и начала приема SMS-сообщений, отправьте номер телефона пользователя на ваш сервер подтверждения любым способом (обычно с помощью HTTPS POST-запроса).
Ваш сервер генерирует проверочное сообщение и отправляет его по SMS на указанный вами номер телефона. См. раздел «Выполнение SMS-проверки на сервере» .
Получайте подтверждающие сообщения
Когда на устройство пользователя поступает подтверждающее сообщение, Play Services явно отправляет вашему приложению Intent SmsRetriever.SMS_RETRIEVED_ACTION , содержащий текст сообщения. Используйте BroadcastReceiver для получения этого подтверждающего сообщения.
В обработчике onReceive объекта BroadcastReceiver получите текст проверочного сообщения (и, при необходимости, адрес отправителя) из дополнительных параметров Intent:
/**
* BroadcastReceiver to wait for SMS messages. This can be registered either
* in the AndroidManifest or at runtime. Filters Intents on
* SmsRetriever.SMS_RETRIEVED_ACTION.
*/
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:
// (Optional) Get SMS Sender address - only available in
// GMS version 24.20 onwards, else it will return null
String senderAddress = extras.getString(SmsRetriever.EXTRA_SMS_ORIGINATING_ADDRESS);
// Get SMS message contents
String message = extras.getString(SmsRetriever.EXTRA_SMS_MESSAGE);
// Extract one-time code from the message and complete verification
// by sending the code back to your server.
break;
case CommonStatusCodes.TIMEOUT:
// Waiting for SMS timed out (5 minutes)
// Handle the error ...
break;
}
}
}
}
Для регистрации этого BroadcastReceiver используйте следующее:
- Фильтр намерений:
com.google.android.gms.auth.api.phone.SMS_RETRIEVED(значение константыSmsRetriever.SMS_RETRIEVED_ACTION) - Разрешение:
com.google.android.gms.auth.api.phone.permission.SEND(значение константыSmsRetriever.SEND_PERMISSION)
Вы можете зарегистрировать приемник в файле AndroidManifest.xml вашего приложения, как показано в следующем примере, или динамически, используя Context.registerReceiver .
<receiver android:name=".MySMSBroadcastReceiver" android:exported="true"
android:permission="com.google.android.gms.auth.api.phone.permission.SEND">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>
Отправьте одноразовый код из подтверждающего сообщения на свой сервер.
Теперь, когда у вас есть текст проверочного сообщения, используйте регулярное выражение или другую логику, чтобы получить одноразовый код из сообщения. Формат одноразового кода зависит от того, как вы реализовали его на своем сервере.
Наконец, отправьте одноразовый код на свой сервер по защищенному соединению. Когда ваш сервер получит одноразовый код, он зафиксирует, что номер телефона подтвержден.