Как создать средство выбора файлов для сохранения файла на Google Drive с помощью REST API? - PullRequest
0 голосов
/ 18 декабря 2018

Теперь, когда Google устарел API Google Drive для Android, я в процессе переноса своего кода в Drive REST API.

У меня почти все работает,но я не могу воспроизвести функциональность, которая создает средство выбора файлов, позволяя пользователю выбирать, в какую папку он хочет сохранить файл на своем Google Диске.Я могу успешно скопировать файл в корневую папку пользователя на его Google Диске, но я бы предпочел создать средство выбора, позволяющее пользователю размещать его там, где он хочет.

У меня есть файлсредство выбора, созданное для выбора файла для загрузки с Google Диска с использованием примера приложения , предоставленного Google, но, к сожалению, они не предоставляют пример выбора папки.Кроме того, я смог найти документацию для создания средства выбора файлов для веб-приложений, но не для приложений Android.

Я знаю, что могу выбрать имя папки для вставки файла, но как мне создать средство выбора, позволяющее пользователю выбрать папку (и назвать файл) с помощью REST API?Это должно быть простым, и я бы хотел избежать использования сторонних библиотек.

Спасибо!

1 Ответ

0 голосов
/ 13 июля 2019

Этот вопрос немного устарел, так что вы, возможно, уже поняли его.Но у меня была та же самая проблема, поэтому, возможно, другие тоже заинтересовались.

Проблема в том, что 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;
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...