GoogleApiClient connection failed with ConnectionResult statuscode SIGN_IN_REQUIRED

1.8k Views Asked by At

[EDIT] - For Bounty

I am trying to connect my android application with Google Drive to sync, MP3 audio files. Need working code/examples (apart from the links given below) for connecting with Google Drive using the GoogleDriveAndroidApi and GoogleApiClient.


This question has been asked many number of times, but none of them had a solution for the question. So, i am asking this again.

I am working on Google Drive Android API for the first time, and couldn't pass through the "Choose account for 'APP NAME'" screen. Here is what i doing as of now:

  1. Tried to follow the urls below:

https://developers.google.com/drive/android/get-started

https://github.com/googledrive/android-quickstart

https://www.numetriclabz.com/integrate-google-drive-in-android-tutorial/

  1. Using compile 'com.google.android.gms:play-services-drive:10.0.1' in my build.gradle (if that makes any difference)

  2. Code tried so far:

     public class ARCBackupActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
                GoogleApiClient.OnConnectionFailedListener {
    
            private static final int REQUEST_CODE = 1;
    
            private GoogleApiClient mGoogleApiClient;
            private Toolbar mToolbar;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.arc_activity_backup);
    
                mToolbar = (Toolbar) findViewById(R.id.toolbar);
                setSupportActionBar(mToolbar);
    
                getSupportActionBar().setDisplayShowTitleEnabled(false);
                getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    
            }
    
    
            @Override
            protected void onResume() {
                super.onResume();
                if (mGoogleApiClient == null) {
                    // Create the API client and bind it to an instance variable.
                    // We use this instance as the callback for connection and connection
                    // failures.
                    // Since no account name is passed, the user is prompted to choose.
                    mGoogleApiClient = new GoogleApiClient.Builder(this)
                            .addApi(Drive.API)
                            .addScope(Drive.SCOPE_FILE)
                            .addConnectionCallbacks(this)
                            .addOnConnectionFailedListener(this)
                            .build();
                }
                // Connect the client. 
                mGoogleApiClient.connect();
            }
    
            @Override
            protected void onPause() {
                if (mGoogleApiClient != null) {
                    mGoogleApiClient.disconnect();
                }
                super.onPause();
            }
    
            @Override
            protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
                switch (requestCode) {
    
                    case REQUEST_CODE:
    
                        if (resultCode == Activity.RESULT_OK) {
                            mGoogleApiClient.connect();
                        }
                        break;
                }
            }
    
            @Override
            public void onConnectionFailed(ConnectionResult result) {
                // Called whenever the API client fails to connect.
                Log.i(Const.DEBUG, "GoogleApiClient connection failed: " + result.toString());
                if (!result.hasResolution()) {
                    // show the localized error dialog.
                    GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
                    return;
                }
                // The failure has a resolution. Resolve it.
                // Called typically when the app is not yet authorized, and an
                // authorization
                // dialog is displayed to the user.
                try {
                    result.startResolutionForResult(this, REQUEST_CODE);
                } catch (IntentSender.SendIntentException e) {
                    Log.e(Const.DEBUG, "Exception while starting resolution activity", e);
                }
            }
    
            @Override
            public void onConnected(Bundle connectionHint) {
                Log.d(Const.DEBUG, "API client connected.");
    
                //saveFileToDrive();
            }
    
            @Override
            public void onConnectionSuspended(int cause) {
                Log.d(Const.DEBUG, "GoogleApiClient connection suspended");
            }
        }
    

    What is that i am missing here? Any complete example with good explanation is much appreciated.

    Let me know if i need to give more info to solve the issue

    [EDIT 1]

    If i add Plus.API while building the googleApiClient, it solves the problem of getting stuck in the loop of choosing the account. But, Plus.API is deprecated, is there a workaround for this just by using GoogleApiClient?

    Here is the changed code:

     @Override
        protected void onResume() {
            super.onResume();
    
            if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
                Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
                mGoogleApiClient.disconnect();
            }
    
    
            if (mGoogleApiClient == null) {
                // Create the API client and bind it to an instance variable.
                // We use this instance as the callback for connection and connection
                // failures.
                // Since no account name is passed, the user is prompted to choose.
                mGoogleApiClient = new GoogleApiClient.Builder(this)
                        .addApi(Drive.API)
                        .addApi(Plus.API)
                        .addScope(Drive.SCOPE_FILE)
                        .addConnectionCallbacks(this)
                        .addOnConnectionFailedListener(this)
                        .build();
            }
            // Connect the client.
            mGoogleApiClient.connect();
        }
    

Still looking for the correct way of implementing...

2

There are 2 best solutions below

1
On BEST ANSWER

It looks like that the problem you have is because of

@Override
protected void onPause() {
    if (mGoogleApiClient != null) {
        mGoogleApiClient.disconnect();
    }
    super.onPause();
}

Let me explain. When the account chooser appears it makes your activity to call onPause(). And in onPause() you calls mGoogleApiClient.disconnect().

As result, you have new GoogleApiClient after account selection (when onResume and onActivityResult is called).

To fix the problem just place mGoogleApiClient.connect() and mGoogleApiClient.disconnect() to onStart()/onStop() methods of your activity or use enableAutoManage(Activity, OnConnectionFailedListener) for you GoogleApiClient.

Happy coding! :)

1
On

Well I was going through issues for Google drive on github ,i found the similar issue their go through @iuribtt answer

Here is link

Google Drive Issues

In case this link got expired I am posting his answer :

Try to use "keytool -exportcert -alias androiddebugkey -keystore C:\Users\XXXXX.android\debug.keystore -list -v" and not the keystore that you generate, once you want the debug mode.

The path for the "debug.keystore" and the password is "android" https://support.google.com/cloud/answer/6158849?hl=en#android

And after that create the project in https://developers.google.com/mobile/add

Finally, enable the Drive API in the https://console.developers.google.com

Hope this Helps!!!Cheers!!!