للتحقق من أرقام الهواتف تلقائيًا، يجب تنفيذ أجزاء البرنامج والخادم من عملية إثبات الملكية. يوضح هذا المستند كيفية تنفيذ جزء العميل في تطبيق Android.
لبدء عملية التحقق من رقم الهاتف في أحد تطبيقات Android، يجب إرسال رقم الهاتف إلى خادم التحقق واستدعاء واجهة برمجة تطبيقات استرداد الرسائل القصيرة SMS لبدء الاستماع إلى رسالة قصيرة SMS تحتوي على رمز يتم استخدامه مرة واحدة لتطبيقك.
قبل البدء
لإعداد تطبيقك، أكمِل الخطوات الواردة في الأقسام التالية.
المتطلبات الأساسية للتطبيق
تأكد من أن ملف إصدار تطبيقك يستخدم القيم التالية:
- إصدار minSdkVersion من 19 أو أعلى
- إصدار aggregateSdkVersion من الإصدار 28 أو أحدث
تهيئة تطبيقك
في ملف build.gradle على مستوى مشروعك، عليك تضمين مستودع Google Maven
ومستودع Maven المركزي
في القسمين buildscript
وallprojects
:
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
أضف التبعية خدمات Google Play
لواجهة برمجة تطبيقات استرداد الرسائل القصيرة SMS إلى ملف إنشاء Gradle في الوحدة،
والتي عادة ما تكون app/build.gradle
:
dependencies {
implementation 'com.google.android.gms:play-services-auth:20.4.1'
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
، وأرفِق المستمعين الذين تعذّر عليهم تحقيق النجاح في الرسائل القصيرة 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 التي تحتوي على سلسلة فريدة تعرّف تطبيقك.
3- إرسال رقم الهاتف إلى خادمك
بعد أن حصلت على رقم هاتف المستخدم وبدأت في الاستماع لرسائل SMS، أرسل رقم هاتف المستخدم إلى خادم إثبات الملكية باستخدام أي طريقة (عادةً مع طلب HTTPS POST).
ينشئ الخادم رسالة تحقق ويرسلها عبر رسالة قصيرة SMS إلى رقم الهاتف الذي حددته. راجع تنفيذ عملية التحقق من خلال الرسائل القصيرة SMS على الخادم.
4. تلقي رسائل التحقق
عندما يتم استلام رسالة تحقق على جهاز المستخدم، فإن خدمات 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. 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
باستخدام فلتر الأهداف
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)