17

I am developing the application where I am integrating the Google Drive in my App. Below is my code which is I simply copied from the sample code but I am getting exception when connecting with Google Drive.

Exception : ConnectionResult{statusCode=INTERNAL_ERROR, resolution=null} in the onConnectionFailed() method.

Please guys share your views.

public class MainActivity extends Activity implements ConnectionCallbacks,
        OnConnectionFailedListener {

    private static final String TAG = "android-drive-quickstart";
    private static final int REQUEST_CODE_CAPTURE_IMAGE = 1;
    private static final int REQUEST_CODE_CREATOR = 2;
    private static final int REQUEST_CODE_RESOLUTION = 3;

    private GoogleApiClient mGoogleApiClient;
    private Bitmap mBitmapToSave;

    /**
     * Create a new file and save it to Drive.
     */
    private void saveFileToDrive() {
        // Start by creating a new contents, and setting a callback.
        Log.i(TAG, "Creating new contents.");
        final Bitmap image = mBitmapToSave;
        Drive.DriveApi.newContents(mGoogleApiClient).addResultCallback(new OnNewContentsCallback() {

            @Override
            public void onNewContents(ContentsResult result) {
                // If the operation was not successful, we cannot do anything
                // and must
                // fail.
                if (!result.getStatus().isSuccess()) {
                    Log.i(TAG, "Failed to create new contents.");
                    return;
                }
                // Otherwise, we can write our data to the new contents.
                Log.i(TAG, "New contents created.");
                // Get an output stream for the contents.
                OutputStream outputStream = result.getContents().getOutputStream();
                // Write the bitmap data from it.
                ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
                image.compress(Bitmap.CompressFormat.PNG, 100, bitmapStream);
                try {
                    outputStream.write(bitmapStream.toByteArray());
                } catch (IOException e1) {
                    Log.i(TAG, "Unable to write file contents.");
                }
                // Create the initial metadata - MIME type and title.
                // Note that the user will be able to change the title later.
                MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
                        .setMimeType("image/jpeg").setTitle("Android Photo.png").build();
                // Create an intent for the file chooser, and start it.
                IntentSender intentSender = Drive.DriveApi
                        .newCreateFileActivityBuilder()
                        .setInitialMetadata(metadataChangeSet)
                        .setInitialContents(result.getContents())
                        .build(mGoogleApiClient);
                try {
                    startIntentSenderForResult(
                            intentSender, REQUEST_CODE_CREATOR, null, 0, 0, 0);
                } catch (SendIntentException e) {
                    Log.i(TAG, "Failed to launch file chooser.");
                }
            }
        });
    }

    @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. Once connected, the camera is launched.
        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_CAPTURE_IMAGE:
                // Called after a photo has been taken.
                if (resultCode == Activity.RESULT_OK) {
                    // Store the image data as a bitmap for writing later.
                    mBitmapToSave = (Bitmap) data.getExtras().get("data");
                }
                break;
            case REQUEST_CODE_CREATOR:
                // Called after a file is saved to Drive.
                if (resultCode == RESULT_OK) {
                    Log.i(TAG, "Image successfully saved.");
                    mBitmapToSave = null;
                    // Just start the camera again for another photo.
                    startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
                            REQUEST_CODE_CAPTURE_IMAGE);
                }
                break;
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // Called whenever the API client fails to connect.
        Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
        if (!result.hasResolution()) {
            // show the localized error dialog.
            GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 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_RESOLUTION);
        } catch (SendIntentException e) {
            Log.e(TAG, "Exception while starting resolution activity", e);
        }
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        Log.i(TAG, "API client connected.");
        if (mBitmapToSave == null) {
            // This activity has no UI of its own. Just start the camera.
            startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
                    REQUEST_CODE_CAPTURE_IMAGE);
            return;
        }
        saveFileToDrive();
    }

    @Override
    public void onDisconnected() {
        Log.i(TAG, "API client disconnected.");
    }

}
N Sharma
  • 33,489
  • 95
  • 256
  • 444
  • The easiest way to debug issues like this is to enable http logging and see what is being sent/received on the wire. See http://code.google.com/p/google-http-java-client/wiki/Android#Logging – pinoyyid Jan 23 '14 at 07:05

13 Answers13

25

Heads up! There's a problem in the Developers Console.

If you are getting this bug even after 1) making sure that you have registered the package name with its corresponding certificate fingerprint, and 2) are (re)using an already existing project, then you should check that this project has an product name and an email address (double check that one specially) associated with it, both to be found in the "consent screen" section.

Very old projects may not have these two fields populated. Newer projects have these fields filled out with some default values.

Took me a day to find this...

enter image description here

Daniel F
  • 13,684
  • 11
  • 87
  • 116
  • BTW, this **may** also occur if you have chosen an email address which is later removed from the access permissions. Haven't verified this, though. – Daniel F Jun 13 '14 at 08:17
  • Just adding Email and Product name solve my problem with GooglePlayServicesUtil Internal error. Thank you! – Konstantin Konopko Aug 28 '14 at 14:11
  • that is brilliant answer Daniel !!! Actually your answer is the correct one. Of course Google somehow forgot to mention in documentation that you need to fill also consent screen, and I killed like 2 days finding why copy pasting official google demo won't work even when I followed all steps precisely...Thanks! – qkx Sep 30 '14 at 14:47
  • 3
    @qkx yes, its very frustrating, since you're of course looking for programming mistakes in the super confusing android code (which authentication method do I need to use? am I using the correct one? am I using it correctly?) It's a real pain if it turns out that the originating problem is a purely administrative one. At least you've cleaned up your code, right? ;-) – Daniel F Sep 30 '14 at 15:23
  • you're absolutely right. Actually whole google drive documentation is very confusing, skipping from one page to another and linking to many other pages and forgotting to mention some important things...It's very hard to follow their tutorial, it should be much more straightforward – qkx Sep 30 '14 at 15:44
  • Can you give more insight about the 2. point? Do i have to match the product name with anything within my app project? – user1767754 Oct 27 '14 at 13:33
  • @user1767754 That name isn't important from a technical point of view. But it is what users of your app will get displayed when they get asked by Google if they want to allow that app to be able to access their data. If your app uses the Calendar API then Google would ask them something like '"Product Name" would like to access your calendar data, ok?'. They'll also find that name in their Dashboards list of apps which have access to their data. Else it doesn't have to do anything with the Developer Console. I think that that is what the **consent** screen is about, for dealing with end users. – Daniel F Oct 27 '14 at 14:32
  • I also used a sample code which is as simple as above but getting the same error.My app crashes saying "unknown issue with google play services", and I get ConnectionResult{statusCode=INTERNAL_ERROR..) My console config is ok as said above.Its been almost 3 days with no fu...g luck. I m really pissed up ... – Tanvir Mar 19 '15 at 13:40
  • Thank you very much . This saved so much time. – Dhiraj Powar Jul 09 '15 at 12:29
  • 7
    There's a change in the UI of GDC. It is now located under *Credentials* -> *OAuth consent screen* – mr5 Aug 29 '15 at 16:05
10

I resolve this issue by signing my Google Drive application on API console following these steps

  1. Go to the Google Developers Console.
  2. Select a project, or create a new one.
  3. In the sidebar on the left, expand APIs & auth. Next, click APIs.
  4. In the list of APIs, make sure the status is ON for the Drive API.
  5. In the sidebar on the left, select Credentials.

If your application needs to submit authorized requests:

  1. Under OAuth, click Create new Client ID.
  2. Select Installed application and Android.
  3. In the Package name field, enter your Android app's package name.
  4. Paste the SHA1 fingerprint into the form where requested.
  5. Click Create Client ID.
Pang
  • 9,564
  • 146
  • 81
  • 122
yasir shehzad
  • 101
  • 1
  • 2
  • 1
    "4. In the list of APIs, make sure the status is ON for the Drive API." this solved my problem. Thanks. – chrome May 13 '16 at 08:44
9

I solved the issue from register the application and generate signing certificate fingerprint.

https://developers.google.com/drive/android/auth#generate_the_signing_certificate_fingerprint_and_register_your_application

I followed above links and It solved my problem.

N Sharma
  • 33,489
  • 95
  • 256
  • 444
4

For me the problem was that when in the example there was :

.addApi(Drive.API)

And I didn't added the drive api in the console

this error message helped me to figure out the issue

com.google.android.gms.drive.auth.c: Authorization failed: server returned error: Access Not Configured. The API is not enabled for your project, or there is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your configuration.. See https://developers.google.com/drive/handle-errors for details.

jpprade
  • 3,497
  • 3
  • 45
  • 58
  • For me this was also an issue. The other issue was that the packet name that I had in my Manifest.xml was different than the introduced in the developer console. – Francis Moy Mar 13 '15 at 09:13
4

Don't forget the permissions:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Mansour Alnasser
  • 4,446
  • 5
  • 40
  • 51
3

Do you have any error messages in logcat? The most likely cause of a failed connection is that you haven't properly setup an app in the cloud console.

See the instructions here: https://developers.google.com/drive/android/auth

Cheryl Simon
  • 46,552
  • 15
  • 93
  • 82
  • That error message is the logcat entry... Would have been nice if it would have been more verbose. – Daniel F Mar 30 '14 at 00:56
  • this is of course "must have" condition written in documentaion. But it still won't work until you follow Daniel F advice and fill Email in consent screen :) Sure Google somehow forgot to mention it and I killed like 2 days findind why copy pasting official google demo won't work even when I followed all steps precisely... – qkx Sep 30 '14 at 14:45
2

In my case, I had to change the Client ID to use the exact package name of the activity class building the GoogleApiClient object, not a higher-level package.

2

I was also getting the same error. For my project, Drive API was not enabled under API & auth -> APIs. After enabling this Drive API, this problem was resolved.

ElGavilan
  • 6,610
  • 16
  • 27
  • 36
1

I solved adding this line to gradle:

compile 'com.google.android.gms:play-services-identity:8.1.0'
csamiro
  • 71
  • 6
0

You need to have two separate Client IDs, one for debug, the other one for release. Sometimes we miss the obvious.

goodhyun
  • 4,814
  • 3
  • 33
  • 25
0

In Android Studio go to

Tool-> Android-SDK Manager -> Google Play Service

Update the Google Play Service..I am sure it will work

Prashant Date
  • 433
  • 4
  • 14
0

I got the same problem as above, when I moved an existing application from Eclipse to Android studio. My problem was that I named applicationId different from the package id. Changing applicationId to be the same as the package name solved the problem.

Skywalker
  • 1,717
  • 1
  • 22
  • 25
0

I got the same issue. My sign-in was working but it stopped working all of sudden. I tried all the solutions mentioned here. But didn't solve my problem. However, upon disabling the google sign in and enabling it solved my problem. So just go to the firebase console, select Authentication > Sign-in Methods > google > click Edit > disable and enable.

makkhay gurung
  • 528
  • 1
  • 4
  • 15