Подтвердить что ты не робот

Выбор файла изображения из галереи с помощью FileProvider

Компиляция для Android N Я столкнулся с проблемой FileProvider. Мне нужно, чтобы пользователь мог выбрать изображение из галереи/сделать снимок с помощью камеры, а затем обрезать его до квадрата.

Мне удалось реализовать FileProvider для съемки с камерой, но у меня есть серьезная проблема с выбором изображения из галереи. Проблема в том, что в галерее есть много файлов из разных мест, и у меня есть Exception, например:

  java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/6133-3766/DCIM/100ANDRO/DSC_0035.JPG

Итак, вопрос в том, что я могу поместить в file_paths.xml, чтобы получить доступ в любом месте /storage/. Я не могу полагаться на точный путь, поскольку, возможно, изображения из WhatsApp и подобных приложений, например, изображение WhatsApp получает этот путь:

/storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20160821-WA0000.jpg

который мне удалось решить пустым путем:

<external-path name="external_storage" path=""/>

который похож на Environment.getExternalStorageDirectory() в соответствии с документацией .

Но до сих пор не удается понять, как обращаться с изображениями, хранящимися в /storage/SOME_DIR/. Пожалуйста, помогите.

4b9b3361

Ответ 1

Я думаю, что этот вопрос основан на недоразумении.

Цель FileProvider - предоставить доступ (внешнему приложению) к файлу, который уже контролирует ваше приложение.

Вам никогда не удастся использовать собственный поставщик файлов, чтобы получить доступ к файлу, принадлежащему внешнему приложению.

Это зависит от внешнего приложения, которое предоставит вам доступ с помощью поставщика файлов, если он захочет.

Кажется, это вопрос, о котором идет речь. Если я не понял ваш вопрос, дайте мне знать, но если я пойму это, то, что вы пытаетесь сделать, просто не сработает.

Ответ 2

Согласовано с @x-code, вы не очень хорошо разбираетесь в проблеме, хотя, если вы пытаетесь получить доступ к внутренним данным другого приложения, тогда у вас должны быть разрешения на это.

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

Собственно, я нашел в документации, что версия SDK 24 теперь обновлена ​​многими схемами и имеет значительные изменения в работе с файлами, из документации проблема с файлом:// описывается как..

Передача файла://URI вне домена пакета могут оставить приемник с недостижимым путем. Поэтому попытки передать файл://URI запускают FileUriExposedException. Рекомендуемым способом совместного использования содержимого частного файла является использование FileProvider.

Из-за соображений безопасности настоятельно рекомендуется использовать Content://вместо использования файла://поэтому в основном используйте ContentProvider вместо FileProvider.

Простой пример его использования ниже,

in AndroidMenifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>
</manifest> 

И затем создайте файл поставщика _paths.xml в папке xml в папке res. Папка может понадобиться для создания, если она не существует.

Содержимое файла показано ниже. В нем описано, что мы хотели бы предоставить доступ к внешнему хранилищу в корневой папке (path=".") с именем external_files.

Рез /XML/provider _paths.xml

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

теперь использовать его,

Uri photoURI = FileProvider.getUriForFile(MainActivity.this,
        BuildConfig.APPLICATION_ID + ".provider",
        createImageFile());

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