Google Play Game Services & libGDX "SignInActivity must be started with startActivityForResult"

android, google-play-games, libgdx

Solution

I had the same issue, then I noticed this in the logs: "Activity is launching as a new task, so cancelling activity result"

In the AndroidManifest.xml file of my libgdx game, I had set this property: 'android:launchMode="singleInstance"' As soon as I removed that, I was able to use GPGS just like the sample apps.

Problem

I'm trying to implement Google Play Game Services into my libGDX game. I followed the tutorial here: http://helios.hud.ac.uk/u1070589/blog/?p=202 When my game loads, I create a new GameHelper object and call its setup method. I've debugged this part and it completes without any problems. I've placed a GPGS button on my main menu, when it's clicked I call the `Login()` method in my main Android Activity. At this point the `mConnectionResult.startResolutionForResult(mActivity, RC_RESOLVE)` call in the `resolveConnectionResult` method (GameHelper class) returns the error: E/SignInActivity(21930): SignInActivity must be started with startActivityForResult The ConnectionResult object (mConnectionResult) doesn't have a public method available called startActivityForResult so I can't just change the startResolutionForResult call. In the `beginUserInitiatedSignIn()` method (GameHelper) the connection returns `ConnectionResult.SUCCESS`. When `resolveConnectionResult()` is called, `mConnectionResult.hasResolution()` also returns true. I've double-checked that my debug key matches the entry for my app in the Google APIs Console. I've checked that my app ID matches the one shown on the Google Play Developer Console. I have managed to get the Type-a-Number example app working without any problems. Here's my main Android activity: ``` package com.eb.droid; import android.content.Intent; import android.view.Window; import android.view.WindowManager; import com.badlogic.gdx.backends.android.AndroidApplication; import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration; import com.swarmconnect.Swarm; import com.eb.GoogleInterface; import com.google.example.games.basegameutils.GameHelper; import com.google.example.games.basegameutils.GameHelper.GameHelperListener; public final class AndroidGame extends AndroidApplication implements GameHelperListener, GoogleInterface { private final int RC_RESOLVE = 5000, RC_UNUSED = 5001; //request codes we use when invoking an external activity private final SwarmData swarmData = new SwarmData(); private GameHelper aHelper; public AndroidGame() { aHelper = new GameHelper(this); aHelper.enableDebugLog(true, "MYTAG"); } public final void onCreate(android.os.Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration(); // Disable hardware functions to save battery power. cfg.useAccelerometer = false; cfg.useCompass = false; cfg.useGL20 = true; aHelper.setup(this); setSwarmKeyPartA(); initialize(new Game(this, swarmData), cfg); // Activate Swarm if user is already logged-in. App won't nag player to log-in, they always have to // do it manually via the Swarn dashboard via the title screen. //Log.d(LOG, "onCreate() Swarm.isLoggedIn() = " + Swarm.isLoggedIn()); if (Swarm.isLoggedIn()) { Swarm.setActive(this); } } public void onResume() { super.onResume(); if (Swarm.isLoggedIn()) { Swarm.setActive(this); Swarm.init(this, swarmData.swarmAppID, swarmData.swarmAppKey); } } public void onPause() { super.onPause(); Swarm.setInactive(this); } @Override ublic void onStart() { super.onStart(); aHelper.onStart(this); } @Override public void onStop() { super.onStop(); aHelper.onStop(); } @Override public void onActivityResult(int request, int response, Intent data) { super.onActivityResult(request, response, data); aHelper.onActivityResult(request, response, data); } public void onSignInFailed() { System.out.println("sign in failed"); } public void onSignInSucceeded() { System.out.println("sign in succeeded"); } public void Login() { try { runOnUiThread(new Runnable() { @Override public void run() { aHelper.beginUserInitiatedSignIn(); } }); } catch (final Exception ex) { } } public void LogOut() { try { runOnUiThread(new Runnable() { @Override public void run() { aHelper.signOut(); } }); } catch (final Exception ex) { } } public boolean getSignedIn() { return aHelper.isSignedIn(); } public void submitScore(int _score) { System.out.println("in submit score"); aHelper.getGamesClient().submitScore(getString(R.string.leaderboard_high_scores), _score); } public void showAchievements() { startActivityForResult(aHelper.getGamesClient().getAchievementsIntent(), RC_UNUSED); } public void showLeaderboards() { startActivityForResult(aHelper.getGamesClient().getAllLeaderboardsIntent(), RC_UNUSED); } public void getScoresData() { } } ``` My app also currently implements Swarm, as can be seen in the Activity. I tried removing Swarm to see if that was negatively affecting the GPGS login, but still no luck.

Original source