SMS doğrulama kodunu okumak için bir kerelik izin isteyin

Bu sayfada, tek bir SMS doğrulama mesajını okumak üzere kullanıcıdan izin istemek için SMS Kullanıcı İzni API'sinin nasıl kullanılacağı açıklanmaktadır. Kullanıcı onay verirse API, doğrulama kodunu alabileceğiniz ve doğrulama işlemini tamamlayabileceğiniz mesaj metnini döndürür.

Bağımlılıkları yükleyin

Play Hizmetleri kimlik doğrulama bileşenini uygulamanızın build.gradle dosyasına 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. Kullanıcının telefon numarasını alın

Kullanıcının telefon numarasına sahip değilseniz, bir SMS doğrulama akışına başlamadan önce bunu isteyin.

Uygulamanıza uygun bir şekilde kullanıcının telefon numarasını edinebilirsiniz. Kullanıcının hesabını oluşturmak için bu bilgiler gerekli değilse, kullanıcının telefon numarasını doldurmasına yardımcı olmak için Parolalar için Akıllı Kilit ipucu seçiciyi kullanmayı düşünün. İpucu seçiciyi kullanmak için:

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. Gelen mesajları dinlemeye başlayın

Ardından, gelen mesajları dinlemeye başlamak için SMS Kullanıcı İzni API'sinin startSmsUserConsent() yöntemini startSmsUserConsent() . SMS mesajının geleceği telefon numarasını biliyorsanız, belirtin (aksi takdirde, null bırakın). Bu şekilde, SMS Kullanıcı İzni API'si yalnızca bu numaradan gelen mesajları tetikleyecektir.

Dinlemeye başlamak için:

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 */);

Gelen SMS mesajlarını dinledikten sonra, doğrulama sisteminizin doğrulama kodunu, ilk adımda aldığınız kullanıcının telefon numarasına göndermesini sağlayabilirsiniz.

Sonraki beş dakika boyunca, cihaz bir kerelik kod içeren bir SMS mesajı aldığında, Play hizmetleri uygulamanıza, kullanıcıdan mesajı okuma izni isteme niyetini yayınlayacaktır. Bir mesaj, yayını yalnızca şu kriterleri karşılıyorsa tetikler:

  • Mesaj, en az bir rakam içeren 4-10 karakterlik alfanümerik bir dizi içerir.
  • Mesaj, kullanıcının kişilerinde olmayan bir telefon numarası tarafından gönderilmiştir.
  • Gönderenin telefon numarasını belirttiyseniz, mesaj bu numara tarafından gönderilmiştir.

Bu yayınları, SEND_PERMISSION iznine sahip ve SMS_RETRIEVED_ACTION amaçlarına yanıt veren bir yayın alıcısı ile gerçekleştirin. Yayın alıcısını oluşturmak ve kaydetmek için:

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 için bir etkinlik EXTRA_CONSENT_INTENT , kullanıcıdan mesajın içeriğini okumak için bir kerelik izin EXTRA_CONSENT_INTENT olursunuz.

3. Doğrulama kodunu bir mesajdan alın

onActivityResult() yönteminde, kullanıcının izin isteğinize verdiği yanıtı onActivityResult() . RESULT_OK sonuç kodunu RESULT_OK , kullanıcı mesajın içeriğini okuma izni verir ve mesaj metnini amaçtan alabilirsiniz.

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;
    }
}

Mesaj metnini aldıktan sonra, doğrulama kodunu ayrıştırabilir ve formu otomatik olarak doldurabilir veya başka bir şekilde doğrulama akışını tamamlayabilirsiniz.