使用 Google 驱动器 API 的 Android 打开文件 | INTERNAL_ERROR

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

我正在尝试使用 Google Drive API for Android to open a file. From the following official tutorial,我有以下内容:

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) {
}
}

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;
}
}

我像这样在 Gradle 文件中包含依赖项:

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

Manifest.xml 中的 Activity 如下所示:

<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>

请注意我在GoogleAPI吊上添加了包名的SHA1。此外,内容屏幕中的字段已按说明填写 here

当我尝试 运行 这段代码时,我在 onConnectionFailed 回调中不断收到以下错误消息:

{statusCode=INTERNAL_ERROR, resolution=null}

知道哪里出了问题吗?我无法弄清楚问题是什么。

我找到了答案。问题是 debug key。本质上,我 运行 keytool 命令并生成了 SHA1,然后我将其添加到 Google 上的 API 控制台。然后我 运行 来自 Android Studio 的项目。这给了我错误。

然后我从 Android Studio -> Menu -> Build -> Generate signed apk 创建了一个新的密钥库。 运行 用于生成 SHA1 的相同命令,我将其上传到 API 控制台。然后使用更新的 apk 文件,我能够获取文件的内容。

问题是 Google 无法验证密钥。