Search code examples
androidgoogle-apigoogle-play-gamesgoogle-api-client

Implementing Google Play Game Services - How to let user sign in


It's my first time working with a google API as I'm fairly new to android programming. I've been trying to implement google play game services and display leaderboards in my app (it's a game as you may have guessed), and have had some difficulty following along with google's documentation.

I have set a button and would like to let the user sign in when it is tapped, and leave the user logged on until they log out afterwards. I have programmed this following the documentation:

public class MainActivity extends AppCompatActivity implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

  Button bLeaderboard;

  private GoogleApiClient mGoogleApiClient;

  private static int RC_SIGN_IN = 9001;

  private boolean mResolvingConnectionFailure = false;
  private boolean mAutoStartSignInflow = true;
  private boolean mSignInClicked = false;


@Override
@SuppressLint("NewApi")
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    bLeaderboard = (Button) findViewById(R.id.bLeaderboard);
    bLeaderboard.setOnClickListener(this);

     mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Games.API).addScope(Games.SCOPE_GAMES)
            .build();
}

@Override
public void onClick(View v) {
    switch (v.getId()) {

        case R.id.bLeaderboard:

            mSignInClicked = true;
            mGoogleApiClient.connect();
}

}

The problem is that whenever I tap on the leaderboard button the app crashes and I get this error message:

AndroidRuntime: FATAL EXCEPTION: main Process: com.example.game, PID: 26284 java.lang.IllegalStateException: A fatal developer error has occurred. Check the logs for further information. at com.google.android.gms.common.internal.zzd$zza.zzc(Unknown Source) at com.google.android.gms.common.internal.zzd$zza.zzv(Unknown Source) at com.google.android.gms.common.internal.zzd$zze.zzasf(Unknown Source) at com.google.android.gms.common.internal.zzd$zzd.handleMessage(Unknown Source) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

I have also been unable to understand what to do with these three implemented methods:

@Override
public void onConnected(@Nullable Bundle bundle) {
}

@Override
public void onConnectionSuspended(int i) {
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

Any help is greatly appreciated as I have not been able to find any tutorials on this except for google's documentation, which as I said earlier, I struggle to comprehend and follow.


Solution

  • This works for me correctly

     public class MainActivity extends ActionBarActivity implements  GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
    
    // Client used to interact with Google APIs
    private GoogleApiClient mGoogleApiClient;
    private static int RC_SIGN_IN = 9001;
    
    private boolean mResolvingConnectionFailure = false;
    private boolean mAutoStartSignInflow = true;
    private boolean mSignInClicked = false;
    GameHelper gameHelper;
    
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
    
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Games.API).addScope(Games.SCOPE_GAMES)
                .build();
        gameHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
        gameHelper.enableDebugLog(true);
        gameHelper.setup(new GameHelper.GameHelperListener() {
            @Override
            public void onSignInFailed() {
            Toast.makeText(getApplicationContext(),"Please Check Your Internet Connection!",Toast.LENGTH_LONG).show();
            }
    
            @Override
            public void onSignInSucceeded() {
                Toast.makeText(getApplicationContext(),"Signed in Succeed",Toast.LENGTH_LONG).show();
            }
        });
    
    
    
        setContentView(view);
    
        //for load all Score card
    
    
    
        scorecard=(Button)findViewById(R.id.score_card);
        scorecard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
    
    
                startActivityForResult(Games.Leaderboards.getAllLeaderboardsIntent(mGoogleApiClient), 1);
    
            }
        });
    
    
    
    
    
    }
    private boolean isScoreResultValid(final Leaderboards.LoadPlayerScoreResult scoreResult) {
        return scoreResult != null && GamesStatusCodes.STATUS_OK == scoreResult.getStatus().getStatusCode() && scoreResult.getScore() != null;
    }
    
    
    
    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }
    
    @Override
    public void onConnected(Bundle connectionHint) {
        // The player is signed in. Hide the sign-in button and allow the
        // player to proceed.
        // now submit your high_score
        Games.Leaderboards.submitScore(mGoogleApiClient,getResources().getString(R.string.leaderboard_easy),high_score);
    
    }
    
    @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, "Sign in error")) {
                mResolvingConnectionFailure = false;
            }*/
        }
    
        // Put code here to display the sign-in button
    }
    
    @Override
    public void onConnectionSuspended(int i) {
        // Attempt to reconnect
        mGoogleApiClient.connect();
    }
    
    
    
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent intent) {
        if (requestCode == RC_SIGN_IN) {
            mSignInClicked = false;
            mResolvingConnectionFailure = false;
            if (resultCode == RESULT_OK) {
                mGoogleApiClient.connect();
            } else {
                // Bring up an error dialog to alert the user that sign-in
                // failed. The R.string.signin_failure should reference an error
                // string in your strings.xml file that tells the user they
                // could not be signed in, such as "Unable to sign in."
                BaseGameUtils.showActivityResultError(this,
                        requestCode, resultCode, R.string.signin_failure);
            }
        }
    }
    // Call when the sign-in button is clicked
    private void signInClicked() {
        mSignInClicked = true;
        mGoogleApiClient.connect();
    }
    
    // Call when the sign-out button is clicked
    private void signOutclicked() {
        mSignInClicked = false;
        Games.signOut(mGoogleApiClient);
    }
    
     }