Following the deprecation of the
[Google Sign-In](https://android-developers.googleblog.com/2024/09/streamlining-android-authentication-credential-manager-replaces-legacy-apis.html)
API, we are removing the games v1 SDK in 2026. After February 2025, you will be unable to publish
titles that are newly integrated with games v1 SDK, on Google Play. We recommend that you use the
games v2 SDK instead.  

While existing titles with the previous games v1 integrations continue to function for a
couple of years, you are encouraged to
[migrate to v2](https://developer.android.com/games/pgs/android/migrate-to-v2)
starting June 2025.  

This guide is for using the Play Games Services v1 SDK. For information
on the latest SDK version, see the
[v2 documentation](https://developer.android.com/games/pgs/android/android-signin).

In order to access Google Play Games Services functionality, your game needs to provide the
signed-in player's account. If the player is not authenticated, your game may encounter errors
when making calls to the Google Play Games Services APIs. This documentation describes how to
implement a seamless sign-in experience in your game.

## Implement player sign-in

The [`GoogleSignInClient`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient) class is the main entry point to retrieve the account of the currently
signed-in player, and to sign-in the player if they have not previously done so on your app in the
device.
| **Note:** The [`GoogleSignInClient`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient) class makes use of the Google Play services [`Task`](https://developer.google.com/android/reference/com/google/android/gms/tasks/Task) class to return results asynchronously. To learn more about using tasks to manage threaded work, see the [Tasks API developer guide](https://developer.google.com/android/guides/tasks).

To create a sign-in client, follow these steps:

1. Create a sign-in client via the
   [`GoogleSignInOptions`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInOptions)
   object, as shown in the following code snippet. In the
   [`GoogleSignInOptions.Builder`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInOptions.Builder)
   to configure your sign-in, you must specify
   [`GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInOptions.html#DEFAULT_GAMES_SIGN_IN).

   ```
   GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
   ```
2. If you want to use a
   [`SnapshotsClient`](https://developer.google.com/android/reference/com/google/android/gms/games/SnapshotsClient),
   then add `.requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)` to your
   [`GoogleSignInOptions.Builder`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInOptions.Builder)
   as shown in the following code snippet:

   ```
   GoogleSignInOptions  signInOptions =
       new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
           .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
           .build();
   ```
   | **Caution:** Don't request any other scopes or Google profile data unless they're essential for your use case. Any other scope causes the first time silent sign-in to fail, except for users who have already signed in successfully on a different device.
3. Call the [`GoogleSignIn.getClient()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignIn.html#getClient(android.app.Activity,%0Acom.google.android.gms.auth.api.signin.GoogleSignInOptions)) method and pass in
   the options that you configured in the previous steps. If the call is
   successful, the Google Sign-In API returns an instance of
   [`GoogleSignInClient`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient).

### Check whether player is already signed in

You can check whether an account is already signed in
on the current device using [`GoogleSignIn.getLastSignedInAccount()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignIn.html#getLastSignedInAccount())
and whether this account already has the required permissions granted using
[`GoogleSignIn.hasPermissions()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignIn.html#hasPermissions()).
If both conditions are true---that is, `getLastSignedInAccount()` returns a
non-null value and `hasPermissions()` returns `true`---you can safely use
the account returned from `getLastSignedInAccount()`, even if the device is
offline.

### Perform a silent sign-in

You can call [`silentSignIn()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient.html#silentSignIn()) to retrieve the currently signed-in player's account,
and try to sign players in without displaying a user interface if they have
successfully signed in to your app on a different device.

The [`silentSignIn()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient.html#silentSignIn()) method returns a `Task<GoogleSignInAccount>`. When the task completes,
you set the [`GoogleSignInAccount`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount) field you declared earlier to the sign-in account that the task
returns as the result, or to `null`, indicating there is not a signed-in user.

If the silent sign-in attempt fails, you can optionally send the sign-in intent to display a
sign-in user interface, as described in
[Perform an interactive sign-in](https://developer.android.com/games/pgs/v1/android/signin#interactive-signin).

Since the state of the signed-in player can change when the activity is not in the foreground, we
recommended calling [`silentSignIn()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient.html#silentSignIn()) from the activity's
[`onResume()`](https://developer.android.com/reference/android/app/Activity#onResume())
method.

To perform the sign-in silently, follow these steps:

1. Call the [`silentSignIn()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient.html#silentSignIn()) method on the [`GoogleSignInClient`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient) to start the silent sign-in flow. This call returns an `Task<GoogleSignInAccount>` object which contains a [`GoogleSignInAccount`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount) if silent sign-in is successful.
2. Handle the success or failure of the player sign-in by overriding [`OnCompleteListener`](https://developer.google.com/android/reference/com/google/android/gms/tasks/OnCompleteListener).
   - If the sign-in task was successful, get the [`GoogleSignInAccount`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount) object by calling [`getResult()`](https://developer.google.com/android/reference/com/google/android/gms/tasks/Task.html#getResult()).
   - If sign-in was not successful, you can send a sign-in intent to launch an interactive sign-in flow. For a list of additional callback listeners you can use, see the [Tasks API developer guide](https://developer.google.com/android/guides/tasks) and [`Task`](https://developer.google.com/android/reference/com/google/android/gms/tasks/Task) API reference.

The following code snippet shows how your app can perform silent sign-in:  

```gdscript
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();
}
```

If the silent sign-in attempt fails, you can call
[`getException()`](https://developer.google.com/android/reference/com/google/android/gms/tasks/Task.html#getException()) to
obtain an [`ApiException`](https://developer.google.com/android/reference/com/google/android/gms/common/api/ApiException)
with the detailed status code. A status code of [`CommonStatusCodes.SIGN_IN_REQUIRED`](https://developers.google.com/android/reference/kotlin/com/google/android/gms/common/api/CommonStatusCodes#SIGN_IN_REQUIRED())
indicates that the player needs to take explicit action to sign-in. In this case, your app should
launch an interactive sign-in flow as described in the next section.

### Perform an interactive sign-in

To sign in with player interaction, your app needs to launch the sign-in intent. If successful,
the Google Sign-In API displays a user interface that prompts the player to enter their credentials
to sign in. This approach simplifies your app development, since the sign-in activity handles
scenarios such as needing to update Google Play services or showing consent prompts, on your app's
behalf. The result is returned via the
[`onActivityResult`](https://developer.android.com/reference/android/app/Activity#onActivityResult(int,%20int,%20android.content.Intent))
callback.

To perform the sign-in interactively, follow these steps:

1. Call [`getSigninIntent()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient.html#getSignInIntent()) on the [`GoogleSignInClient`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient) to obtain a sign-in intent, then call
   [`startActivity()`](https://developer.android.com/reference/android/content/Context#startActivity(android.content.Intent)) and pass in that intent. The following code snippet shows how your app can
   launch an interactive sign-in flow:

   ```scdoc
   private void startSignInIntent() {
     GoogleSignInClient signInClient = GoogleSignIn.getClient(this,
         GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN);
     Intent intent = signInClient.getSignInIntent();
     startActivityForResult(intent, RC_SIGN_IN);
   }
   ```
2. In the [`onActivityResult()`](https://developer.android.com/reference/android/app/Activity#onActivityResult(int,%20int,%20android.content.Intent))
   callback, handle the result from the returned intent.

   - If the sign-in result was successful, get the [`GoogleSignInAccount`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount) object from the `GoogleSignInResult`.
   - If sign-in result was not successful, you should handle the sign-in error (for example, by displaying an error message in an alert). The following code snippet shows how your app can handle the results of player sign-in:

   ```transact-sql
   @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();
       }
     }
   }
   ```

## Retrieve player information

The [`GoogleSignInAccount`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount) that the Google Sign-In API returns does not contain any player
information. If your game uses player information, such as the player's display name and player ID,
you can follow these steps to retrieve this information.
| **Note:** You should not store the player ID returned from the Android SDK in the game's backend, as it's possible for an untrusted device to tamper with it. Instead, you should [enable server-side API
| access](https://developer.android.com/games/pgs/v1/android/server-access) and retrieve the player ID or other data with a server-side call directly from the game's backend.

1. Obtain a [`PlayersClient`](https://developer.google.com/android/reference/com/google/android/gms/games/PlayersClient) object by calling the [`getPlayersClient()`](https://developer.google.com/android/reference/com/google/android/gms/games/Games.html#getPlayersClient(android.app.Activity,%20com.google.android.gms.auth.api.signin.GoogleSignInAccount)) method, and passing in the [`GoogleSignInAccount`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount) as a parameter.
2. Use the [`PlayersClient`](https://developer.google.com/android/reference/com/google/android/gms/games/PlayersClient) methods to asynchronously load the [`Player`](https://developer.google.com/android/reference/com/google/android/gms/games/Player) object that contains a player's information. For example, you can call [`getCurrentPlayer()`](https://developer.google.com/android/reference/com/google/android/gms/games/PlayersClient.html#getCurrentPlayer()) to load the currently signed-in player. If the task returns an [`ApiException`](https://developer.google.com/android/reference/com/google/android/gms/common/api/ApiException) with status code of [`SIGN_IN_REQUIRED`](https://developers.google.com/android/reference/kotlin/com/google/android/gms/common/api/CommonStatusCodes#SIGN_IN_REQUIRED()), this indicates that the player needs to be re-authenticated. To do this, call [`GoogleSignInClient.getSignInIntent()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient.html#getSignInIntent()) to sign in the player interactively.
3. If the task successfully returns the [`Player`](https://developer.google.com/android/reference/com/google/android/gms/games/Player) object, you can then call the methods of the [`Player`](https://developer.google.com/android/reference/com/google/android/gms/games/Player) object to retrieve specific player details (for example, [`getDisplayName()`](https://developer.google.com/android/reference/com/google/android/gms/games/Player.html#getDisplayName()) or [`getPlayerId()`](https://developer.google.com/android/reference/com/google/android/gms/games/Player.html#getPlayerId()).

## Provide a sign-in button

To provide a standard Google sign-in button in your game, you can use one of
these approaches:

- Include a [`com.google.android.gms.common.SignInButton`](https://developer.android.com/reference/com/google/android/gms/common/SignInButton) on the main activity layout; or
- Design a custom sign-in button according to the [Google Sign-In branding
  guidelines](https://developer.google.com/identity/branding-guidelines).

When users click the sign-in button, your game should initiate the sign-in flow by sending a
sign-in intent, as described in [Perform an interactive
sign-in](https://developer.android.com/games/pgs/v1/android/signin#interactive-signin).

This code snippet shows how you can add a sign-in button in the [`onCreate()`](https://developer.android.com/reference/android/app/Activity#onCreate(android.os.Bundle))
method for your activity.  

```transact-sql
@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);
}
```

The following code snippet shows how you can send the sign-in intent when the user clicks on the
sign-in button.  

```transact-sql
@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);
  }
}
```

## Display game pop-ups

You can display pop-up views in your game using the [`GamesClient`](https://developer.google.com/android/reference/com/google/android/gms/games/GamesClient) class. For example, your game
can display a "Welcome back" or an "Achievements unlocked" pop-up. To allow Google Play Games Services
to launch pop-ups in views in your game, call the
[`setViewForPopups()`](https://developer.google.com/android/reference/com/google/android/gms/games/GamesClient.html#setViewForPopups(android.view.View))
method. You can further customize where the pop-up appears in the screen by calling
[`setGravityForPopups()`](https://developer.google.com/android/reference/com/google/android/gms/games/GamesClient.html#setGravityForPopups(int)).

## Sign the player out

Signing-out is done via call the [`signOut()`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient.html#signOut()) method on the [`GoogleSignInClient`](https://developer.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInClient).  

```transact-sql
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.
        }
      });
}
```