1

I am trying to access the google drive through android app. I have turned on the Drive API and Drive SDK in Google Developer Console and generated a OAuth Client id.

Inserted the Client key in AndroidManifest.xml as

<meta-data
  android:name="com.google.android.apps.drive.APP_ID"
  android:value=id="***CLIENT_KEY***" />

And a permission as

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

This is the code which I am trying to run (Originally from here)

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi.DriveContentsResult;
import com.google.android.gms.drive.MetadataChangeSet;

/**
 * Android Drive Quickstart activity. This activity takes a photo and saves it
 * in Google Drive. The user is prompted with a pre-made dialog which allows
 * them to choose the file location.
 */

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.newDriveContents(mGoogleApiClient)
            .setResultCallback(new ResultCallback<DriveContentsResult>() {

        @Override
        public void onResult(DriveContentsResult 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.getDriveContents().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)
                    .setInitialDriveContents(result.getDriveContents())
                    .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 onConnectionSuspended(int cause) {
    Log.i(TAG, "GoogleApiClient connection suspended");
}
}

This is the error I am getting

02-19 18:58:18.204  27221-27221/com.gajendraprofile.drive I/android-drive-quickstart﹕ GoogleApiClient connection failed: ConnectionResult{statusCode=INTERNAL_ERROR, resolution=null}
02-19 18:58:47.584  27431-27431/com.gajendraprofile.drive I/android-drive-quickstart﹕ GoogleApiClient connection failed: ConnectionResult{statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent{21b27910: android.os.BinderProxy@21b00a7c}}
02-19 18:58:51.564  27431-27431/com.gajendraprofile.drive I/android-drive-quickstart﹕ GoogleApiClient connection failed: ConnectionResult{statusCode=INTERNAL_ERROR, resolution=null}`

Am I making any errors above? Are there any better simple example to access Google Drive from Android?

Cheryl Simon
  • 46,552
  • 15
  • 93
  • 82
Gaj
  • 150
  • 2
  • 15
  • Where is the "Inserted the Client key in AndroidManifest.xml as..." coming from? I never heard or used anything similar. – seanpj Feb 19 '15 at 21:22
  • Thanks for your reply, I saw adding manifest key from [here](http://stackoverflow.com/questions/13412134/how-do-i-use-the-google-drive-api-key-to-access-drive-content-from-android-appli) in the last comment. I have searched many websites and forum. I could not able to find how the client id key should be assigned or linked to the app. Do I need to assign the api key in manifest same like Google Maps Api Key. or I just need to generate the key with my package name in google console and it will be automatically fetched when the request is sent from the app?. – Gaj Feb 19 '15 at 23:37
  • BTW, for running any of the demos, I needed only DriveAPI (not DriveSDK). But this is probably irrelevant – seanpj Feb 20 '15 at 03:47
  • I looked at the link you mention in the comment above. The GDAA came in Jan 2014, and changed a few times during last year. No question / answer older than circa March 2014 has much relevance. – seanpj Feb 20 '15 at 04:00

2 Answers2

0

The Quick Start you play with as as simple as it gets, to answer you question.

But it may be outdated (I don't know, last time I ran it was 8 months ago). GooPlayServices are on the 6.5.+ version and last update of that code was half a year ago. I have some code on GitHub that I can't claim is simpler, but (probably) more in line with current lib version. It is a bit broader and deals with both GDAA and REST APIs, as well as with the Google account pick process. If you use Android Studio, you should be able to make use of it. Just a few points:

  • You have go through the Developers Console stuff. Basically you must have your 'package name' / SHA1 registered. I usually register both debug and release SHA1s and double check if my APKs are actually correct - see SO 28532206
  • Look at SO 28439129 here to get some sense what is involved in connecting to GooDrive
  • If you use the code I mentioned, make sure you environment is in line with dependencies in 'build.gradle' there (my SDK Manager shows GooPlaySvcs 21, which is 'com.google.android.gms:play-services:6.5.87')

Good Luck

Community
  • 1
  • 1
seanpj
  • 6,735
  • 2
  • 33
  • 54
0

This error "GoogleApiClient connection failed: ConnectionResult{statusCode=INTERNAL_ERROR, resolution=null} " occurs if you have not created credentials for your application.

  • Go to console- https://console.cloud.google.com/apis/credentials
  • Click on Create Credentials
  • Select QAuth client ID
  • Select Application type as Android if you are running from AndroidStudio
  • Add the projectname, SHA key & package name
  • Run the project and the application should work.

I faced issue running android-quickstart-master and the issue got resolved after following the above steps

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
Ajay B
  • 746
  • 9
  • 19