Чтобы получить доступ к функциям игровых сервисов 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()
и передайте параметры, настроенные на предыдущих шагах. Если вызов выполнен успешно, Google Sign-In API возвращает экземпляр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()
. - Если вход не был успешным, вы можете отправить намерение входа, чтобы запустить интерактивный процесс входа. Список дополнительных приемников обратного вызова, которые вы можете использовать, см. в руководстве разработчика Tasks API и справочнике
Task
API.
- Если задача входа выполнена успешно, получите объект
В следующем фрагменте кода показано, как ваше приложение может выполнять автоматический вход:
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 Sign-In API отображает пользовательский интерфейс, который предлагает игроку ввести свои учетные данные для входа. Такой подход упрощает разработку вашего приложения, поскольку действие входа обрабатывает такие сценарии, как необходимость обновления сервисов 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
, который возвращает Google Sign-In API, не содержит никакой информации об игроке. Если в вашей игре используется информация об игроке, такая как отображаемое имя и идентификатор игрока, вы можете выполнить следующие действия, чтобы получить эту информацию.
- Получите объект
PlayersClient
, вызвав методgetPlayersClient()
и передавGoogleSignInAccount
в качестве параметра. - Используйте методы
PlayersClient
для асинхронной загрузки объектаPlayer
, содержащего информацию об игроке. Например, вы можете вызватьgetCurrentPlayer()
, чтобы загрузить текущего игрока, вошедшего в систему. Если задача возвращаетApiException
с кодом состоянияSIGN_IN_REQUIRED
, это означает, что игроку необходимо пройти повторную аутентификацию. Для этого вызовитеGoogleSignInClient.getSignInIntent()
для интерактивного входа в проигрыватель. - Если задача успешно возвращает объект
Player
, вы можете вызвать методы объектаPlayer
для получения сведений о конкретном игроке (например,getDisplayName()
илиgetPlayerId()
.
Предоставление кнопки входа
Чтобы добавить в игру стандартную кнопку входа в Google, вы можете использовать один из следующих подходов:
- Включите
com.google.android.gms.common.SignInButton
в макет основного действия; или - Создайте настраиваемую кнопку входа в соответствии с рекомендациями по фирменному стилю Google Sign-In .
Когда пользователи нажимают кнопку входа, ваша игра должна инициировать процесс входа, отправляя намерение входа, как описано в разделе Выполнение интерактивного входа .
Этот фрагмент кода показывает, как вы можете добавить кнопку входа в метод 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. } }); }