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

بعد إيقاف واجهة برمجة التطبيقات تسجيل الدخول باستخدام Google نهائيًا، سنزيل الإصدار v1 من حزمة تطوير البرامج (SDK) للألعاب في عام 2026. بعد فبراير 2025، لن يكون بإمكانك نشر الألعاب التي تم دمجها حديثًا مع الإصدار v1 من حزمة SDK للألعاب على Google Play. ننصحك باستخدام الإصدار v2 من حزمة SDK للألعاب بدلاً من ذلك.
مع أنّ التطبيقات الحالية التي تتضمّن عمليات الدمج السابقة للإصدار 1 من "خدمات ألعاب Google Play" ستستمر في العمل لعدّة سنوات، ننصحك بنقل البيانات إلى الإصدار 2 بدءًا من يونيو 2025.
هذا الدليل مخصّص لاستخدام الإصدار 1 من حزمة تطوير البرامج (SDK) الخاصة بـ "خدمات ألعاب Play". للحصول على معلومات حول أحدث إصدار من حزمة SDK، يُرجى الاطّلاع على مستندات الإصدار 2.

للوصول إلى وظائف "خدمات ألعاب 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().
    • إذا لم تنجح عملية تسجيل الدخول، يمكنك إرسال طلب تسجيل دخول لبدء عملية تفاعلية لتسجيل الدخول. للحصول على قائمة بمستمعي عمليات معاودة الاتصال الإضافية التي يمكنك استخدامها، راجِع دليل المطوّر لواجهة برمجة التطبيقات Tasks API ومرجع واجهة برمجة التطبيقات 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" واجهة مستخدم تطلب من اللاعب إدخال بيانات الاعتماد لتسجيل الدخول. ويسهّل هذا الأسلوب عملية تطوير تطبيقك، لأنّ نشاط تسجيل الدخول يتعامل مع سيناريوهات مثل الحاجة إلى تحديث &quot;خدمات Google Play&quot; أو عرض طلبات الحصول على الموافقة، وذلك نيابةً عن تطبيقك. يتم عرض النتيجة من خلال 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() معاودة الاتصال، عالِج النتيجة من الغرض الذي تم عرضه.

    • في حال نجاح عملية تسجيل الدخول، احصل على العنصر 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 Sign-In API على أي معلومات عن اللاعب. إذا كانت لعبتك تستخدم معلومات اللاعبين، مثل الاسم المعروض ورقم تعريف اللاعب، يمكنك اتّباع الخطوات التالية لاسترداد هذه المعلومات.

  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. على سبيل المثال، يمكن أن تعرض لعبتك نافذة منبثقة بعنوان "مرحبًا بعودتك" أو "تم تحقيق إنجازات". للسماح لـ &quot;خدمات ألعاب Google Play&quot; بعرض النوافذ المنبثقة في طرق العرض في لعبتك، استدعِ الدالة 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.
        }
      });
}