In order to use the Google Play games services, your game needs to implement user sign-in to authenticate your player's identity with the Google Play games services. If the user is not authenticated, your game will encounter errors when making calls to the Google Play games services APIs. This documentation describes some sign-in implementation techniques that your game can use to provide a seamless user experience, as recommended by the sign-in best practices.
In order to sign players in, you will need to properly instantiate GoogleApiClient in your Activity by following the instructions in Accessing the Games APIs.
Implementing player sign-in
If your game activity calls connect() in onStart(), the GoogleApiClient will attempt to sign in silently. If the user signed in successfully before and has not signed out, the system calls the onConnected() method. If sign in fails, the system calls the onConnectionFailed() method. To resolve the connection failure, you can implement code like this:
private static int RC_SIGN_IN = 9001;
private boolean mResolvingConnectionFailure = false;
private boolean mAutoStartSignInflow = true;
private boolean mSignInClicked = false;
// ...
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (mResolvingConnectionFailure) {
// Already resolving
return;
}
// If the sign in button was clicked or if auto sign-in is enabled,
// launch the sign-in flow
if (mSignInClicked || mAutoStartSignInFlow) {
mAutoStartSignInFlow = false;
mSignInClicked = false;
mResolvingConnectionFailure = true;
// Attempt to resolve the connection failure using BaseGameUtils.
// The R.string.signin_other_error value should reference a generic
// error string in your strings.xml file, such as "There was
// an issue with sign in, please try again later."
if (!BaseGameUtils.resolveConnectionFailure(this,
mGoogleApiClient, connectionResult,
RC_SIGN_IN, getString(R.string.signin_other_error))) {
mResolvingConnectionFailure = false;
}
}
// Put code here to display the sign-in button
}
If the system calls onConnectionFailed() and the failure cannot be resolved, your game should show a sign-in button to let users sign in again when they are ready. Follow these steps to implement a sign-in button:
-
Attach a
View.OnClickListenerto your activity to allow your game to detect when the user clicks the sign-in or sign-out button.public class MyGameActivity extends Activity implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { -
Next, add the sign-in and sign-out buttons to your game activity's layout. Notice that the initial visibility of the sign-out button is set to
gone. Your game should only make the sign-out button visible after user signs in successfully. A similar sign-in button is also provided by Google Sign-in for Android. However, for simplicity, we recommend that you follow the code snippet provided here instead.<!-- sign-in button --> <com.google.android.gms.common.SignInButton android:id="@+id/sign_in_button" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <!-- sign-out button --> <Button android:id="@+id/sign_out_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sign Out" android:visibility="gone" />To learn more about how to declare layouts for Android apps, see the Layouts API guide.
-
Override
onCreate()to set up callbacks to detect if the user clicked on the sign-in and sign-out buttons.@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.sign_in_button).setOnClickListener(this); findViewById(R.id.sign_out_button).setOnClickListener(this); // ... } -
To start the sign-in flow when the user clicks the sign-in button, override the
onClick()callback:@Override public void onClick(View view) { if (view.getId() == R.id.sign_in_button) { // start the asynchronous sign in flow mSignInClicked = true; mGoogleApiClient.connect(); } else if (view.getId() == R.id.sign_out_button) { // sign out. mSignInClicked = false; Games.signOut(mGoogleApiClient); // 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); } } -
Google Play games services supports asynchronous user sign-in. To enable the system to notify your game when the user successfully signs in, override the
onConnected()method.@Override public void onConnected(Bundle connectionHint) { // show sign-out button, hide the sign-in button findViewById(R.id.sign_in_button).setVisibility(View.GONE); findViewById(R.id.sign_out_button).setVisibility(View.VISIBLE); // (your code here: update UI, enable functionality that depends on sign in, etc) }
Providing 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.SignInButtonon the main activity layout as described in the previous section; 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 explicitly calling
connect().
Signing the player in at startup
After users sign in successfully for the first time in your game, your game should sign them in automatically whenever they start the game again, until they explicitly sign out.
To add automatic sign-in, implement the following behavior in the onStart() callback.
boolean mExplicitSignOut = false;
boolean mInSignInFlow = false; // set to true when you're in the middle of the
// sign in flow, to know you should not attempt
// to connect in onStart()
GoogleApiClient mGoogleApiClient; // initialized in onCreate
@Override
protected void onStart() {
super.onStart();
if (!mInSignInFlow && !mExplicitSignOut) {
// auto sign in
mGoogleApiClient.connect();
}
}
@Override
public void onClick (View view) {
if (view.getId() == R.id.sign_out_button) {
// user explicitly signed out, so turn off auto sign in
mExplicitSignOut = true;
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
Games.signOut(mGoogleApiClient);
mGoogleApiClient.disconnect();
}
}
// ...
}
You can customize how the Google Play Games 'Connecting' pop-up is displayed
during sign-in by using setShowConnectingPopup(). By default, this pop-up is always
displayed when the user signs in. Optionally, you can change where the pop-up
appears in your screen by setting the gravity parameter in
setShowConnectingPopup(). The default gravity is CENTER.
Saving player progress before sign-in
Your game should save users' progress locally even if they are not signed in, then upload that progress when they choose to sign in later. This prevents users from losing their game progress even if they decide to postpone signing in to your game.
To reduce code complexity, your game can use a game progress data object to cache
the player's score and the achievements. When the Google API client establishes a
connection, it can upload this object to the Google Play games services. The
following code snippet shows how your game can cache the user's progress in the
MyGameProgress class.
MyGameProgress mGameProgress = ....;
// when user finishes level:
mGameProgress.addScore(userScore);
mGameProgress.addAchievement(fooAchievement);
mGameProgress.addAchievement(barAchievement);
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
mGameProgress.save(mGoogleApiClient);
}
@Override
protected void onConnected() {
// sign in successful, so save progress if we have any.
if (mGameProgress != null) {
mGameProgress.save(mGoogleApiClient);
}
// ...
}
Checking if a user is signed in
To check if the user is signed-in, call isConnected().
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
// signed in. Show the "sign out" button and explanation.
// ...
} else {
// not signed in. Show the "sign in" button and explanation.
// ...
}
Signing the player out
Call signOut() to sign the user out of the
Google Play games services. If your game is using other Google Play services, make sure to
also sign the user out of those services (for example, call clearDefaultAccount() to sign out of their Google
account). Also, your game should set a flag to indicate that the user explicitly
signed out, then check that flag the next time the game activity's onStart() method is called. Based on
the flag value, your game can then determine whether or not to call
connect()
to sign the user in.