Каков лучший способ использования выходного файла URI Storage Access Framework, чем DocumentFile в Android 10?

Начиная с Android 11 и выше (API > 29), Environment.getexternalstoragedirectory() больше не будет работать. Поскольку большинство библиотек используют параметр java.io.file: Можно ли получить обычный файл из DocumentFile? Придется использовать DocumentFile. Но так как это медленно, я нашел лучшее решение здесь: https://www.reddit.com/r/androiddev/comments/725ee3/documentfile_is_dead_slow_heres/

Есть ли другой способ, чтобы мы могли использовать старые функции java.io.file, начиная с Android 11? Как мы можем использовать Document Поскольку они предоставили поддержку Environment.getexternalstoragedirectory() только до Android Q/Android 10, добавив android:requestLegacyExternalStorage="true" в тег приложения. Я хотел бы знать, как лучше всего обрабатывать файлы. Возможно, тот, который будет совместим со старым java.io.file и потребует меньше кода.

Чтобы открыть средство выбора папок:

Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
        startActivityForResult(Intent.createChooser(i, "Choose Directory"), OPEN_DIRECTORY_REQUEST_CODE);

Онактивитирезультат:

getContentResolver().takePersistableUriPermission(
                       data.getData(),
                       Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION
               );
DocumentFile documentFile = DocumentFile.fromTreeUri(this, data.getdata);

FileNotFound, если я попытаюсь получить файл с помощью Environment.getexternalstoragedirectory()


person cooldev    schedule 05.09.2019    source источник


Ответы (1)


Поскольку большинство библиотек используют параметр java.io.file

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

Есть ли другой способ, чтобы мы могли использовать старые функции java.io.file, начиная с Android 11?

Ограничьте себя частями файловой системы, для которых у вас есть доступ на чтение/запись с помощью методов на Context:

  • getFilesDir()
  • getCacheDir()
  • getExternalFilesDir() и getExternalFilesDirs()
  • getExternalCacheDir() и getExternalCacheDirs()
  • getExternalMediaDir() и getExternalMediaDirs()

Для этих деревьев каталогов вы можете использовать File.

В остальном, в целом, вы обращаетесь с остальной частью устройства так же, как и с Интернетом: получаете InputStream и «загружаете» контент.

person CommonsWare    schedule 05.09.2019
comment
Можете ли вы поделиться примером кода InputStream? Спасибо, CommonsWare, я уже просмотрел ваш блог commonsware. com/blog/2019/03/28/death-external-storage-why.html и нашел его очень полезным и потрясающим! Продолжайте в том же духе. - person cooldev; 05.09.2019
comment
@cooldev: Можете ли вы поделиться примером кода InputStream? -- getContentResolver().openInputStream(yourUri) дает вам InputStream для контента, указанного Uri. Позвоните getContentResolver() по телефону Context. - person CommonsWare; 05.09.2019
comment
@CommonsWare, например, WhatsApp в настоящее время хранит данные во внешнем хранилище, верно? В таком случае как они поведут себя? Если я хочу создать собственную папку во внешнем хранилище, как мне это сделать? - person Vivek MVK; 25.08.2020
comment
@VivekMVK: WhatsApp в настоящее время хранит данные во внешнем хранилище, верно? -- Я не пользуюсь WhatsApp, поэтому не могу ответить на этот вопрос. Если я хочу создать собственную папку во внешнем хранилище, как мне это сделать? -- в течение следующих ~12 месяцев вы можете использовать android:requestLegacyExternalStorage="true" в элементе <application> в манифесте. Кроме того, используйте ACTION_OPEN_DOCUMENT_TREE и позвольте пользователю решить, где пользователь хочет, чтобы его содержимое хранилось на устройстве пользователя (или, возможно, в облачных службах пользователя). - person CommonsWare; 25.08.2020