Implementing Sign-in in Your Android Game

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:

  1. Attach a View.OnClickListener to 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 {
    
  2. 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.

  3. 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);
    
        // ...
    }
    
  4. 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);
        }
    }
    
  5. 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:

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.

Send feedback about...

Play Games Services for Android
Play Games Services for Android