0

I'm not keen on the standard behavior of the Play Games Service to automatically attempt a connection when the app is first launched, so I have disabled this. In my main menu I have a 'display scores' button. What I want to happen when the user presses this button is this:

  • If the user is connected (logged in), go ahead and display the leaderboard

  • If the user is not connected, then display the connection dialog. Once connected, display the leaderboard

  • On the main menu, I will have an extra button "Log out" which will display only if the user is connected / logged in.

When the user clicks the button, I am carrying out the following:

Code

if (buttonPressed()){

    //Display connection dialogue and initiate log in
    getGameHelper().beginUserInitiatedSignIn();


    //Check if the user is signed in before continuing
    if (getGameHelper.isSignedIn()){

        startActivityForResult(Games.Leaderboards.getLeaderboardIntent(getApiClient(), myLeaderBoardID), 1);

    }

}

If the user isn't connected: The user is presented with a connection dialogue - this works fine. They can then log in. Once they have done this, nothing else happens (the code has moved on and therefore does not display the leaderboard because the user isn't logged in - if I don't have the check to see if the user is signed in here the app would just crash). If the user then presses the button again, it will display the leaderboard.

How can I do all this with just one button press?

What I want is, if the user isn't logged in, to display the log-in dialogue, then as soon as the user has logged in, display the leaderboard. I need to make startActivityForResult wait until the user has completed sign in.

In short

I need to make my code wait until it's connected to Play before attempting to display the Leaderboard.

Any help would be appreciated

Zippy
  • 3,826
  • 5
  • 43
  • 96

1 Answers1

1

You can be notified of successful/failed sign-in as follows:

getGameHelper().setup( 
   new GameHelper.GameHelperListener() {  
      @Override
      public void onSignInSucceeded() {
         // execute code on successful sign-in
         // for example, here you could show your leaderboard
      }
      @Override
      public void onSignInFailed() {
         // execute code on failed sign-in
      }
   };
);

You should of course do this before you attempt to sign-in. You can then show your leaderboard when sign-in succeeds. This code should be placed where you create your game helper (i.e. before the buttonPressed() code is executed).

Once this code is in place, you should change your buttonPressed() code to look as follows:

if ( buttonPressed() ) {

   // check if user already signed-in and show leaderboard; otherwise do sign-in
   if ( getGameHelper.isSignedIn() )  {
      startActivityForResult( Games.Leaderboards.getLeaderboardIntent( getApiClient(), myLeaderBoardID ), 1 );
   }
   else   {
      getGameHelper().beginUserInitiatedSignIn();
      // NOTE: do nothing further here; show the leaderboard in 
      //       the listener's onSignInSucceeded() 
   }
}

One final note: the listener you create will be called for all sign-in operations, so if you need to have this functionality in multiple places (for example, if you want to do the same with achievements) then you will need to use some signal as to what needs to happen on successful sign-in and take the correct action in onSignInSucceeded().

Signalling an action for sign-in success:

Add this code to you class (global scope)

public final static int NO_ACTION = 0;
public final static int SHOW_LEADERBOARD = 1;
public final static int SHOW_ACHIEVEMENTS = 2;

public int signInAction = NO_ACTION;

Next set the action just before signing-in (based on where the sign-in occurs):

if ( buttonPressed() ) {

   // check if user already signed-in and show leaderboard; otherwise do sign-in
   if ( getGameHelper.isSignedIn() )  {
      startActivityForResult( Games.Leaderboards.getLeaderboardIntent( getApiClient(), myLeaderBoardID ), 1 );
   }
   else   {

      // NEW: request leaderboard to be shown upon sign in
      signInAction = SHOW_LEADERBOARD;
      // NEW---------------------------------------------- 
      getGameHelper().beginUserInitiatedSignIn();
      // NOTE: do nothing further here; show the leaderboard in 
      //       the listener's onSignInSucceeded() 
   }
}

And finally change the listener to respond the set sign-in action:

getGameHelper().setup( 
   new GameHelper.GameHelperListener() {  
      @Override
      public void onSignInSucceeded() {
         if ( signInAction == SHOW_LEADERBOARD )  {
            // show your leaderboard here
         }
         else if ( signInAction == SHOW_ACHIEVEMENTS )  {
            // show achievements here
         }

         // important! reset the sign-in action so that any subsequent sign-in
         // attempts do not re-use the currently set action!
         signInAction = NO_ACTION;
      }
      @Override
      public void onSignInFailed() {
         // execute code on failed sign-in

         // important! it should also be cleared in case of an error
         signInAction = NO_ACTION;
      }
   };
);

Of course, this is just one way to achieve this, but it should work just fine for most purposes. Just be sure to set the signInAction to the appropriate value before you perform the sign-in - and be sure to clear it when sign-in is complete.

free3dom
  • 18,729
  • 7
  • 52
  • 51
  • Hi @free3dom many thanks for this, the only problem with launching the leaderboard from within onSignInSucceeded() is that this seems to be called not just when the user signs in but also when the app is launched/relaunched. Meaning if the user exits the app without signing out and then re-launches it, the leaderboard automatically is displayed. Which I definitely don't want. Do you know how I can mitigate this behavior? Thanks again! – Zippy May 17 '14 at 22:02
  • Indeed, that is what I meant in the final note. Ideally, you should use a global state of some sort (maybe a member variable) and set that to some defined code when you (for instance) want to display the leaderboard on successful sign-in. If this in unclear let me know and I will add some code illustrating what I have in mind :) – free3dom May 17 '14 at 22:09
  • Hi @free3dom - I did try using a boolean and checking the state of the boolean in onSignInSucceeded() but it got very messy and confusing! I would be very grateful if you could explain with some code Much appreciated :-) Cheers! – Zippy May 17 '14 at 22:18
  • Added an example. Hope it helps, and ask if anything is unclear. – free3dom May 17 '14 at 22:43