Android:调用 GoogleApiClient.connect() 时出错

Android: Error calling GoogleApiClient.connect()

当我调用方法 mGoogleApiClient.connect() 时,应用程序崩溃了。

以下代码复制自www.developers.google.com

我想实现 Google 登录功能,但无法实现。

我还编辑了 build.gradle 文件。在我的上一个应用程序中,由于这个问题我无法添加排行榜,现在我的下一个应用程序再次需要排行榜,但这次我不能离开它。

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.games.Games;
import com.google.example.games.basegameutils.BaseGameUtils;

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();
        }

        //checkButtonVisibility();
    }

    private void checkButtonVisibility() {
        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            findViewById(R.id.sign_out_button).setVisibility(View.VISIBLE);
            // signed in. Show the "sign out" button and explanation.
            // ...
        } else {
            findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
            // not signed in. Show the "sign in" button and explanation.
            // ...
        }
    }


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

    @Override
    public void onConnected(Bundle connectionHint) {
        // show sign-out button, hide the sign-in button
        findViewById(R.id.sign_in_button).setVisibility(View.GONE);
        findViewById(R.id.sign_out_button).setVisibility(View.VISIBLE);

        // (your code here: update UI, enable functionality that depends on sign in, etc)
    }



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

        // If the sign in button was clicked or if auto sign-in is enabled,
        // launch the sign-in flow
        if (mSignInClicked || mAutoStartSignInFlow) {
            mAutoStartSignInFlow = false;
            mSignInClicked = false;
            mResolvingConnectionFailure = true;

            // Attempt to resolve the connection failure using BaseGameUtils.
            // The R.string.signin_other_error value should reference a generic
            // error string in your strings.xml file, such as "There was
            // an issue with sign in, please try again later."
            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 {
                // Bring up an error dialog to alert the user that sign-in
                // failed. The R.string.signin_failure should reference an error
                // string in your strings.xml file that tells the user they
                // could not be signed in, such as "Unable to sign in."
                BaseGameUtils.showActivityResultError(this, requestCode, resultCode, RC_SIGN_IN); //R.string.signin_failure
            }
        }
        //checkButtonVisibility();
    }

    // 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;
            mGoogleApiClient.connect();
        }
        else if (view.getId() == R.id.sign_out_button) {
            // sign out.
            mSignInClicked = false;
            Games.signOut(mGoogleApiClient);

            // show sign-in button, hide the sign-out button
            findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
            findViewById(R.id.sign_out_button).setVisibility(View.GONE);
        }

        checkButtonVisibility();
    }
}

Logcat:

06-12 09:54:03.113    4364-4364/com.example.gSignIn I/System.out﹕ Calling Method: mGoogleApiClient.connect( )
06-12 09:54:03.238    4364-4368/com.example.gSignIn D/dalvikvm﹕ GC_CONCURRENT freed 1903K, 16% free 14093K/16647K, paused 21ms+6ms, total 63ms
06-12 09:54:03.598    4364-4364/com.example.gSignIn D/AndroidRuntime﹕ Shutting down VM
06-12 09:54:03.598    4364-4364/com.example.gSignIn W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x411762a0)
06-12 09:54:03.613    4364-4364/com.example.gSignIn E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.IllegalStateException: A fatal developer error has occurred. Check the logs for further information.
            at com.google.android.gms.internal.jl$h.b(Unknown Source)
            at com.google.android.gms.internal.jl$h.g(Unknown Source)
            at com.google.android.gms.internal.jl$b.hy(Unknown Source)
            at com.google.android.gms.internal.jl$a.handleMessage(Unknown Source)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4921)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
            at dalvik.system.NativeStart.main(Native Method)

清单:

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

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

    <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. 您是否在 Google Developer Console 中正确设置了 API 控制台项目?
  2. 如果您正在使用 Google Play Games Services, you must set up the project using the Google Play Games Console(单击左侧的 图标)。
  3. 如果您使用 Google Play Games Services,您可能还需要将以下内容添加到您的 androidmanifest.xml

    <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"/>
    

你在Google Play Games Services Console的APP ID应该设置在resources/values.xml,例如:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_id">1234567890</string>
</resources>

请注意,应用程序 ID 只是一个唯一的 ~10 个字符值,而不是作为客户端 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"/>

这对我有帮助,还要确保你正确地引用了你的 build.gradle : 添加依赖项:compile project(':BaseGameUtils')