这个问题有点老了,所以你可能已经弄清楚了。但我也遇到了同样的问题,所以也许其他人也感兴趣。
这里的问题是 Google Drive REST API 使用 ID 来识别文件和文件夹。 API 不提供文件或目录选择器,这就是您使用 Android 内置选择器的原因。例如,要允许用户为新文件选择名称和目标文件夹,您可以使用以下意图:
Intent createDirectoryPickerIntent(String fileName, String mimeType) {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(mimeType);
intent.putExtra(Intent.EXTRA_TITLE, fileName);
return intent;
}
并在您的活动中创建它:
public void openDirectoryPicker() {
if (mDriveServiceHelper != null) {
Intent pickerIntent = mDriveServiceHelper.createDirectoryPickerIntent("fileName", "text/plain");
startActivityForResult(pickerIntent, REQUEST_CODE_OPEN_DIR);
}
}
(记得删除空文件,以免第二步写入实际内容失败。)
文件选择器通过 URI 来识别文件,并且不知道有关文件 ID 的任何信息。按名称查询文件以获取新文件的 ID 可能会失败,因为另一个文件夹甚至同一文件夹中可能存在重复项。这就是 Google 建议使用其他方式访问文件的原因:
对于使用 Android API 的文件选择器的客户端(例如通过调用
DriveClient#newOpenFileActivityIntentSender),我们建议使用
存储访问框架 (SAF),用于访问 Drive Android 应用程序的
内容提供商。示例应用程序演示了如何启动文件
选择器 Intent 并处理它返回的数据。 (Google Drive Android API 弃用指南 https://developers.google.com/drive/android/deprecation#file_picker_ui)
The 示例应用程序 https://github.com/gsuitedevs/android-samples/tree/master/drive/deprecation正如您所说,提供了一个读取文件的示例openFileUsingStorageAccessFramework(...)
。您可以执行相同的操作来写入使用上述目录选择器创建的文件。 URI 由意图提供。
在您的活动中:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
switch (requestCode) {
case REQUEST_CODE_SIGN_IN:
//...
}
break;
case REQUEST_CODE_OPEN_DIR:
if (resultCode == RESULT_OK && resultData != null) {
Uri uri = resultData.getData();
if (uri != null && mDriveServiceHelper != null) {
mDriveServiceHelper.writeToFileUsingStorageAccessFramework(this, getContentResolver(), uri, "some content")
.addOnSuccessListener(Void -> {
Log.v(TAG, "success");
})
.addOnFailureListener(exception -> {
Log.e(TAG, "Unable to write to file.", exception);
});
}
} else {
Log.v(TAG, "Unable to write to file.");
}
break;
}
super.onActivityResult(requestCode, resultCode, resultData);
}
并在DriveServiceHelper
与示例应用程序非常相似:
Task<Void> writeToFileUsingStorageAccessFramework(Context context, ContentResolver contentResolver, Uri uri, String content) {
return Tasks.call(mExecutor, () -> {
// Retrieve the document's display name from its metadata.
String name;
try (Cursor cursor = contentResolver.query(uri, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
name = cursor.getString(nameIndex);
} else {
throw new IOException("Empty cursor returned for file.");
}
}
// Write content to the file, e.g.
try (OutputStream outputStream = contentResolver.openOutputStream(uri);) {
if (outputStream != null) {
outputStream.write(content.getBytes());
outputStream.close();
}
}
return null;
});
}