تسجيل الدخول في ألعاب Android

لتتمكن من الدخول إلى وظائف خدمات ألعاب Google Play، يجب أن توفر اللعبة حساب اللاعب الذي تم تسجيل دخوله. إذا لم تتم مصادقة اللاعب، فقد تواجه لعبتك أخطاء عند إجراء مكالمات إلى واجهات برمجة تطبيقات خدمات ألعاب Google Play. توضح هذه الوثائق كيفية تنفيذ تجربة سلسة لتسجيل الدخول إلى لعبتك.

تنفيذ تسجيل دخول اللاعب

تُعد فئة GoogleSignInClient نقطة الدخول الرئيسية لاسترداد حساب المشغل الذي تم تسجيل الدخول إليه حاليًا، ولتسجيل الدخول إلى المشغل إذا لم يسبق له إجراء ذلك على تطبيقك في الجهاز.

لإنشاء برنامج تسجيل دخول، اتبع الخطوات التالية:

  1. أنشئ برنامج تسجيل دخول من خلال كائن GoogleSignInOptions، كما هو موضّح في مقتطف الرمز التالي. في GoogleSignInOptions.Builder لإعداد تسجيل الدخول، يجب تحديد GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN.

    GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
  2. إذا أردت استخدام SnapshotsClient، أضِف .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS) إلى GoogleSignInOptions.Builder كما هو موضّح في مقتطف الرمز التالي:

    GoogleSignInOptions  signInOptions =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
            .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
            .build();
  3. عليك استدعاء طريقة GoogleSignIn.getClient() وتمرير الخيارات التي قمت بتهيئتها في الخطوات السابقة. إذا نجحت المكالمة، ستعرض واجهة برمجة تطبيقات تسجيل الدخول إلى Google نسخة افتراضية من GoogleSignInClient.

التحقّق مما إذا كان اللاعب مُسجّل الدخول

يمكنك التحقُّق مما إذا كان قد سبق تسجيل الدخول إلى أحد الحسابات على الجهاز الحالي باستخدام GoogleSignIn.getLastSignedInAccount() وما إذا كان هذا الحساب يمتلك الأذونات المطلوبة التي تم منحها باستخدام GoogleSignIn.hasPermissions(). إذا تمّ استيفاء كلا الشرطين، أي أنّ الدالة getLastSignedInAccount() تعرض قيمة غير فارغة وتعرض hasPermissions() true، يمكنك استخدام الحساب الذي تم إرجاعه من getLastSignedInAccount() بأمان، حتى إذا كان الجهاز غير متصل بالإنترنت.

إجراء تسجيل دخول بدون مطالبة

يمكنك الاتصال بـ silentSignIn() لاسترداد حساب المشغل الذي تم تسجيل الدخول إليه حاليًا، ومحاولة تسجيل دخول اللاعبين بدون عرض واجهة المستخدم إذا تم تسجيل الدخول بنجاح إلى تطبيقك على جهاز آخر.

تعرض طريقة silentSignIn() Task<GoogleSignInAccount>. عند اكتمال المهمة، يمكنك ضبط الحقل GoogleSignInAccount الذي أعلنتَه سابقًا لحساب تسجيل الدخول أن المهمة تعرض كنتيجة، أو على null، للإشارة إلى عدم وجود مستخدم سجّل الدخول.

إذا تعذّرت محاولة تسجيل الدخول بدون مطالبة، يمكنك اختياريًا إرسال نية تسجيل الدخول لعرض واجهة مستخدم تسجيل الدخول، كما هو موضّح في إجراء تسجيل الدخول التفاعلي.

نظرًا لأن حالة المشغل الذي تم تسجيل الدخول إليه يمكن أن تتغير عندما لا يكون النشاط في المقدمة، فإننا نقترح الاتصال بـ silentSignIn() من خلال طريقة النشاط onResume().

لإجراء تسجيل الدخول بشكل غير ملحوظ، اتبع الخطوات التالية:

  1. يمكنك استدعاء طريقة silentSignIn() على GoogleSignInClient لبدء تدفق تسجيل الدخول بدون مطالبة. تعرض هذه الاستدعاء كائن Task<GoogleSignInAccount> الذي يحتوي على GoogleSignInAccount إذا تم تسجيل الدخول بنجاح.
  2. يمكنك معالجة نجاح أو فشل عملية تسجيل دخول اللاعب من خلال إلغاء OnCompleteListener.
    • إذا نجحت مهمة تسجيل الدخول، يمكنك الحصول على الكائن GoogleSignInAccount من خلال استدعاء getResult().
    • إذا لم ينجح تسجيل الدخول، يمكنك إرسال نية تسجيل الدخول لبدء تدفق تسجيل الدخول التفاعلي. للحصول على قائمة بالمستمعين الإضافيين الذين يمكنك معاودة الاتصال بهم، يمكنك الاطّلاع على دليل مطوّري برامج واجهة برمجة تطبيقات "مهام Google" وTask مرجع واجهة برمجة التطبيقات.

يعرض مقتطف الشفرة التالي كيفية إجراء تطبيقك لعملية تسجيل دخول صامت:

private void signInSilently() {
  GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
  GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
  if (GoogleSignIn.hasPermissions(account, signInOptions.getScopeArray())) {
    // Already signed in.
    // The signed in account is stored in the 'account' variable.
    GoogleSignInAccount signedInAccount = account;
  } else {
    // Haven't been signed-in before. Try the silent sign-in first.
    GoogleSignInClient signInClient = GoogleSignIn.getClient(this, signInOptions);
    signInClient
        .silentSignIn()
        .addOnCompleteListener(
            this,
            new OnCompleteListener<GoogleSignInAccount>() {
              @Override
              public void onComplete(@NonNull Task<GoogleSignInAccount> task) {
                if (task.isSuccessful()) {
                  // The signed in account is stored in the task's result.
                  GoogleSignInAccount signedInAccount = task.getResult();
                } else {
                  // Player will need to sign-in explicitly using via UI.
                  // See [sign-in best practices](http://developers.google.com/games/services/checklist) for guidance on how and when to implement Interactive Sign-in,
                  // and [Performing Interactive Sign-in](http://developers.google.com/games/services/android/signin#performing_interactive_sign-in) for details on how to implement
                  // Interactive Sign-in.
                }
              }
            });
  }
}

@Override
protected void onResume() {
  super.onResume();
  signInSilently();
}

إذا تعذّرت محاولة تسجيل الدخول بدون مطالبة، يمكنك استدعاء getException() للحصول على ApiException باستخدام رمز الحالة المفصّل. يشير رمز الحالة CommonStatusCodes.SIGN_IN_REQUIRED إلى أن على اللاعب اتخاذ إجراء صريح لتسجيل الدخول. في هذه الحالة، يجب أن يطلق تطبيقك خطوات تسجيل دخول تفاعلية كما هو موضح في القسم التالي.

تنفيذ تسجيل الدخول التفاعلي

لتسجيل الدخول باستخدام تفاعل اللاعبين، يحتاج تطبيقك إلى إطلاق هدف تسجيل الدخول. في حالة نجاح هذا الإجراء، تعرض واجهة برمجة تطبيقات تسجيل الدخول إلى Google واجهة مستخدم تطلب من اللاعب إدخال بيانات اعتماده لتسجيل الدخول. تبسّط هذه الطريقة تطوير تطبيقك، لأن نشاط تسجيل الدخول يتعامل مع سيناريوهات مثل الحاجة إلى تحديث خدمات Google Play أو عرض رسائل طلب الموافقة، نيابة عن تطبيقك. ويتم عرض النتيجة من خلال معاودة الاتصال onActivityResult.

لإجراء تسجيل الدخول بشكل تفاعلي، اتبع الخطوات التالية:

  1. اتّصِل بالرقم getSigninIntent() على GoogleSignInClient للحصول على نية تسجيل الدخول، ثم اتّصِل startActivity() وانقل هذه النية. يعرض مقتطف الشفرة التالي كيف يمكن لتطبيقك تشغيل تدفق تسجيل دخول تفاعلي:

    private void startSignInIntent() {
      GoogleSignInClient signInClient = GoogleSignIn.getClient(this,
          GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN);
      Intent intent = signInClient.getSignInIntent();
      startActivityForResult(intent, RC_SIGN_IN);
    }
  2. في معاودة الاتصال على onActivityResult()، يمكنك معالجة النتيجة من intent المرتجعة.

    • إذا كانت نتيجة تسجيل الدخول ناجحة، يمكنك الحصول على كائن GoogleSignInAccount من GoogleSignInResult.
    • إذا لم تنجح نتيجة تسجيل الدخول، فيجب معالجة خطأ تسجيل الدخول (على سبيل المثال، من خلال عرض رسالة خطأ في تنبيه). يعرض مقتطف الرمز التالي كيفية تعامل تطبيقك مع نتائج تسجيل دخول اللاعب:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if (requestCode == RC_SIGN_IN) {
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (result.isSuccess()) {
          // The signed in account is stored in the result.
          GoogleSignInAccount signedInAccount = result.getSignInAccount();
        } else {
          String message = result.getStatus().getStatusMessage();
          if (message == null || message.isEmpty()) {
            message = getString(R.string.signin_other_error);
          }
          new AlertDialog.Builder(this).setMessage(message)
              .setNeutralButton(android.R.string.ok, null).show();
        }
      }
    }

جارٍ استرداد معلومات المشغّل

لا تحتوي GoogleSignInAccount التي تعرضها واجهة برمجة تطبيقات تسجيل الدخول إلى Google على أي معلومات مشغّل. إذا كانت لعبتك تستخدم معلومات اللاعب، مثل الاسم المعروض للاعب والاسم التعريفي للاعب، فيمكنك اتباع هذه الخطوات لاسترداد هذه المعلومات.

  1. يمكنك الحصول على كائن PlayersClient من خلال استدعاء الطريقة getPlayersClient() وتمرير GoogleSignInAccount كمعلّمة.
  2. يمكنك استخدام طرق PlayersClient لتحميل العنصر Player الذي يحتوي على معلومات اللاعب بشكل غير متزامن. على سبيل المثال، يمكنك الاتصال بـ getCurrentPlayer() لتحميل المشغّل الذي تم تسجيل الدخول إليه حاليًا. إذا كانت المهمة تعرض ApiException برمز الحالة SIGN_IN_REQUIRED، فهذا يشير إلى أن اللاعب بحاجة إلى إعادة المصادقة. لتنفيذ هذا الإجراء، يمكنك الاتصال GoogleSignInClient.getSignInIntent() لتسجيل الدخول من المشغّل بشكل تفاعلي.
  3. إذا نجحت المهمة في عرض الكائن Player، يمكنك عندئذٍ استدعاء طرق الكائن Player لاسترداد تفاصيل لاعب محددة (على سبيل المثال، getDisplayName() أو getPlayerId().

توفير زر تسجيل الدخول

لتوفير زر قياسي في Google لتسجيل الدخول إلى لعبتك، يمكنك استخدام إحدى الطرق التالية:

عندما ينقر المستخدمون على زر تسجيل الدخول، يجب أن تبدأ اللعبة إجراءات تسجيل الدخول من خلال إرسال نية تسجيل دخول، كما هو موضح في إجراء تسجيل الدخول التفاعلي.

يعرض مقتطف الرمز هذا كيفية إضافة زر تسجيل الدخول في طريقة onCreate() لنشاطك.

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_sign_in);
  findViewById(R.id.sign_in_button).setOnClickListener(this);
  findViewById(R.id.sign_out_button).setOnClickListener(this);
}

يعرض مقتطف الشفرة التالي كيفية إرسال نية تسجيل الدخول عندما ينقر المستخدم على زر تسجيل الدخول.

@Override
public void onClick(View view) {
  if (view.getId() == R.id.sign_in_button) {
    // start the asynchronous sign in flow
    startSignInIntent();
  } else if (view.getId() == R.id.sign_out_button) {
    // sign out.
    signOut();
    // show sign-in button, hide the sign-out button
    findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
    findViewById(R.id.sign_out_button).setVisibility(View.GONE);
  }
}

عرض النوافذ المنبثقة للألعاب

يمكنك عرض النوافذ المنبثقة في لعبتك باستخدام صف GamesClient. على سبيل المثال، يمكن أن تعرض لعبتك نافذة منبثقة تعرض رسالة "مرحبًا بك مرة أخرى" أو "تم فتح الإنجازات". للسماح لخدمات ألعاب Google Play بتشغيل النوافذ المنبثقة في مرات المشاهدة داخل اللعبة، اتصل بالطريقة setViewForPopups(). يمكنك أيضًا تخصيص مكان ظهور النافذة المنبثقة على الشاشة من خلال الاتصال على setGravityForPopups().

جارٍ تسجيل خروج اللاعب

يتم تسجيل الخروج عن طريق استدعاء طريقة signOut() في GoogleSignInClient.

private void signOut() {
  GoogleSignInClient signInClient = GoogleSignIn.getClient(this,
      GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN);
  signInClient.signOut().addOnCompleteListener(this,
      new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
          // at this point, the user is signed out.
        }
      });
}