Search code examples
androidgoogle-drive-apigoogle-drive-android-api

Open file using Google Drive API's for Android | INTERNAL_ERROR


I am trying to use the Google Drive API for Android to open a file. From the following official tutorial, I have the following:

GoogleDriveActivity.class

public class GoogleDriveActivity extends Activity implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {

private GoogleApiClient mGoogleApiClient;
private int REQUEST_CODE_RESOLUTION = 1;
private int REQUEST_CODE_OPENER = 2;
private ListView filesLv;
private DataBufferAdapter<Metadata> mResultsAdapter;
private String mNextPageToken;
private boolean hasMore;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_google_drive);

    filesLv = (ListView) findViewById(R.id.listViewResults);
    hasMore = true;
    mResultsAdapter = new ResultsAdapter(this);
    filesLv.setAdapter(mResultsAdapter);
    filesLv.setOnScrollListener(new AbsListView.OnScrollListener() {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }

        @Override
        public void onScroll(AbsListView view, int first, int visible, int total) {
            if (mNextPageToken != null && first + visible + 5 < total) {
                retrieveNextPage();
            }
        }
    });
}

private void retrieveNextPage() {
    // retrieve the results for the next page.
    Query query = new Query.Builder()
            .setPageToken(mNextPageToken)
            .build();
    Drive.DriveApi.query(mGoogleApiClient, query)
            .setResultCallback(metadataBufferCallback);
}

private final ResultCallback<DriveApi.MetadataBufferResult> metadataBufferCallback = new
        ResultCallback<DriveApi.MetadataBufferResult>() {
            @Override
            public void onResult(DriveApi.MetadataBufferResult result) {
                if (!result.getStatus().isSuccess()) {
                    return;
                }
                mResultsAdapter.clear();
                mResultsAdapter.append(result.getMetadataBuffer());
                mNextPageToken = result.getMetadataBuffer().getNextPageToken();
                hasMore = mNextPageToken != null;
            }
        };

@Override
public void onResume() {
    super.onResume();
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Drive.API)
                .addScope(Drive.SCOPE_FILE)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }
    mGoogleApiClient.connect();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_RESOLUTION && resultCode == RESULT_OK) {
        mGoogleApiClient.connect();
    }
}

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

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    if (!connectionResult.hasResolution()) {
        return;
    }
    try {
        connectionResult.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
    } catch (IntentSender.SendIntentException e) {
    }

}

@Override
public void onConnected(Bundle bundle) {
    retrieveNextPage();
}

@Override
public void onConnectionSuspended(int i) {
}
}

The ResultsAdapter.class:

public class ResultsAdapter extends DataBufferAdapter<Metadata> {

public ResultsAdapter(Context context) {
    super(context, android.R.layout.simple_list_item_1);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = View.inflate(getContext(),
                android.R.layout.simple_list_item_1, null);
    }
    Metadata metadata = getItem(position);
    TextView titleTextView =
            (TextView) convertView.findViewById(android.R.id.text1);
    titleTextView.setText(metadata.getTitle());
    return convertView;
}
}

I am including the dependency in the Gradle file like this:

compile 'com.google.android.gms:play-services-drive:7.8.0'

The Activity in the Manifest.xml looks like the following:

<activity
            android:name="com.myproject.GoogleDriveActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="adjustPan">
            <meta-data android:name="com.google.android.apps.drive.APP_ID" android:value="id=<google project number>"/>
</activity>

Please note that I have added the SHA1 to the Google API condole with the package name. Also, the fields in the content screen are filled out as explained here.

When I try to run this code, I keep getting the following error message in the onConnectionFailed callback:

{statusCode=INTERNAL_ERROR, resolution=null}

Any idea on what could be going wrong? I am not able to figure out what the problem is.


Solution

  • I found an answer. The problem was the debug key. Essentially, I ran the keytool command and generated the SHA1 which I then added to the API console on Google. I then ran the project from Android Studio. This was giving me the error.

    I then created a new keystore from Android Studio -> Menu -> Build -> Generate signed apk. Ran the same command to generate SHA1 which I uploaded to the API console. Then with the updated apk file, I was able to get the contents of the file.

    The problem was that the key could not be authenticated by Google.