لإثبات ملكية أرقام الهواتف تلقائيًا، عليك تنفيذ كلاً من جزء العميل والخادم أثناء عملية إثبات الملكية. يوضّح هذا المستند طريقة تنفيذ جزء العميل في تطبيق Android.
لبدء عملية إثبات ملكية رقم الهاتف في أحد تطبيقات Android، عليك إرسال رقم الهاتف إلى خادم إثبات الملكية واستدعاء واجهة برمجة التطبيقات لاسترداد الرسائل القصيرة SMS لبدء الاستماع إلى رسالة قصيرة تحتوي على رمز يتم استخدامه مرة واحدة لتطبيقك. وبعد تلقّي الرسالة، سترسل الرمز الذي يتم استخدامه مرة واحدة إلى خادمك لإكمال عملية إثبات الملكية.
قبل البدء
لإعداد تطبيقك، أكمِل الخطوات الواردة في الأقسام التالية.
المتطلّبات الأساسية للتطبيق
تأكَّد من أنّ ملف الإصدار لتطبيقك يتضمّن القيم التالية:
- إصدار minSdkإصدار من 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.7.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
وارفِق نجاح المستمعين في المَهمة باسترداد الرسائل القصيرة 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
،
الذي يتضمّن نص الرسالة. يمكنك استخدام 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)