Để tự động xác minh số điện thoại, bạn phải triển khai cả phần ứng dụng khách và máy chủ của quy trình xác minh. Tài liệu này mô tả cách triển khai phần ứng dụng khách trong ứng dụng Android.
Để bắt đầu quy trình xác minh số điện thoại trong một ứng dụng Android, bạn gửi số điện thoại đến máy chủ xác minh và gọi SMS Retriever API để bắt đầu nghe tin nhắn SMS chứa mã một lần cho ứng dụng. Sau khi nhận được tin nhắn, bạn gửi lại mã một lần cho máy chủ để hoàn tất quá trình xác minh.
Trước khi bắt đầu
Để chuẩn bị cho ứng dụng của bạn, hãy hoàn tất các bước trong những phần sau.
Điều kiện tiên quyết đối với ứng dụng
Hãy đảm bảo tệp bản dựng của ứng dụng sử dụng các giá trị sau:
- minSdkVersion từ 19 trở lên
- compileSdkVersion từ 28 trở lên
Định cấu hình ứng dụng
Trong tệp build.gradle cấp dự án, hãy thêm kho lưu trữ Maven của Google và kho lưu trữ trung tâm Maven vào cả hai phần buildscript
và allprojects
:
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
Thêm phần phụ thuộc Dịch vụ Google Play dành cho API Thu thập SMS vào tệp bản dựng Gradle của mô-đun, thường là app/build.gradle
:
dependencies {
implementation 'com.google.android.gms:play-services-auth:20.7.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1'
}
1. Lấy số điện thoại của người dùng
Bạn có thể lấy số điện thoại của người dùng theo bất cứ cách nào phù hợp với ứng dụng của bạn. Thông thường, cách tốt nhất là sử dụng bộ chọn gợi ý để nhắc người dùng chọn từ các số điện thoại được lưu trữ trên thiết bị, từ đó tránh phải nhập số điện thoại theo cách thủ công. Cách sử dụng bộ chọn gợi ý:
// 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
}
}
}
2. Khởi động trình truy xuất SMS
Khi bạn đã sẵn sàng xác minh số điện thoại của người dùng, hãy lấy một bản sao của đối tượng SmsRetrieverClient
, gọi startSmsRetriever
và đính kèm trình nghe thành công và không thành công vào nhiệm vụ truy xuất 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 via 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
// ...
}
});
Tác vụ truy xuất SMS sẽ nghe tối đa 5 phút cho một tin nhắn SMS chứa một chuỗi duy nhất xác định ứng dụng của bạn.
3. Gửi số điện thoại đến máy chủ của bạn
Sau khi bạn đã có số điện thoại của người dùng và bắt đầu nghe tin nhắn SMS, hãy gửi số điện thoại của người dùng đến máy chủ xác minh của bạn bằng một phương thức bất kỳ (thường là yêu cầu POST qua HTTPS).
Máy chủ của bạn sẽ tạo một thông báo xác minh và gửi qua SMS đến số điện thoại mà bạn đã chỉ định. Xem Thực hiện xác minh qua SMS trên máy chủ.
4. Nhận thông báo xác minh
Khi nhận được thông báo xác minh trên thiết bị của người dùng, Dịch vụ Google Play sẽ truyền phát rõ ràng ý định SmsRetriever.SMS_RETRIEVED_ACTION
đến ứng dụng của bạn, trong đó có nội dung thông báo. Sử dụng BroadcastReceiver
để nhận
thông báo xác minh này.
Trong trình xử lý onReceive
của BroadcastReceiver
, hãy lấy nội dung của thông báo xác minh từ các tính năng bổ sung của Intent:
/**
* BroadcastReceiver to wait for SMS messages. This can be registered either
* in the AndroidManifest or at runtime. Should filter 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:
// Get SMS message contents
String message = (String) extras.get(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;
}
}
}
}
Đăng ký BroadcastReceiver
này bằng bộ lọc ý định com.google.android.gms.auth.api.phone.SMS_RETRIEVED
(giá trị của hằng số SmsRetriever.SMS_RETRIEVED_ACTION
) và quyền com.google.android.gms.auth.api.phone.permission.SEND
(giá trị của hằng số SmsRetriever.SEND_PERMISSION
) trong tệp AndroidManifest.xml
của ứng dụng, như trong ví dụ sau hoặc sử dụng Context.registerReceiver
một cách linh động.
<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>
5. Gửi mã một lần từ thư xác minh tới máy chủ của bạn
Hiện bạn đã có văn bản của thông báo xác minh, hãy sử dụng biểu thức chính quy hoặc một số logic khác để nhận mã một lần từ thông báo. Định dạng của mã một lần phụ thuộc vào cách bạn triển khai mã trong máy chủ.
Cuối cùng, gửi mã một lần đến máy chủ của bạn qua kết nối an toàn. Khi nhận được mã một lần, máy chủ của bạn sẽ ghi lại số điện thoại đó.
Tùy chọn: Lưu số điện thoại bằng Smart Lock cho Mật khẩu
Sau khi người dùng xác minh số điện thoại của họ, bạn có thể nhắc người dùng lưu tài khoản dùng số điện thoại này bằng Smart Lock cho Mật khẩu để họ có thể dùng số này một cách tự động trong các ứng dụng khác và trên các thiết bị khác mà không phải nhập hoặc chọn lại số điện thoại:
Credential credential = new Credential.Builder(phoneNumberString)
.setAccountType("https://signin.example.com") // a URL specific to the app
.setName(displayName) // optional: a display name if available
.build();
Auth.CredentialsApi.save(apiClient, credential).setResultCallback(
new ResultCallback() {
public void onResult(Result result) {
Status status = result.getStatus();
if (status.isSuccess()) {
Log.d(TAG, "SAVE: OK"); // already saved
} else if (status.hasResolution()) {
// Prompt the user to save
status.startResolutionForResult(this, RC_SAVE);
}
}
});
Sau đó, sau khi người dùng cài đặt lại ứng dụng hoặc cài đặt ứng dụng trên một thiết bị mới, bạn có thể truy xuất số điện thoại đã lưu mà không cần hỏi lại người dùng về số điện thoại của họ:
// On the next install, retrieve the phone number
mCredentialRequest = new CredentialRequest.Builder()
.setAccountTypes("https://signin.example.com") // the URL specific to the developer
.build();
Auth.CredentialsApi.request(apiClient, mCredentialRequest).setResultCallback(
new ResultCallback<CredentialRequestResult>() {
public void onResult(CredentialRequestResult credentialRequestResult) {
if (credentialRequestResult.getStatus().isSuccess()) {
credentialRequestResult.getCredential().getId(); // this is the phone number
}
}
});
// Then, initiate verification and sign the user in (same as original verification logic)