1

I'm trying to implement Google sign-in using BaseGameUtils for my game.

The project structure is as follows:

public class LoginActivity extends BaseGameActivity implements... {}
public class MainActivity extends LoginActivity   {}
public class NormalActivity extends LoginActivity      {}

During the course of the application, MainActivity starts NormalActivity.

Ideally, I want the game to sign-in in MainActivity, automatically, or by clicking the sign-in button.

But for API Levels < 21, I observed that sign-in from MainActivity fails and throws an "Unknown Error".

However, after this failure when I open NormalActivity from MainActivity, the Signing in Pop up comes and the sign in is successful when inside NormalActivity.

Additional Information:

During my investigations I observed that on my device with API<21 I get the following error in console:

E/dalvikvm: Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.GooglePlayServiceUtil.zza

This error does not appear for API 21. Also, I found that AppOpsManager was added in API 19.

So, I suspect this is the root cause of the issue, however I'm unable to figure out how to work around this.

I have been searching for a solution and have unsuccessfully tried the answers posted in the following threads:

Google game services sign in issue (fails first attempt, successful second)

Google Play Game Services: strange sign in behavior

LoginActivity.java

public class LoginActivity extends BaseGameActivity implements
    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
    ResultCallback<People.LoadPeopleResult>{

private static final int RC_SIGN_IN = 9001;

public GoogleApiClient mGoogleApiClient;

private boolean mResolvingConnectionFailure = false;

private boolean mAutoStartSignInFlow = true;

private boolean mSignInClicked = false;

String TAG = "LoginActivity: ";

protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    Log.v(TAG, "onCreate()");
    mGoogleApiClient = buildGoogleApiClient();
}

@Override
protected void onStart()
{
    super.onStart();
    mGoogleApiClient.connect();
}

@Override
protected void onStop()
{
    super.onStop();

    Log.d(TAG, "onStop(): disconnecting");
    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
    }

}

public GoogleApiClient buildGoogleApiClient() {

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

@Override
public void onConnected(Bundle connectionHint) {
    Log.i(TAG, "onConnected");
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    if (mResolvingConnectionFailure) {
        return;
    }

    if (mSignInClicked || mAutoStartSignInFlow) {
        mAutoStartSignInFlow = false;
        mSignInClicked = false;
        mResolvingConnectionFailure = true;

        if (!BaseGameUtils.resolveConnectionFailure(this,
                mGoogleApiClient, connectionResult,
                RC_SIGN_IN, getResources().getString(R.string.signin_other_error)))
        {
            mResolvingConnectionFailure = false;
        }
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == RC_SIGN_IN) {
        mSignInClicked = false;
        mResolvingConnectionFailure = false;
        if (resultCode == RESULT_OK) {
            mGoogleApiClient.connect();
        } else {
            BaseGameUtils.showActivityResultError(this,
                    requestCode, resultCode, R.string.signin_failure);
        }
    }
}


@Override
public void onConnectionSuspended(int cause) {
    mGoogleApiClient.connect();
}

@Override
public void onResult(People.LoadPeopleResult loadPeopleResult) {

}

public boolean isSignedIn() {
    return (mGoogleApiClient != null && mGoogleApiClient.isConnected());
}


@Override
public void onSignInFailed() {

}

@Override
public void onSignInSucceeded() {

}}
Community
  • 1
  • 1
  • Try adding `.addApi(Plus.API).addScope(Plus.SCOPE_PLUS_LOGIN)` GoogleApiClient builder. – Tarun Apr 23 '15 at 15:46
  • Hi, thanks. I initially added that as well. But it doesn't make a difference in the current behavior. – Ritika Sood Apr 23 '15 at 16:19
  • Are you calling `onActivityResult` in `MainActivity`??? If not, then do try by adding `onActivityResult` in your derived class. – Tarun Apr 23 '15 at 17:08
  • I did that but it didn't work, also, the `NormalActivity` class doesn't have the `onActivityResult` function, but as it calls `super.onStart()` , where I call `mGoogleApiClient.connect()`, the connection succeeds. – Ritika Sood Apr 23 '15 at 19:18
  • Does it work now? Bcz I didn't find any issue with your code other than those two possibilities I could think of. – Tarun Apr 23 '15 at 19:22

1 Answers1

1

I found the reason for this behavior.

As both the MainActivity and NormalActivity both are derivations of LoginActivity, I did not think that there was an issue with the basic implementation of these classes.

The only difference between MainActivity and NormalActivity was that in AndroidManifest.xml, MainActivity was in android:launchMode: "singleInstance"

Removing the launchMode parameter solved the problem.

Hope this helps other stuck in a similar problem.

  • After reading this I came through this old [answer](http://stackoverflow.com/a/5118924/786337). That explains why sign in didn't work for your MainActivity. – Tarun Apr 24 '15 at 14:42
  • It was an interesting issue.. :) – Tarun Apr 24 '15 at 15:16