Android : Google Sign In GoogleApiClient.connect()

2020-05-03 11:39发布

问题:

the following code is copied from www.developers.google.com

i want to implement Google Sign In functionality, but unable to do so. when i click on SignIn Button it asks for permission and does some searching then Nothing happens, if i call GoogleApiClient.isConnected() it returns false.

i have imported BaseGameUtils and also added line: compile project(':BaseGameUtils')

app_id is generated using sha1 through: keytool -exportcert -alias androiddebugkey -keystore C:\Users\usman\.android\debug.keystore -list -v

public class MenuActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {
    boolean mExplicitSignOut = false;
    boolean mInSignInFlow = false; // set to true when you're in the middle of the
    // sign in flow, to know you should not attempt
    // to connect in onStart()
    GoogleApiClient mGoogleApiClient;  // initialized in onCreate
    private static int RC_SIGN_IN = 9001;
    private boolean mResolvingConnectionFailure = false;
    private boolean mAutoStartSignInFlow = true;
    private boolean mSignInClicked = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_menu);
        findViewById(R.id.sign_in_button).setOnClickListener(this);
        findViewById(R.id.sign_out_button).setOnClickListener(this);

        // Create the Google Api Client with access to the Play Game and Drive services.
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Games.API).addScope(Games.SCOPE_GAMES)
                .addApi(Drive.API).addScope(Drive.SCOPE_APPFOLDER) // Drive API
                .build();
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (!mInSignInFlow && !mExplicitSignOut) {
            // auto sign in
            //mGoogleApiClient.connect();
        }
    }



    @Override
    protected void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        findViewById(R.id.sign_in_button).setVisibility(View.GONE);
        findViewById(R.id.sign_out_button).setVisibility(View.VISIBLE);
    }



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

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

            if (!BaseGameUtils.resolveConnectionFailure(this, mGoogleApiClient, connectionResult, RC_SIGN_IN, "signin_other_error")) //R.string.signin_other_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 {
                BaseGameUtils.showActivityResultError(this, requestCode, resultCode, 404); //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);
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.sign_out_button) {
            // user explicitly signed out, so turn off auto sign in
            mExplicitSignOut = true;
            if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
                Games.signOut(mGoogleApiClient);
                mGoogleApiClient.disconnect();
            }
        }

        if (view.getId() == R.id.sign_in_button) {
            // start the asynchronous sign in flow
            mSignInClicked = true;
            System.out.println("Calling Method: mGoogleApiClient.connect( )\n");
            mGoogleApiClient.connect();
        }
        else if (view.getId() == R.id.sign_out_button) {
            mSignInClicked = false;
            Games.signOut(mGoogleApiClient);

            findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
            findViewById(R.id.sign_out_button).setVisibility(View.GONE);
        }
    }
}

Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.gsignin">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />

    <application android:allowBackup="true" android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:theme="@style/AppTheme">

    <meta-data android:name="com.google.android.gms.appstate.APP_ID" android:value="@string/app_id" />
    <meta-data android:name="com.google.android.gms.games.APP_ID" android:value="@string/app_id" />
    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

    <activity android:name="com.example.gsignin.Splash" android:label="@string/app_name" android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

    <activity android:name="com.example.gsignin.MenuActivity" android:label="@string/app_name" android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="com.example.gsignin.MenuActivity"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>

    </application>
</manifest>

回答1:

For Google Sign-in you might want to try starting from the Android Sign-in Quickstart and then integrating from there. If you're using Play Games Services, BaseGamesUtils can be helpful but is not required.

Next, unless you are updating / migrating a legacy Play Games Services project, remove all references to APP_STATE from your manifest and app. The App State API, used for Play Games Services, has been deprecated and may cause issues in authorization.

You indicate that your APP_ID is coming from a keytool -list call but this sounds incorrect. APP_ID corresponds to the Play Games Services application ID and is only used for Play Games Services features. You only should be running:

keytool -list -keystore ~/.android/debug.keystore

for getting a SHA-1 hash. This hash is used to register your Android application (which has package name com.example.gsignin) on the Google Developer Console.

Hope that helps, you might be best off by starting with the working sample that I pointed you to and then working from there to figure out where things are breaking.