درخواست درستی‌سنجی پیامک در برنامه Android

برای درستی‌سنجی خودکار شماره‌های تلفن، باید هم بخش مشتری و هم بخش سرور جریان درستی‌سنجی را پیاده‌سازی کنید. این سند نحوه پیاده‌سازی بخش کارخواه را در برنامه Android شرح می‌دهد.

برای شروع جریان درستی‌سنجی شماره تلفن در برنامه Android، شماره تلفن را به سرور درستی‌سنجی‌تان ارسال می‌کنید و با SMS Retriever API تماس می‌گیرید تا گوش دادن به پیامک حاوی کد یک‌باره برای برنامه‌تان را شروع کند. پس‌از دریافت پیام، کد یک‌باره را به سرورتان برمی‌گردانید تا فرایند درستی‌سنجی تکمیل شود.

برای آماده‌سازی برنامه‌تان، مراحل بخش‌های زیر را تکمیل کنید.

پیش‌نیازهای برنامه

مطمئن شوید فایل ساخت برنامه‌تان از مقادیر زیر استفاده می‌کند:

  • حداقل نسخه کیت توسعه نرم‌افزار ۱۹ یا بالاتر
  • compileSdkVersion برابر با ۲۸ یا بالاتر

پیکربندی برنامه

در فایل build.gradle سطح پروژه، مخزن Maven Google و مخزن مرکزی Maven را در هر دو بخش buildscript و allprojects اضافه کنید:

buildscript {
    repositories {
        google()
        mavenCentral()
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

وابستگی خدمات Google Play را برای SMS Retriever API به فایل ساخت Gradle مدول خود اضافه کنید، که معمولاً app/build.gradle است:

dependencies {
  implementation 'com.google.android.gms:play-services-auth:22.0.0'
  implementation 'com.google.android.gms:play-services-auth-api-phone:18.3.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
      }
  }
}

راه‌اندازی بازیابی پیامک

وقتی آماده درستی‌سنجی شماره تلفن کاربر هستید، نمونه‌ای از شیء SmsRetrieverClient را دریافت کنید، با startSmsRetriever تماس بگیرید، و شنوندگان موفقیت و شکست را به تکلیف بازیابی پیامک پیوست کنید:

// 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
    // ...
  }
});

تکلیف بازیابی پیامک تا پنج دقیقه منتظر پیامکی می‌ماند که حاوی رشته‌ای منحصربه‌فرد برای شناسایی برنامه شما باشد.

ارسال شماره تلفن به سرور شما

پس‌از دریافت شماره تلفن کاربر و شروع گوش دادن به پیامک‌ها، شماره تلفن کاربر را بااستفاده از هر روشی (معمولاً با درخواست HTTPS POST) به سرور درستی‌سنجی خود ارسال کنید.

سرور شما پیام درستی‌سنجی تولید می‌کند و آن را ازطریق پیامک به شماره تلفنی که مشخص کرده‌اید ارسال می‌کند. انجام درستی‌سنجی پیامکی در سرور را ببینید.

دریافت کردن پیام‌های درستی‌سنجی

وقتی پیام درستی‌سنجی در دستگاه کاربر دریافت می‌شود، خدمات Play به‌طور صریح یک SmsRetriever.SMS_RETRIEVED_ACTION Intent را به برنامه شما همه‌فرستی می‌کند، که حاوی نوشتار پیام است. برای دریافت این پیام درستی‌سنجی، از 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>

کد یک‌بارمصرف را از پیام درستی‌سنجی به سرورتان ارسال کنید

اکنون که متن پیام درستی‌سنجی را دارید، از عبارت باقاعده یا منطق دیگری برای دریافت کد یک‌بارمصرف از پیام استفاده کنید. قالب کد یک‌بارمصرف به نحوه پیاده‌سازی آن در سرورتان بستگی دارد.

درنهایت، کد یک‌بارمصرف را ازطریق اتصال امن به سرورتان ارسال کنید. وقتی سرورتان کد یک‌بارمصرف را دریافت می‌کند، ثبت می‌کند که شماره تلفن درستی‌سنجی شده است.