FileProvider и URI содержимого MediaStore - PullRequest
0 голосов
/ 10 марта 2019

Я пытаюсь создать базовый файловый менеджер для просмотра файлов внешнего хранилища на моем Android P устройстве.У меня есть два метода , которые создают намерения открыть файлы с помощью внешних приложений .Оба метода одинаковы , за исключением Uri part.

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

content://com.myapp.FILE_PROVIDER/external_files/6537-6630/DCIM/Camera/20180727_221149.jpg

Другой запрашивает MediaStore и возвращает Uri, который выглядит следующим образом:

content://media/external/images/media/3273

Остальная часть кода идентична

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setDataAndType(uri, mimeType);
startActivity(intent);

Оба URI действительны, однако, когда я открываю изображения (случайные изображения из внешнего хранилища), используя тот, который создан с FileProvider , они открываются с доступом только для чтения ввнешние приложения.Я могу сказать это, потому что у меня нет вариантов редактирования.Изображение из Uri с помощью MediaStore открывается, как и ожидалось, с доступом для записи и, следовательно, с возможностями редактирования.

Я также загрузил пару файловых менеджеров из магазина Play.Например, Диспетчер файлов - локальный и облачный обозреватель файлов (я полагаю, он использует FileProvider) имеет ту же проблему доступа только для чтения при открытии изображений.

Код

    <provider
        android:name="com.myapp.files.MyFileProvider"
        android:authorities="${applicationId}.FILE_PROVIDER"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="." />
    <root-path name="external_files" path="/storage/" />
</paths>

Мои вопросы:

1.Я что-то пропускаю при использовании FileProvider?Может быть, он не предназначен для хранения внешних файлов?

2.Существуют ли другие способы получения действительных URI для существующих файлов?Поскольку MediaStore не имеет всех файлов

1 Ответ

0 голосов
/ 10 марта 2019

Может быть, он не предназначен для файлов внешнего хранилища?

Вы не используете его для внешнего хранилища .Вы используете его для съемного хранилища .

<root-path> недокументировано и не поддерживается.FileProvider не будет надежно работать со съемным хранилищем, поскольку ваше приложение не имеет доступа к произвольным расположениям файловой системы на съемном хранилище.Я предполагаю, что если вы попытаетесь записать этот файл в свое приложение - будь то с помощью File или Uri - у вас произойдет ошибка с ошибкой.

MediaStore имеет доступ к большему количеству съемных носителейпотому что это часть ОС.

Существуют ли другие способы получения действительных URI для существующих файлов?

Вы можете использовать ACTION_OPEN_DOCUMENT_TREE и задатьПользователь выбирает свое съемное хранилище.Затем вы можете:

  • Использовать takePersistableUriPermission(), чтобы получить долгосрочный доступ к дереву документов, которое выбрал пользователь
  • Использовать DocumentFile, чтобы пройти по этому дереву документов и получить Uri значения для документов в нем

Просто имейте в виду, что пользователю не нужно выбирать свое съемное хранилище - он может выбирать любое дерево документов по своему усмотрению.Если все сделано правильно, это может быть функция, а не ошибка в вашем приложении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...