FileProvider - IllegalArgumentException: no se pudo encontrar la raíz configurada

234

Estoy tratando de tomar una foto con la cámara, pero recibo el siguiente error:

FATAL EXCEPTION: main
Process: com.example.marek.myapplication, PID: 6747
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example.marek.myapplication/files/Pictures/JPEG_20170228_175633_470124220.jpg
    at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:711)
    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
    at com.example.marek.myapplication.MainActivity.dispatchTakePictureIntent(MainActivity.java:56)
    at com.example.marek.myapplication.MainActivity.access$100(MainActivity.java:22)
    at com.example.marek.myapplication.MainActivity$1.onClick(MainActivity.java:35)

AndroidManifest.xml:

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.marek.myapplication.fileprovider"
        android:enabled="true"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

Java:

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            Toast.makeText(getApplicationContext(), "Error while saving picture.", Toast.LENGTH_LONG).show();
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this,
                    "com.example.marek.myapplication.fileprovider",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }

file_paths.xml

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

Estuve buscando todo el día sobre este error e intenté entenderlo FileProvider, pero no tengo idea de lo que este mensaje de error intenta decirme. Si quieres más información / código, escríbeme en el comentario.

Pivoman
fuente
2
¿Puedes pegar también el código del método createImageFile?
Ankit Batra
Lo siento mucho, pero cancelé este proyecto y ya no estoy trabajando en ello . Aceptaré la respuesta más favorita para "cerrar" esta pregunta. Gracias a todos por su participación y espero que ayude a los demás.
Pivoman
Me encontré con el mismo problema. Encontré esta solución para obtener una configuración básica de FileProvider utilizando un proyecto de ejemplo de github mínimo: stackoverflow.com/a/48103567/2162226 . Proporciona los pasos para los archivos a copiar (sin hacer cambios) en un proyecto independiente local
Gene Bo
Este problema ahora está solucionado en Delphi 10.4: quality.embarcadero.com/browse/RSP-26950
Dave Nottage

Respuestas:

211

Su archivo está almacenado en getExternalFilesDir(). Eso se asigna a <external-files-path>, no <files-path>. Además, su ruta de archivo no contiene images/, por lo que el pathatributo en su XML no es válido.

Reemplazar res/xml/file_paths.xmlcon:

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

ACTUALIZACIÓN 2020 MAR 13

Ruta del proveedor para una ruta específica de la siguiente manera:

  • <files-path/> -> Context.getFilesDir()
  • <cache-path/> -> Context.getCacheDir()
  • <external-path/> -> Environment.getExternalStorageDirectory()
  • <external-files-path/> -> Context.getExternalFilesDir(String)
  • <external-cache-path/> -> Context.getExternalCacheDir()
  • <external-media-path/> -> Context.getExternalMediaDirs()

Ref: https://developer.android.com/reference/androidx/core/content/FileProvider

CommonsWare
fuente
55
ok, agregué la ruta de archivos externos, pero todavía tengo el mismo error: / Quizás haya más errores. Estoy usando un dispositivo emulador de Android, ¿tengo que crear esa carpeta o algo así?
Pivoman
22
"Se debe definir el atributo 'ruta'" aquí falta la ruta en la configuración.
blackjack
1
Estaba teniendo un problema con varias rutas en Android 5. Dejé solo una ruta, en lugar de 2.
ODAXY
3
Recibí un informe de bloqueo (de 50-100 dispositivos, creo) que es idéntico a este. <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="extfiles" path="."/> </paths>Esto path="."es lo que encontré en mi propia investigación para permanecer en el nivel superior. Si revisa FileProvider más de cerca, verá que la ruta leída desde XML se canoniza. Mi mejor conjetura es que ContextCompat#getExternalFilesDirsdevolvió nulo @line 616 (v26.0.1), por lo que PathStrategy no estaba registrado. Esto ocurrió en el dispositivo Huawei.
androidguy
10
En lugar de usar <external-files-path, probé <external-path y funcionó.
seguro
166

Esto puede resolver el problema de todos: se agregan todas las etiquetas para que no tenga que preocuparse por la ruta de las carpetas. Reemplace res / xml / file_paths.xml con:

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <external-path
    name="external"
    path="." />
  <external-files-path
    name="external_files"
    path="." />
  <cache-path
    name="cache"
    path="." />
  <external-cache-path
    name="external_cache"
    path="." />
<files-path
    name="files"
    path="." />
</paths>
Mitul Varmora
fuente
3
Mejor solución. Gracias.
Pawan Pillai
1
Solución simple ... pero para este brillante! Usé un proveedor y luego ingresé a la posibilidad del usuario para cambiar el directorio de destino ... ya nada funcionó porque en ese punto el proveedor debería ser dinámico ... ¡me salvaste el día!
Bronz
1
utilizó esta solución y el código comenzó a funcionar. Se eliminó el código innecesario al probar cuál de estos funcionaba
Kartik,
1
Hermano, me salvaste el día. Muchas gracias :-)
manjunath kallannavar
1
Genial funcionó para mí, como nuevo alumno me hizo darme cuenta de que no estaba obteniendo archivos externos sino caché
Tony Merritt
82

Tengo un problema similar después de los sabores habilitados (dev, stage).

Antes de los sabores, mi recurso de ruta se veía así:

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

Después de agregar android: autoridades = "$ {applicationId} .fileprovider" en el Manifiesto appId fue pl.myapp.dev o pl.myapp.stage depende del sabor y la aplicación comenzó a fallar. Eliminé la ruta completa y la reemplacé con punto y todo comenzó a funcionar.

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="my_images"
        path="." />
</paths>
antigravedad
fuente
77
Trabajó para mi. ¡Gracias! Cómo se te ocurrió '.' notación?
NightFury
2
@antygravity, ¿puede proporcionar referencia / documentación de esta solución?
geekoraul
77
¿Hay alguna consecuencia negativa de esta solución?
RediOne1
Trabajó para mí, muchas gracias.
Hiren
¡Esta debería ser la respuesta aceptada! La única solución que funcionó
egorikem el
43

Si está utilizando caché interna, use.

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache" path="/" />
</paths>
Inocente
fuente
3
gracias, mi situación: quiero instalar una aplicación que guarde en / data / data / pkg_name / files, así que mi configuración correcta es la siguiente: <files-path name = "files" path = "/" />
aolphn
25

Perdí 2 semanas tratando de encontrar alguna solución ... Si llegas aquí después de intentar todo lo anterior:

1 - Verifique si su proveedor de etiquetas está dentro de la aplicación de etiquetas

<application>

    <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.companyname.Pocidadao.fileprovider" android:exported="false" android:grantUriPermissions="true">
      <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
    </provider>

</application>

2 - Si intentas muchos caminos sin éxito, prueba con esto:

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

  <root-path name="root" path="." />
  <files-path name="my_images" path="/" />
  <files-path name="my_images" path="myfile/"/>
  <files-path name="files" path="." />

  <external-path name="external_files" path="." />
  <external-path name="images" path="Pictures" />
  <external-path name="my_images" path="." />
  <external-path name="my_images" path="Android/data/com.companyname.yourproject/files/Pictures" />
  <external-path name="my_images" path="Android/data/com.companyname.yourproject/files/Pictures/" />

  <external-files-path name="images" path="Pictures"/>
  <external-files-path name="camera_image" path="Pictures/"/>
  <external-files-path name="external_files" path="." />
  <external-files-path name="my_images" path="my_images" />

  <external-cache-path name="external_cache" path="." />

</paths>

Pruebe esto, si la cámara funciona, luego comience a eliminar algunas líneas y continúe probando ...

3 - No olvide verificar si la cámara está activada en su emulador.

Diego Venâncio
fuente
1
Gracias, esto funcionó para mí. ¿Es necesario eliminar otros caminos?
CodeSlave
22

Estoy seguro de que llego tarde a la fiesta, pero a continuación funcionó para mí.

<paths>
    <root-path name="root" path="." />
</paths>
espartano
fuente
¡Este fue el paso final para que mi código funcionara también! Gracias.
Dog Dogma
15

Esto me confunde un poco también.

El problema está en el atributo "ruta" en su archivo xml.

De este documento FileProvider 'ruta' es un subdirectorio, pero en otro documento (cámara / fotobásico) que se muestra 'ruta' es ruta completa.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>

Simplemente cambio esta 'ruta' a ruta completa y simplemente funciona.

Supakij
fuente
15

Llegaría tarde, pero encontré una solución para eso. Trabajé bien para mí, solo cambié el archivo XML de rutas a:

 <?xml version="1.0" encoding="utf-8"?>
<paths>
    <root-path name="root" path="." />
</paths>
subbu
fuente
1
Para mí, esto provider_paths.xmlda una advertencia de inspección "La ruta raíz del elemento no está permitida aquí".
Luis A. Florit
15

Tenga en cuenta que la ruta externa no apunta a su almacenamiento secundario, también conocido como "almacenamiento extraíble" (a pesar del nombre "externo"). Si obtiene "Error al encontrar la raíz configurada", puede agregar esta línea a su archivo XML.

<root-path name="root" path="." />

Ver más detalles aquí FileProvider y almacenamiento externo secundario

Peter Shashkin
fuente
14

Compruebe cuántos almacenamientos ofrece su dispositivo: no se admite compartir archivos del almacenamiento secundario. Mire la FileProvider.javafuente (de support-core-utils 25.3.1 ):

            } else if (TAG_EXTERNAL_FILES.equals(tag)) {
                File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null);
                if (externalFilesDirs.length > 0) {
                    target = externalFilesDirs[0];
                }
            } else if (TAG_EXTERNAL_CACHE.equals(tag)) {
                File[] externalCacheDirs = ContextCompat.getExternalCacheDirs(context);
                if (externalCacheDirs.length > 0) {
                    target = externalCacheDirs[0];
                }
            }

Entonces, toman solo el primer almacenamiento.

Además, puede ver que getExternalCacheDirs()se utiliza para obtener una lista de almacenamientos a través de la ContextCompatinterfaz. Consulte la documentación para conocer sus límites (se le dice que no reconozca los flashes USB, por ejemplo). Lo mejor es hacer una salida de depuración de la lista de almacenamientos de esta API por su cuenta, para que pueda verificar que la ruta de almacenamiento coincida con la ruta pasada getUriForFile().

Ya hay un ticket asignado (para el período 06-2017) en el rastreador de problemas de Google, que solicita admitir más de un almacenamiento. Finalmente, encontré SO pregunta sobre esto también.

izquierda
fuente
1
Esta respuesta en profundidad debería estar recibiendo más votos a favor. Gracias por buscar qué almacenamiento externo FileProvider reconoce realmente.
LarsH
10

He pasado 5 horas para esto ...

He probado todos los métodos anteriores, pero depende de qué almacenamiento esté usando su aplicación actualmente.

https://developer.android.com/reference/android/support/v4/content/FileProvider#GetUri

Consulte la documentación antes de probar los códigos.

En mi caso, ya que el files-pathsubdirectorio será Context.getFilesDir(). Lo funky es que se Context.getFilesDir()nota uno al otro subdirectorio.

lo que estoy buscando es

data/user/0/com.psh.mTest/app_imageDir/20181202101432629.png

Context.getFilesDir()

devoluciones /data/user/0/com.psh.mTest/files

entonces la etiqueta debería ser

....files-path name="app_imageDir" path="../app_imageDir/" ......

¡Entonces funciona!

Parque Seho
fuente
1
Gracias por referirse a la documentación. Me llevó a la respuesta correcta. En mi caso, mi archivo se guardó getExternalStorageDirectory()y se suponía que debía proporcionar la ruta con la <external-path>etiqueta en lugar de<files-path>
alierdogan7
Gracias por esta respuesta específica en files-path. Ayudó mucho :)
arungiri_10
¡¡¡Si, funciona!!! el punto clave es especificar el ".." al comienzo de la ruta, como esta ruta = "../ myDirectory /"
Robert Apikyan
9

Nada de esto funcionó para mí. El único enfoque que funciona es no declarar una ruta explícita en xml. Haz esto y sé feliz:

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

Aquí también tiene un excelente tutorial sobre esta pregunta: https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s

Paulo Linhares - Packapps
fuente
7

Mi problema fue que tenía nombres superpuestos en las rutas de archivo para diferentes tipos, como este:

<cache-path
    name="cached_files"
    path="." />
<external-cache-path
    name="cached_files"
    path="." />

Después de cambiar los nombres ("cached_files") para que sean únicos, me deshice del error. Supongo que esas rutas se almacenan en algún HashMap o algo que no permite duplicados.

Peligro
fuente
3

Lo que hice para resolver esto:

AndroidManifest.xml

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.mydomain.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"/>
        </provider>

filepaths.xml (Permitir que FileProvider comparta todos los archivos que están dentro del directorio de archivos externos de la aplicación)

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

y en clase java

Uri fileProvider = FileProvider.getUriForFile(getContext(),"com.mydomain.fileprovider",newFile);
Rupam Das
fuente
3

Esto funcionó para mí también. En lugar de dar la ruta completa, di path = "Pictures" y funcionó bien.

<?xml version="1.0" encoding="utf-8"?>
 <paths>
  <external-files-path
    name="images"
    path="Pictures">
  </external-files-path>
 </paths>
Amit Arora
fuente
2

Depende del tipo de almacenamiento que desee hacer, INTERNO o EXTERNO

para ALMACENAMIENTO EXTERNO

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

pero para ALMACENAMIENTO INTERNO, tenga cuidado con la ruta, ya que utiliza el método getFilesDir (), lo que significa que su archivo se ubicará en el directorio raíz de la aplicación ("/")

  File storeDir = getFilesDir(); // path "/"

Entonces su archivo de proveedor debe ser así:

<paths>
    <files-path name="my_images" path="/" />
</paths>
Christian Altamirano Ayala
fuente
Todos los ejemplos suponen que el usuario está utilizando almacenamiento externo. Necesitaba ayuda con el almacenamiento interno y tardé horas en encontrar esta respuesta. Gracias.
zeeshan
2

ninguna de las anteriores trabajado para mí, después de unas horas de depuración descubrí que el problema está en createImageFile(), específicamente absolute pathvsrelative path

Supongo que ustedes están usando la guía oficial de Android para tomar fotos. https://developer.android.com/training/camera/photobasics

    private static File createImageFile(Context context) throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }

Tome nota de que storageDiresta es la ubicación donde se creará el archivo. Entonces, para obtener la ruta absoluta de este archivo, simplemente uso image.getAbsolutePath(), esta ruta se usará onActivityResultsi necesita la imagen de mapa de bits después de tomar la foto

a continuación está el file_path.xml, simplemente use .para que use la ruta absoluta

<paths>
    <external-path
        name="my_images"
        path="." />
</paths>

y si necesitas el mapa de bits después de tomar una foto

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Bitmap bmp = null;
        try {
            bmp = BitmapFactory.decodeFile(mCurrentPhotoPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
grandia
fuente
2

Estaba recibiendo este error Failed to find configured root that contains...

El siguiente trabajo soluciona mi problema

res / xml / file_paths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="media" path="." />
</paths>

AndroidManifest.xml

<provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="[PACKAGE_NAME]"
      android:exported="false"
      android:grantUriPermissions="true">
         <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths">
         </meta-data>
</provider>

ActivityClass.java

void shareImage() {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,"com.slappstudio.pencilsketchphotomaker", selectedFilePath));
        startActivity(Intent.createChooser(intent,getString(R.string.string_share_with)));
    }
Ali Tamoor
fuente
1

El documento oficial de Android dice que file_paths.xml debería tener:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">   
    <external-path name="my_images"    
        path="Android/data/com.example.package.name/files/Pictures" />
</paths>

Pero para que funcione en el último Android, debería haber un "/" al final del camino, como este:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">   
    <external-path name="my_images"    
        path="Android/data/com.example.package.name/files/Pictures/" />
</paths>
Shripad Bhat
fuente
1

El siguiente cambio en el archivo xml file_paths funcionó para mí.

 <external-files-path name="my_images" path="Pictures"/>
 <external-files-path name="my_movies" path="Movies"/>
Manmohan Soni
fuente
1

Tuve el mismo problema, probé el siguiente código para que funcione.

1.Cree Xmlfile: proveedor_rutas

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

2. archivo Mainfest

 <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.ril.learnet.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
 </provider>

3.En su archivo Java.

      File file =  new File(getActivity().getFilesDir(), "myfile");
        if (!file.exists()) {
            file.mkdirs();
        }
        String  destPath = file.getPath() + File.separator + attachmentsListBean.getFileName();

               file mfile = new File(destPath);
                Uri path;
                Intent intent = new Intent(Intent.ACTION_VIEW);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
                {
                    path = FileProvider.getUriForFile(AppController.getInstance().getApplicationContext(), AppController.getInstance().getApplicationContext().getPackageName() + ".provider", mfile );
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                } else {
                    path = Uri.fromFile(mfile);
                }
   intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.setDataAndType(path, "image/*");
                    getActivity().startActivity(intent);
Suresh Kumar
fuente
1

Si nada ayuda y obtienes el error

failed to find configured root that contains /data/data/...

luego intente cambiar alguna línea como:

File directory = thisActivity.getDir("images", Context.MODE_PRIVATE);

a:

File directory = new File(thisActivity.getFilesDir(), "images");

y en el archivo xml:

<files-path name="files" path="." />

lo cual es extraño, ya que la carpeta a la que accedo es /images.

LivinTheNoobLife
fuente
Cambiar de .getDir a .getFilesDir me ayudó. ¡Gracias!
Dmitriy Pavlukhin
1

Mi problema era un nombre de archivo incorrecto : creo file_paths.xmlbajo res / xml mientras el recurso estaba configurado provider_paths.xmlen Manifiesto:

<provider
        android:authorities="ir.aghigh.radio.fileprovider"
        android:name="android.support.v4.content.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

He cambiado provider_pathsa file_pathsy problema resuelto.

Saeed Arianmanesh
fuente
1

Si su ruta de archivo es como / storage / emulated / 0 / "yourfile"

solo necesitas modificar tu FileProvider xml

<paths>
    <external-path name="external" path="." />
</paths>

luego llame a esta función cuando necesite compartir archivos

Intent sharingIntent = new Intent(Intent.ACTION_SEND);
                    Uri fileUri = FileProvider.getUriForFile(getContext(),
                            "com.example.myapp.fileprovider",
                            file);
                    sharingIntent.setType("*/*"); // any flie type
                    sharingIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
                    startActivity(Intent.createChooser(sharingIntent, "Share file"));

funciona en android M ~ Pie

perezoso
fuente
¡Funciona! Pero, ¿puede explicar por qué usamos path = "." en lugar de path = "DCIM", "Imágenes" ...?
Hoang Lam
@Hoang Lam La diferencia es si necesita especificar un directorio, en mi ejemplo, puede acceder a todos
perezoso
0

Veo que al menos no está proporcionando la misma ruta que otros en file_paths.xml. Por lo tanto, asegúrese de proporcionar exactamente el mismo nombre de paquete o ruta en 3 lugares, incluidos:

  • android:authorities atributo en manifiesto
  • path atributo en file_paths.xml
  • authority argumento al llamar a FileProvider.getUriForFile ().
Pei
fuente
0
  • Para usuarios de Xamarin.Android

Esto también podría ser el resultado de no actualizar sus paquetes de soporte cuando apunta a Android 7.1, 8.0+. Actualícelos a v25.4.0.2 + y este error en particular podría desaparecer (si configuró su archivo file_path correctamente como lo indicaron otros).


Contexto: cambié a apuntar a Oreo desde Nougat en una aplicación Xamarin.Forms y tomé una foto con Xam.Plugin.Media comenzó a fallar con el mensaje de error anterior, por lo que actualizar los paquetes me funcionó bien.

Ahmed Alejo
fuente
0

Noté que la política o el comportamiento con respecto al path.xmlarchivo cambió entre Support Library 26 y 27. Para capturar una imagen de la cámara, vi los siguientes cambios:

  • Con 26, tuve que usar <external-path>y la ruta completa dada en el pathargumento.

  • Con 27, tuve que usar <external-files-path>y solo la subcarpeta en el pathargumento.

Entonces, ¿qué funcionó específicamente para mí con Support Library 27 ya que el path.xmlarchivo era

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="camera_image" path="Pictures/"/>
</paths>
Johan Paul
fuente
0

Hola amigos, intenta esto

En este código

1) Cómo declarar el proveedor de 2 archivos en manifiesto.

2) Primer proveedor de descarga de archivos

3) segundo proveedor utilizado para cámara y gallary

PASO 1

     <provider
        android:name="android.support.v4.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>
<files-path name="apks" path="." />
</paths>

Segundo proveedor

     <provider
        android:name=".Utils.MyFileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true"
        tools:replace="android:authorities"
        tools:ignore="InnerclassSeparator">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_path" />
    </provider>

file_path.xml

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

.Utils.MyFileProvider

Crear clase MyFileProvider (solo Crear clase sin ningún método declarar)

Cuando usó File Provider usó (.fileprovider) este nombre y usó para la imagen (.provider) usó esto.

Si hay algún problema para entender este código, puede contactar en [email protected], lo ayudaré.

Rahul Patil
fuente
0

El problema podría no ser solo la ruta xml.

Lo siguiente es mi solución:

Mirando el curso raíz en android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile():

    public File getFileForUri(Uri uri) {
        String path = uri.getEncodedPath();

        final int splitIndex = path.indexOf('/', 1);
        final String tag = Uri.decode(path.substring(1, splitIndex));
        path = Uri.decode(path.substring(splitIndex + 1));

        final File root = mRoots.get(tag); // mRoots is parsed from path xml
        if (root == null) {
            throw new IllegalArgumentException("Unable to find configured root for " + uri);
        }

        // ...
    }

Esto significa que mRootsdebe contener la etiqueta de uri solicitada. Entonces escribo un código para imprimir mRootsy una etiqueta de uri, y luego encuentro fácilmente que las etiquetas no coinciden .

¡Resulta que establecer la autoridad del proveedor como ${applicationID}.provideruna idea estúpida ! Esta autoridad es tan común que podría ser utilizada por otros proveedores, lo que arruinará la configuración de la ruta.

Thundertrick
fuente
-1

Debe cambiar el archivo xml file_paths.xml de

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

a

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <fexeternal-path name="my_images" path="Android/data/com.example.marek.myapplication/files/Pictures"/>
</paths>
Andrey
fuente
1
Aunque ha copiado su respuesta de arriba, no se ha hecho correctamente. Corrija la falta de coincidencia de escritura en su respuesta.
Abhinav Saxena