Чтобы получить доступ к функциям игровых сервисов Google Play, ваша игра должна предоставить учетную запись вошедшего в систему игрока. Если игрок не прошел аутентификацию, ваша игра может столкнуться с ошибками при вызове API игровых сервисов Google Play. В этой документации описывается, как реализовать беспрепятственный вход в вашу игру.
Реализация входа в систему игрока
Класс GoogleSignInClient
— это основная точка входа для получения учетной записи игрока, выполнившего вход в систему, а также для входа в систему игрока, если он ранее не сделал этого в вашем приложении на устройстве.
Чтобы создать клиент для входа, выполните следующие действия:
Создайте клиент входа в систему с помощью объекта
GoogleSignInOptions
, как показано в следующем фрагменте кода. ВGoogleSignInOptions.Builder
для настройки входа необходимо указатьGoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
.GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
Если вы хотите использовать
SnapshotsClient
, добавьте.requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
в свойGoogleSignInOptions.Builder
, как показано в следующем фрагменте кода:GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS) .build();
Вызовите метод
GoogleSignIn.getClient()
и передайте параметры, которые вы настроили на предыдущих шагах. Если вызов успешен, API входа в Google возвращает экземплярGoogleSignInClient
.
Проверьте, вошел ли игрок уже в систему
Вы можете проверить, выполнен ли уже вход в учетную запись на текущем устройстве с помощью GoogleSignIn.getLastSignedInAccount()
и имеет ли эта учетная запись необходимые разрешения, предоставленные с помощью GoogleSignIn.hasPermissions()
. Если оба условия верны — то есть getLastSignedInAccount()
возвращает ненулевое значение, а hasPermissions()
возвращает true
— вы можете безопасно использовать учетную запись, возвращенную из getLastSignedInAccount()
, даже если устройство находится в автономном режиме.
Выполните автоматический вход
Вы можете вызвать silentSignIn()
чтобы получить учетную запись игрока, вошедшего в систему в данный момент, и попытаться войти в систему игроков, не отображая пользовательский интерфейс, если они успешно вошли в ваше приложение на другом устройстве.
Метод silentSignIn()
возвращает Task<GoogleSignInAccount>
. После завершения задачи вы устанавливаете в поле GoogleSignInAccount
, которое вы объявили ранее, учетную запись для входа, которую задача возвращает в качестве результата, или значение null
, указывающее на отсутствие вошедшего в систему пользователя.
Если попытка тихого входа не удалась, вы можете дополнительно отправить намерение входа для отображения пользовательского интерфейса входа, как описано в разделе «Выполнение интерактивного входа» .
Поскольку состояние вошедшего в систему игрока может измениться, когда действие не находится на переднем плане, мы рекомендуем вызывать silentSignIn()
из метода onResume()
действия.
Чтобы выполнить вход в автоматическом режиме, выполните следующие действия:
- Вызовите метод
silentSignIn()
вGoogleSignInClient
чтобы запустить процесс автоматического входа. Этот вызов возвращает объектTask<GoogleSignInAccount>
, который содержитGoogleSignInAccount
, если автоматический вход выполнен успешно. - Обработайте успех или неудачу входа игрока, переопределив
OnCompleteListener
.- Если задача входа прошла успешно, получите объект
GoogleSignInAccount
, вызвавgetResult()
. - Если вход не удался, вы можете отправить намерение входа, чтобы запустить интерактивный процесс входа. Список дополнительных прослушивателей обратного вызова, которые вы можете использовать, см. в руководстве разработчика API задач и справочнике по 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
указывает, что игроку необходимо выполнить явное действие для входа в систему. В этом случае ваше приложение должно запустить интерактивный процесс входа, как описано в следующем разделе.
Выполните интерактивный вход
Чтобы войти в систему с помощью взаимодействия с игроком, вашему приложению необходимо запустить намерение входа. В случае успеха API входа в Google отображает пользовательский интерфейс, который предлагает игроку ввести свои учетные данные для входа в систему. Этот подход упрощает разработку приложения, поскольку действие входа обрабатывает такие сценарии, как необходимость обновления служб Google Play или отображение запросы согласия от имени вашего приложения. Результат возвращается через обратный вызов onActivityResult
.
Чтобы выполнить вход в систему в интерактивном режиме, выполните следующие действия:
Вызовите
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); }
В обратном вызове
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
, возвращаемый API входа в систему Google, не содержит никакой информации об игроке. Если в вашей игре используется информация об игроке, такая как отображаемое имя и идентификатор игрока, вы можете выполнить следующие действия, чтобы получить эту информацию.
- Получите объект
PlayersClient
, вызвав методgetPlayersClient()
и передавGoogleSignInAccount
в качестве параметра. - Используйте методы
PlayersClient
для асинхронной загрузки объектаPlayer
, содержащего информацию об игроке. Например, вы можете вызватьgetCurrentPlayer()
чтобы загрузить текущего игрока, выполнившего вход в систему. Если задача возвращаетApiException
с кодом состоянияSIGN_IN_REQUIRED
, это указывает на то, что игроку необходимо пройти повторную аутентификацию. Для этого вызовитеGoogleSignInClient.getSignInIntent()
для интерактивного входа в проигрыватель. - Если задача успешно возвращает объект
Player
, вы можете вызвать методы объектаPlayer
для получения конкретных сведений об игроке (например,getDisplayName()
илиgetPlayerId()
.
Предоставить кнопку входа
Чтобы добавить в игру стандартную кнопку входа в Google, вы можете использовать один из следующих подходов:
- Включите
com.google.android.gms.common.SignInButton
в макет основного действия; или - Создайте собственную кнопку входа в систему в соответствии с рекомендациями по фирменному оформлению входа в систему 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. } }); }
Чтобы получить доступ к функциям игровых сервисов Google Play, ваша игра должна предоставить учетную запись вошедшего в систему игрока. Если игрок не прошел аутентификацию, ваша игра может столкнуться с ошибками при вызове API игровых сервисов Google Play. В этой документации описывается, как реализовать беспрепятственный вход в вашу игру.
Реализация входа в систему игрока
Класс GoogleSignInClient
— это основная точка входа для получения учетной записи игрока, выполнившего вход в систему, а также для входа в систему игрока, если он ранее не сделал этого в вашем приложении на устройстве.
Чтобы создать клиент для входа, выполните следующие действия:
Создайте клиент входа в систему с помощью объекта
GoogleSignInOptions
, как показано в следующем фрагменте кода. ВGoogleSignInOptions.Builder
для настройки входа необходимо указатьGoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
.GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
Если вы хотите использовать
SnapshotsClient
, добавьте.requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
в свойGoogleSignInOptions.Builder
, как показано в следующем фрагменте кода:GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS) .build();
Вызовите метод
GoogleSignIn.getClient()
и передайте параметры, которые вы настроили на предыдущих шагах. Если вызов успешен, API входа в Google возвращает экземплярGoogleSignInClient
.
Проверьте, вошел ли игрок уже в систему
Вы можете проверить, выполнен ли уже вход в учетную запись на текущем устройстве с помощью GoogleSignIn.getLastSignedInAccount()
и имеет ли эта учетная запись необходимые разрешения, предоставленные с помощью GoogleSignIn.hasPermissions()
. Если оба условия верны — то есть getLastSignedInAccount()
возвращает ненулевое значение, а hasPermissions()
возвращает true
— вы можете безопасно использовать учетную запись, возвращенную из getLastSignedInAccount()
, даже если устройство находится в автономном режиме.
Выполните автоматический вход
Вы можете вызвать silentSignIn()
чтобы получить учетную запись игрока, вошедшего в систему в данный момент, и попытаться войти в систему игроков, не отображая пользовательский интерфейс, если они успешно вошли в ваше приложение на другом устройстве.
Метод silentSignIn()
возвращает Task<GoogleSignInAccount>
. После завершения задачи вы устанавливаете в поле GoogleSignInAccount
, которое вы объявили ранее, учетную запись для входа, которую задача возвращает в качестве результата, или значение null
, указывающее на отсутствие вошедшего в систему пользователя.
Если попытка тихого входа не удалась, вы можете дополнительно отправить намерение входа для отображения пользовательского интерфейса входа, как описано в разделе «Выполнение интерактивного входа» .
Поскольку состояние вошедшего в систему игрока может измениться, когда действие не находится на переднем плане, мы рекомендуем вызывать silentSignIn()
из метода onResume()
действия.
Чтобы выполнить вход в автоматическом режиме, выполните следующие действия:
- Вызовите метод
silentSignIn()
вGoogleSignInClient
чтобы запустить процесс автоматического входа. Этот вызов возвращает объектTask<GoogleSignInAccount>
, который содержитGoogleSignInAccount
, если автоматический вход выполнен успешно. - Обработайте успех или неудачу входа игрока, переопределив
OnCompleteListener
.- Если задача входа прошла успешно, получите объект
GoogleSignInAccount
, вызвавgetResult()
. - Если вход не удался, вы можете отправить намерение входа, чтобы запустить интерактивный процесс входа. Список дополнительных прослушивателей обратного вызова, которые вы можете использовать, см. в руководстве разработчика API задач и справочнике по 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
указывает, что игроку необходимо выполнить явное действие для входа в систему. В этом случае ваше приложение должно запустить интерактивный процесс входа, как описано в следующем разделе.
Выполните интерактивный вход
Чтобы войти в систему с взаимодействием с игроком, вашему приложению необходимо запустить намерение входа. В случае успеха API входа в Google отображает пользовательский интерфейс, который предлагает игроку ввести свои учетные данные для входа в систему. Этот подход упрощает разработку приложения, поскольку действие входа обрабатывает такие сценарии, как необходимость обновления служб Google Play или отображение запросы согласия от имени вашего приложения. Результат возвращается через обратный вызов onActivityResult
.
Чтобы выполнить вход в интерактивном режиме, выполните следующие действия:
Вызовите
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); }
В обратном вызове
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
, возвращаемый API входа в систему Google, не содержит никакой информации об игроке. Если в вашей игре используется информация об игроке, такая как отображаемое имя и идентификатор игрока, вы можете выполнить следующие действия, чтобы получить эту информацию.
- Получите объект
PlayersClient
, вызвав методgetPlayersClient()
и передавGoogleSignInAccount
в качестве параметра. - Используйте методы
PlayersClient
для асинхронной загрузки объектаPlayer
, содержащего информацию об игроке. Например, вы можете вызватьgetCurrentPlayer()
чтобы загрузить текущего игрока, вошедшего в систему. Если задача возвращаетApiException
с кодом состоянияSIGN_IN_REQUIRED
, это указывает на то, что игроку необходимо пройти повторную аутентификацию. Для этого вызовитеGoogleSignInClient.getSignInIntent()
для интерактивного входа в проигрыватель. - Если задача успешно возвращает объект
Player
, вы можете вызвать методы объектаPlayer
для получения конкретных сведений об игроке (например,getDisplayName()
илиgetPlayerId()
.
Предоставить кнопку входа
Чтобы добавить в игру стандартную кнопку входа в Google, вы можете использовать один из следующих подходов:
- Включите
com.google.android.gms.common.SignInButton
в макет основного действия; или - Создайте собственную кнопку входа в систему в соответствии с рекомендациями по фирменному оформлению входа в систему 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. } }); }