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
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.
To create a sign-in client, follow these steps:
Create a sign-in client via the
GoogleSignInOptions
object, as shown in the following code snippet. In theGoogleSignInOptions.Builder
to configure your sign-in, you must specifyGoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
.GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
If you want to use a
SnapshotsClient
, then add.requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
to yourGoogleSignInOptions.Builder
as shown in the following code snippet:GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS) .build();
Call the
GoogleSignIn.getClient()
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 ofGoogleSignInClient
.
Check whether player is already signed in
You can check whether an account is already signed in
on the current device using GoogleSignIn.getLastSignedInAccount()
and whether this account already has the required permissions granted using
GoogleSignIn.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()
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()
method returns a Task<GoogleSignInAccount>
. When the task completes,
you set the 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.
Since the state of the signed-in player can change when the activity is not in the foreground, we
recommended calling silentSignIn()
from the activity's
onResume()
method.
To perform the sign-in silently, follow these steps:
- Call the
silentSignIn()
method on theGoogleSignInClient
to start the silent sign-in flow. This call returns anTask<GoogleSignInAccount>
object which contains aGoogleSignInAccount
if silent sign-in is successful. - Handle the success or failure of the player sign-in by overriding
OnCompleteListener
.- If the sign-in task was successful, get the
GoogleSignInAccount
object by callinggetResult()
. - 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
and
Task
API reference.
- If the sign-in task was successful, get the
The following code snippet shows how your app can perform silent sign-in:
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()
to
obtain an ApiException
with the detailed status code. A status code of 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
callback.
To perform the sign-in interactively, follow these steps:
Call
getSigninIntent()
on theGoogleSignInClient
to obtain a sign-in intent, then callstartActivity()
and pass in that intent. The following code snippet shows how your app can launch an interactive sign-in flow:private void startSignInIntent() { GoogleSignInClient signInClient = GoogleSignIn.getClient(this, GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN); Intent intent = signInClient.getSignInIntent(); startActivityForResult(intent, RC_SIGN_IN); }
In the
onActivityResult()
callback, handle the result from the returned intent.- If the sign-in result was successful, get the
GoogleSignInAccount
object from theGoogleSignInResult
. - 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:
@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(); } } }
- If the sign-in result was successful, get the
Retrieve player information
The 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.
- Obtain a
PlayersClient
object by calling thegetPlayersClient()
method, and passing in theGoogleSignInAccount
as a parameter. - Use the
PlayersClient
methods to asynchronously load thePlayer
object that contains a player’s information. For example, you can callgetCurrentPlayer()
to load the currently signed-in player. If the task returns anApiException
with status code ofSIGN_IN_REQUIRED
, this indicates that the player needs to be re-authenticated. To do this, callGoogleSignInClient.getSignInIntent()
to sign in the player interactively. - If the task successfully returns the
Player
object, you can then call the methods of thePlayer
object to retrieve specific player details (for example,getDisplayName()
orgetPlayerId()
.
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
on the main activity layout; or - Design a custom sign-in button according to the Google Sign-In 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.
This code snippet shows how you can add a sign-in button in the onCreate()
method for your activity.
@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.
@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
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()
method. You can further customize where the pop-up appears in the screen by calling
setGravityForPopups()
.
Sign the player out
Signing-out is done via call the signOut()
method on the 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. } }); }