8

I am getting this error message when trying to implement logout for Google Sign-In for Android:

Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.

The crash occurs in DrawerActivity.java (below), where I call the signOut() method.

I've looked at the solutions in other posts and have tried them to no avail:

java.lang.IllegalStateException: GoogleApiClient is not connected yet

GoogleApiClient is not connected yet exception Fatal Exception: java.lang.IllegalStateException GoogleApiClient is not connected yet

MainActivity.java:

protected void onCreate(Bundle savedInstanceState) {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this, this)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();
    //... other code for google sign in not shown
}

protected void onStart() {
    mGoogleApiClient.connect();
}

private void handleSignInResult(GoogleSignInResult result) {
    if (result.isSuccess()) {
        App.getInstance().setClient(mGoogleApiClient);
        //start DrawerActivity
    }
}

In DrawerActivity.java (where I want to perform the sign out)

private void googleSignOut(){
    mGoogleApiClient = App.getInstance().getClient();
    Auth.GoogleSignInApi.signOut(mGoogleApiClient);
}

In my App activity that extends Application (used to store the GoogleApiClient)

public class App extends Application {

    private GoogleApiClient mGoogleApiClient;
    private static App mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized App getInstance() {
        return mInstance;
    }

    public void setClient(GoogleApiClient client){
        mGoogleApiClient = client;
    }

    public GoogleApiClient getClient(){
        return mGoogleApiClient;
    }
}

StackTrace:

21:33.314 25375-25375/com.me.myapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.me.myapp, PID: 25375
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.internal.zzmf.zzb(Unknown Source)
at com.google.android.gms.internal.zzmi.zzb(Unknown Source)
at com.google.android.gms.internal.zzmg.zzb(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.zzc.signOut(Unknown Source)
at com.me.myapp.DrawerActivity.googleSignOut(DrawerActivity.java:526)
at com.me.myapp.DrawerActivity.onNavigationDrawerItemSelected(DrawerActivity.java:512)
at com.me.myapp.NavigationDrawerFragment.selectItem(NavigationDrawerFragment.java:201)
at com.me.myapp.NavigationDrawerFragment.access$000(NavigationDrawerFragment.java:31)
at com.me.myapp.NavigationDrawerFragment$1.onItemClick(NavigationDrawerFragment.java:98)
at android.widget.AdapterView.performItemClick(AdapterView.java:310)
at android.widget.AbsListView.performItemClick(AbsListView.java:1145)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3042)
at android.widget.AbsListView$3.run(AbsListView.java:3879)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteI

Any help would be appreciated. Thanks!

Community
  • 1
  • 1
VIN
  • 6,385
  • 7
  • 38
  • 77
  • 1
    If there is a crash, always include the full stack trace and point out the line in your code where it occurs. – Doug Stevenson Mar 07 '16 at 20:49
  • Sorry @DougStevenson, I've included the stacktrace now. – VIN Mar 07 '16 at 21:10
  • why dont you call connect first if its not connected? – Shmuel Mar 07 '16 at 21:11
  • @Shmuel, I have done that, using `mGoogleApiClient.connect()` in onStart();, but it doesn't have any effect. I get the same crash message. I have also called .connect() in the signOut() method, still same crash message. – VIN Mar 07 '16 at 21:12
  • Can you add some logging to the `#handleSignInResult` method. That method may get getting called with a failing result which would mean `#setClient` is never called – Scott Tomaszewski Mar 07 '16 at 21:15
  • Hey @Scotty, `result.isSuccess()` evaluates to true, so the `App.getInstance().setClient(mGoogleApiClient);` actually is being called. – VIN Mar 07 '16 at 21:42
  • You should consider ditching the threading and just create a second `GoogleApiClient`. According to this post (http://stackoverflow.com/a/25190497/608347) the client isn't a heavy object so might as well avoid the confusing design and make things simple. Even if you dont go down this path you should strip out that `#setClient` and `#getClient` code and see if you get the same error when disconnecting from a single activity. – Scott Tomaszewski Mar 08 '16 at 00:13
  • Thanks @Scotty! I created a new GoogleApiClient in the DrawerActivity.java's onCreate method and it worked. If you post it as the answer, I'll accept it :) – VIN Mar 08 '16 at 02:27

5 Answers5

8

You should ditch the threading and just create a second GoogleApiClient. According to this post (https://stackoverflow.com/a/25190497/608347) the client isn't a heavy object so might as well avoid the confusing design and make things simple. Even if you dont go down this path you should strip out that #setClient and #getClient code and see if you get the same error when disconnecting from a single activity

Community
  • 1
  • 1
Scott Tomaszewski
  • 1,009
  • 8
  • 27
  • 1
    Thanks @Scotty! Creating a new GoogleApiClient in the activity where I perform the signout fixed the error. – VIN Mar 08 '16 at 17:55
6

I know its quite old post and already answered.

However, the actual cause of the error is not object creation at single or multiple places but "enableAutoManage" invocation at the time of Building Client object.

The API doc here suggests that it would automatically do the life cycle management by calling methods on onStart & onStop methods of the activity.

Therefore, if you want to use the same object across different activities then you should avoid calling "enableAutoManage" and invoke apiObject.connect(preferably in onStart of activity) and apiObject.disconnect() (preferably in onStop of activity).

This worked for me, therefore sharing.

Chota Bheem
  • 1,106
  • 1
  • 13
  • 31
2

To make a button Sign Out in another Activity, for example: the login is in the Activity A and the sign out is in the activity B, then you can use this for the second activity.

First create the OnStart method:

 @Override
protected void onStart() {
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();
    mGoogleApiClient.connect();
    super.onStart();
}

After in your button collocate this:

Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
    new ResultCallback<Status>() {
        @Override
        public void onResult(Status status) {
            // ...
            Toast.makeText(getApplicationContext(),"Logged Out",Toast.LENGTH_SHORT).show();
            Intent i=new Intent(getApplicationContext(),MainActivity.class);
            startActivity(i);
        }
    });
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
0

Remove this:

.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)

EM-Creations
  • 4,195
  • 4
  • 40
  • 56
0

you can check whether is connected or not.

 if (mGoogleApiClient.isConnected()) {

          //your code
  }
behrad
  • 1,228
  • 14
  • 21