ขอความยินยอมแบบครั้งเดียวเพื่ออ่านรหัสยืนยันทาง SMS

หน้านี้จะอธิบายวิธีใช้ SMS User Consent API เพื่อขอความยินยอมจากผู้ใช้ในการอ่านข้อความยืนยันทาง SMS รายการเดียว หากผู้ใช้ยินยอม API จะแสดงข้อความในช่องดังกล่าว ซึ่งคุณจะสามารถรับรหัสยืนยันและดำเนินขั้นตอนการยืนยันให้เสร็จสมบูรณ์

ติดตั้งการอ้างอิง

รวมคอมโพเนนต์การตรวจสอบสิทธิ์บริการ Google Play ในไฟล์ build.gradle ของแอป ดังนี้

implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.4.0'

1. ดูหมายเลขโทรศัพท์ของผู้ใช้

หากคุณไม่มีหมายเลขโทรศัพท์ของผู้ใช้ ให้ขอหมายเลขก่อนเริ่มขั้นตอนการยืนยันทาง SMS

คุณสามารถรับหมายเลขโทรศัพท์ของผู้ใช้ได้ในลักษณะที่เหมาะกับแอปของคุณ ลองใช้ตัวเลือกคำแนะนำของ Smart Lock สำหรับรหัสผ่าน เพื่อช่วยให้ผู้ใช้กรอกหมายเลขโทรศัพท์ได้ในกรณีที่ไม่จำเป็นต้องใช้ข้อมูลนั้นในการสร้างบัญชีของผู้ใช้ วิธีใช้ตัวเลือกคำแนะนำ

Kotlin

private val CREDENTIAL_PICKER_REQUEST = 1  // Set to an unused request code

// Construct a request for phone numbers and show the picker
private fun requestHint() {
    val hintRequest = HintRequest.Builder()
        .setPhoneNumberIdentifierSupported(true)
        .build()
    val credentialsClient = Credentials.getClient(this)
    val intent = credentialsClient.getHintPickerIntent(hintRequest)
    startIntentSenderForResult(
        intent.intentSender,
        CREDENTIAL_PICKER_REQUEST,
        null, 0, 0, 0
    )
}

public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        CREDENTIAL_PICKER_REQUEST ->
            // Obtain the phone number from the result
            if (resultCode == Activity.RESULT_OK && data != null) {
                val credential = data.getParcelableExtra<Credential>(Credential.EXTRA_KEY)
                // credential.getId();  <-- will need to process phone number string
            }
        // ...
    }
}

Java

private static final int CREDENTIAL_PICKER_REQUEST = 1;  // Set to an unused request code

// Construct a request for phone numbers and show the picker
private void requestHint() throws IntentSender.SendIntentException {
    HintRequest hintRequest = new HintRequest.Builder()
            .setPhoneNumberIdentifierSupported(true)
            .build();
    PendingIntent intent = Credentials.getClient(this).getHintPickerIntent(hintRequest);
    startIntentSenderForResult(intent.getIntentSender(),
            RESOLVE_HINT, null, 0, 0, 0);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case CREDENTIAL_PICKER_REQUEST:
            // Obtain the phone number from the result
            if (resultCode == RESULT_OK) {
                Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
                // credential.getId();  <-- will need to process phone number string
            }
            break;
        // ...
    }
}

2. เริ่มฟังข้อความขาเข้า

จากนั้น ให้เรียกใช้เมธอด startSmsUserConsent() ของ SMS User Consent API เพื่อเริ่มฟังข้อความขาเข้า หากคุณทราบหมายเลขโทรศัพท์ที่ข้อความ SMS จะเริ่มต้น ให้ระบุหมายเลข (หรือส่งผ่าน null) วิธีนี้จะทำให้ SMS User Consent API เริ่มทำงานกับข้อความจากหมายเลขนี้เท่านั้น

ในการเริ่มฟัง ให้ทำดังนี้

Kotlin

// Start listening for SMS User Consent broadcasts from senderPhoneNumber
// The Task<Void> will be successful if SmsRetriever was able to start
// SMS User Consent, and will error if there was an error starting.
val task = SmsRetriever.getClient(context).startSmsUserConsent(senderPhoneNumber /* or null */)

Java

// Start listening for SMS User Consent broadcasts from senderPhoneNumber
// The Task<Void> will be successful if SmsRetriever was able to start
// SMS User Consent, and will error if there was an error starting.
Task<Void> task = SmsRetriever.getClient(context).startSmsUserConsent(senderPhoneNumber /* or null */);

เมื่อฟังข้อความ SMS เข้ามาแล้ว คุณสามารถให้ระบบยืนยันส่งรหัสการยืนยันไปยังหมายเลขโทรศัพท์ของผู้ใช้ ซึ่งคุณได้ไปในขั้นตอนแรก

ในอีก 5 นาทีข้างหน้า เมื่ออุปกรณ์ได้รับข้อความ SMS ที่มีรหัสแบบใช้ครั้งเดียว บริการ Google Play จะประกาศไปยังแอปของคุณเพื่อแจ้งให้ผู้ใช้ขอสิทธิ์อ่านข้อความ ข้อความจะทำให้ออกอากาศ ก็ต่อเมื่อเป็นไปตามเกณฑ์ต่อไปนี้เท่านั้น

  • ข้อความประกอบด้วยสตริงอักขระที่เป็นตัวอักษรและตัวเลขคละกัน 4-10 ตัวโดยมีตัวเลขอย่างน้อย 1 ตัว
  • หากคุณระบุหมายเลขโทรศัพท์ของผู้ส่ง โปรดทราบว่าข้อความจะส่งโดยใช้หมายเลขนั้น

จัดการการออกอากาศเหล่านี้ด้วยตัวรับสัญญาณออกอากาศที่มีสิทธิ์ SEND_PERMISSION และตอบสนอง Intent SMS_RETRIEVED_ACTION ในการสร้างและลงทะเบียน Broadcast Receiver ให้ทำดังนี้

Kotlin

private val SMS_CONSENT_REQUEST = 2  // Set to an unused request code
private val smsVerificationReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
            val extras = intent.extras
            val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as Status

            when (smsRetrieverStatus.statusCode) {
                CommonStatusCodes.SUCCESS -> {
                    // Get consent intent
                    val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
                    try {
                        // Start activity to show consent dialog to user, activity must be started in
                        // 5 minutes, otherwise you'll receive another TIMEOUT intent
                        startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
                    } catch (e: ActivityNotFoundException) {
                        // Handle the exception ...
                    }
                }
                CommonStatusCodes.TIMEOUT -> {
                    // Time out occurred, handle the error.
                }
            }
        }
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
    registerReceiver(smsVerificationReceiver, SmsRetriever.SEND_PERMISSION, intentFilter)
}

Java

private static final int SMS_CONSENT_REQUEST = 2;  // Set to an unused request code
private final BroadcastReceiver smsVerificationReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
            Bundle extras = intent.getExtras();
            Status smsRetrieverStatus = (Status) extras.get(SmsRetriever.EXTRA_STATUS);

            switch (smsRetrieverStatus.getStatusCode()) {
                case CommonStatusCodes.SUCCESS:
                    // Get consent intent
                    Intent consentIntent = extras.getParcelable(SmsRetriever.EXTRA_CONSENT_INTENT);
                    try {
                        // Start activity to show consent dialog to user, activity must be started in
                        // 5 minutes, otherwise you'll receive another TIMEOUT intent
                        startActivityForResult(consentIntent, SMS_CONSENT_REQUEST);
                    } catch (ActivityNotFoundException e) {
                        // Handle the exception ...
                    }
                    break;
                case CommonStatusCodes.TIMEOUT:
                    // Time out occurred, handle the error.
                    break;
            }
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // ...

    IntentFilter intentFilter = new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION);
    registerReceiver(smsVerificationReceiver, SmsRetriever.SEND_PERMISSION, intentFilter);
}

เมื่อเริ่มต้นกิจกรรมสำหรับ EXTRA_CONSENT_INTENT จะเป็นข้อความแจ้งผู้ใช้ว่ามีสิทธิ์อ่านเนื้อหาของข้อความเพียงครั้งเดียว

3. รับรหัสยืนยันจากข้อความ

ในเมธอด onActivityResult() ให้จัดการการตอบสนองของผู้ใช้ต่อคำขอสิทธิ์ของคุณ หากได้รับรหัสผลลัพธ์ RESULT_OK แสดงว่าผู้ใช้ได้รับสิทธิ์ให้อ่านเนื้อหาของข้อความ และคุณจะดูข้อความได้จาก Intent

Kotlin

public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        // ...
        SMS_CONSENT_REQUEST ->
            // Obtain the phone number from the result
            if (resultCode == Activity.RESULT_OK && data != null) {
                // Get SMS message content
                val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
                // Extract one-time code from the message and complete verification
                // `message` contains the entire text of the SMS message, so you will need
                // to parse the string.
                val oneTimeCode = parseOneTimeCode(message) // define this function

                // send one time code to the server
            } else {
                // Consent denied. User can type OTC manually.
            }
    }
}

Java

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        // ...
        case SMS_CONSENT_REQUEST:
            if (resultCode == RESULT_OK) {
                // Get SMS message content
                String message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE);
                // Extract one-time code from the message and complete verification
                // `sms` contains the entire text of the SMS message, so you will need
                // to parse the string.
                String oneTimeCode = parseOneTimeCode(message); // define this function

                // send one time code to the server
            } else {
                // Consent canceled, handle the error ...
            }
            break;
    }
}

หลังจากได้รับข้อความแล้ว คุณสามารถแยกวิเคราะห์รหัสยืนยันและกรอกแบบฟอร์มอัตโนมัติ หรือดำเนินการตามขั้นตอนการยืนยันให้เสร็จสมบูรณ์