Загрузка фотографии с помощью FileProvider, вызывающая java.lang.IllegalArgumentException: не удалось найти настроенный корень, который содержит

Я хочу использовать FileProvider для получения фото с камеры. Я сделал все из этого туториала, но параметр authority вызывает ошибку.

Учебник: https://developer.android.com/reference/androidx/core/content/FileProvider

Провайдер внутри AndroidManifest:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

provider_paths.xml :

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

ОБНОВЛЕНИЕ:

Это функция создания файла:

private fun createImageFile(): File {
        val timeStamp = SimpleDateFormat(
            "yyyyMMdd_HHmmss",
            Locale.getDefault()
        ).format(Date())
        val imageFileName = "IMG_" + timeStamp + "_"
        val image = File.createTempFile(
            imageFileName, /* prefix */
            ".jpg", /* suffix */
            null      /* directory */
        )

        return image
    }

Это provider_paths.xml (мне не нужен внешний путь, потому что я не хочу, чтобы пользователь принимал разрешения на хранение для использования камеры):

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name = "name"
        path = "path" />
</paths>

Это функция открытой камеры:

private fun openCamera() {
        val tempFile = createImageFile()
        photoUri = Uri.fromFile(tempFile)
        photoUri = FileProvider.getUriForFile(a, a.applicationContext.packageName + ".fileprovider", tempFile)

        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
        if (intent.resolveActivity(a.packageManager) != null) {
            a.startActivityForResult(intent, REQUEST_CAMERA_NODE_MISUSE)
        }
    }

Ошибка: Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/my.package.name/cache/IMG_20190620_102915_7513574861671405500.jpg


person martin1337    schedule 20.06.2019    source источник
comment
добавьте файл манифеста сюда   -  person Radhey    schedule 20.06.2019


Ответы (1)


Убедитесь, что вы указали поставщика файлов в манифесте внутри тега application.

<application
            ...>
     ....
    <provider
            android:authorities = "your_string"
            android:name = "androidx.core.content.FileProvider"
            android:exported = "false"
            android:grantUriPermissions = "true">
        <meta-data
                android:resource = "@xml/file_path"
                android:name = "android.support.FILE_PROVIDER_PATHS" />
    </provider>
</application>

А мой file_path.xml такой

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
            name = "my_images"
            path = "Android/data/com.your.package/files/Pictures" />
</paths>

И из java-кода

val authorities = "your_string"

val imageUri = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
     FileProvider.getUriForFile(context!!, authorities, imageFile)
else
     Uri.fromFile(imageFile)

callCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
            startActivityForResult(
                callCameraIntent,
                CAMERA_REQUEST_CODE
            )

Обновить

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

`android:authorities = "${applicationId}.fileprovider"`

в вашем Java-коде замените это

photoUri = FileProvider.getUriForFile(a, a.applicationContext.packageName + ".provider", tempFile)

к этому

photoUri = FileProvider.getUriForFile(a, a.applicationContext.packageName + ".fileprovider", tempFile)

Второе обновление

В этой функции вы переходите в каталог, которого быть не должно:

private fun createImageFile(): File {
        val timeStamp = SimpleDateFormat(
            "yyyyMMdd_HHmmss",
            Locale.getDefault()
        ).format(Date())
        val imageFileName = "IMG_" + timeStamp + "_"
        val image = File.createTempFile(
            imageFileName, /* prefix */
            ".jpg", /* suffix */
            null      /* directory */
        )

        return image
    }

Попробуй это

private fun createImageFile(): File {
            val timeStamp = SimpleDateFormat(
                "yyyyMMdd_HHmmss",
                Locale.getDefault()
            ).format(Date())
            val imageFileName = "IMG_" + timeStamp + "_"
            val image = File.createTempFile(
                imageFileName, /* prefix */
                ".jpg", /* suffix */
                context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) //null /* directory */
            )

            return image
        }
person Jasurbek    schedule 20.06.2019
comment
Пробовал ваш, не работает. То же исключение. Мой file_path.xml также взят из учебника. - person martin1337; 20.06.2019
comment
Я нашел вашу ошибку, посмотрите мой обновленный ответ - person Jasurbek; 20.06.2019
comment
Я видел это раньше и заменил это, но после обновления это не работает - person martin1337; 20.06.2019
comment
Опубликуйте свой полный код, манифест, provider_paths и код Java, тогда, возможно, я смогу обнаружить вашу ошибку. - person Jasurbek; 20.06.2019
comment
В этой функции вы переходите в каталог, которого быть не должно: см. мой ответ - person Jasurbek; 20.06.2019
comment
Использовал ваше решение для каталогов и все еще такое же исключение. Я действительно не знаю, что не так. Проверил 4 разных учебника для FireProvider, и мой код точно такой же. - person martin1337; 20.06.2019
comment
Давайте продолжим обсуждение в чате. - person Jasurbek; 20.06.2019