Этот вопрос немного устарел, так что вы, возможно, уже поняли его.Но у меня была та же самая проблема, поэтому, возможно, другие тоже заинтересовались.
Проблема в том, что API REST Google Drive использует идентификаторы для идентификации файлов и папок.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 и ничего не знают об идентификаторах файлов.Запрос файлов по имени для получения идентификатора нового файла может завершиться сбоем, поскольку могут быть дубликаты в другой или даже в той же папке.Вот почему Google рекомендует использовать другие средства для доступа к файлам:
Для клиентов, использующих средство выбора файлов API Android (например, путем вызова DriveClient # newOpenFileActivityIntentSender), мы рекомендуем использовать Storage Access Framework (SAF)который обращается к поставщику контента приложения Drive Android.В примере приложения показано, как запустить Intent средства выбора файлов и обработать возвращаемые данные.( Руководство по устареванию API Google Drive Android )
Пример приложения , как вы сказали, является примером для чтения файла в 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;
});
}