ในการยืนยันหมายเลขโทรศัพท์โดยอัตโนมัติ คุณต้องใช้ทั้งส่วนไคลเอ็นต์และเซิร์ฟเวอร์ของขั้นตอนการยืนยัน เอกสารนี้อธิบายวิธีใช้ ส่วนไคลเอ็นต์ในแอป Android
ในการเริ่มขั้นตอนการยืนยันหมายเลขโทรศัพท์ในแอป Android คุณต้องส่งหมายเลขโทรศัพท์ไปยังเซิร์ฟเวอร์การยืนยันและเรียก SMS Fetchr API เพื่อเริ่มการฟังข้อความ SMS ที่มีรหัสแบบใช้ครั้งเดียวสําหรับแอปของคุณ หลังจากได้รับข้อความแล้ว คุณจะต้องส่งรหัสแบบใช้ครั้งเดียวกลับไปยังเซิร์ฟเวอร์เพื่อดําเนินกระบวนการยืนยันให้เสร็จสมบูรณ์
ข้อควรทราบก่อนที่จะเริ่มต้น
ในการเตรียมแอป ให้ทําตามขั้นตอนในหัวข้อต่อไปนี้
ข้อกําหนดเบื้องต้นของแอป
ตรวจสอบว่าไฟล์บิวด์ของแอปใช้ค่าต่อไปนี้
- minSdkVersion 19 ขึ้นไป
- CompSdkVersion 28 ขึ้นไป
กําหนดค่าแอปของคุณ
ในไฟล์ build.gradle ระดับโปรเจ็กต์ ให้รวมที่เก็บ Maven ของ Google และที่เก็บส่วนกลางของ Maven
ทั้งในส่วน buildscript
และ allprojects
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
เพิ่มการอ้างอิงบริการ Google Play สําหรับ SMS Fetcher API ไปยังไฟล์บิวด์แบบ Gradle ของโมดูล ซึ่งโดยทั่วไปคือ app/build.gradle
dependencies {
implementation 'com.google.android.gms:play-services-auth:20.5.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1'
}
1. รับหมายเลขโทรศัพท์ของผู้ใช้
คุณสามารถทราบหมายเลขโทรศัพท์ของผู้ใช้ในลักษณะที่เหมาะสมกับแอปพลิเคชันของคุณ ซึ่งมักจะเป็นประสบการณ์การใช้งานที่ดีที่สุดที่ใช้เครื่องมือเลือกคําแนะนําเพื่อให้ผู้ใช้เลือกจากหมายเลขโทรศัพท์ที่จัดเก็บในอุปกรณ์ ซึ่งทําให้ไม่ต้องพิมพ์หมายเลขโทรศัพท์ด้วยตนเอง วิธีใช้เครื่องมือแนะนํา
// 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. เริ่มโปรแกรมเรียก SMS
เมื่อคุณพร้อมยืนยันหมายเลขโทรศัพท์ของผู้ใช้ รับอินสแตนซ์ของออบเจ็กต์ SmsRetrieverClient
โทรหา startSmsRetriever
แล้วแนบ Listener ที่ประสบความสําเร็จและล้มเหลวไปยังงานการดึงข้อมูล 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
// ...
}
});
งานการดึงข้อมูล SMS จะฟังข้อความ SMS ภายใน 5 นาทีซึ่งมีสตริงที่ไม่ซ้ํากันซึ่งระบุแอปของคุณอยู่
3. ส่งหมายเลขโทรศัพท์ไปยังเซิร์ฟเวอร์ของคุณ
หลังจากได้รับหมายเลขโทรศัพท์ของผู้ใช้และเริ่มฟังข้อความ SMS แล้ว ให้ส่งหมายเลขโทรศัพท์ของผู้ใช้ไปยังเซิร์ฟเวอร์การยืนยันโดยใช้วิธีการใดก็ได้ (ตามปกติจะมีคําขอ HTTPS POST)
เซิร์ฟเวอร์ของคุณสร้างข้อความยืนยันและส่ง SMS ไปยังหมายเลขโทรศัพท์ที่คุณระบุ โปรดดูที่ดําเนินการยืนยันทาง SMS บนเซิร์ฟเวอร์
4. รับข้อความยืนยัน
เมื่อได้รับข้อความยืนยันในอุปกรณ์ของผู้ใช้แล้ว บริการ Play จะออกอากาศ 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. 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;
}
}
}
}
ลงทะเบียน BroadcastReceiver
นี้กับตัวกรอง Intent
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>
5. ส่งรหัสยืนยันแบบใช้ครั้งเดียวจากข้อความยืนยันไปยังเซิร์ฟเวอร์
ตอนนี้คุณได้อ่านข้อความสําหรับการยืนยันแล้ว ให้ใช้นิพจน์ทั่วไปหรือตรรกะอื่นเพื่อรับรหัสแบบใช้ครั้งเดียวจากข้อความ รูปแบบของโค้ดแบบใช้ครั้งเดียว ขึ้นอยู่กับวิธีที่คุณนําโค้ดดังกล่าวไปใช้ในเซิร์ฟเวอร์ของคุณ
สุดท้าย ส่งรหัสแบบใช้ครั้งเดียวไปยังเซิร์ฟเวอร์ผ่านการเชื่อมต่อที่ปลอดภัย เมื่อเซิร์ฟเวอร์ได้รับรหัสแบบใช้ครั้งเดียว ระบบจะบันทึกว่าหมายเลขโทรศัพท์ได้รับการยืนยันแล้ว
ไม่บังคับ: บันทึกหมายเลขโทรศัพท์ด้วย Smart Lock สําหรับรหัสผ่าน
หลังจากที่ผู้ใช้ยืนยันหมายเลขโทรศัพท์แล้ว คุณสามารถแจ้งให้ผู้ใช้บันทึกหมายเลขโทรศัพท์นี้โดยใช้ Smart Lock สําหรับรหัสผ่าน เพื่อให้ใช้งานได้โดยอัตโนมัติในแอปอื่นๆ และในอุปกรณ์อื่นๆ โดยไม่ต้องพิมพ์หรือเลือกหมายเลขโทรศัพท์อีกครั้ง โดยทําดังนี้
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);
}
}
});
จากนั้น หลังจากที่ผู้ใช้ติดตั้งแอปอีกครั้งหรือติดตั้งแอปในอุปกรณ์เครื่องใหม่ คุณจะดึงหมายเลขโทรศัพท์ที่บันทึกไว้ได้โดยไม่ต้องขอหมายเลขโทรศัพท์อีกครั้ง
// 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)