Search code examples
androidgoogle-play-servicesgoogle-play-games

App does not sign in on MainActivity but signs in, in the next activity. Implementing Google Play Services Signin using BaseGameUtils


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() {

}}

Solution

  • 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.