permission - import file provider android
FileProvider-IllegalArgumentException: no se pudo encontrar la raĆz configurada (30)
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>
<external-files-path name="my_images" path="my_images" />
</paths>
2. archivo Mainfest
File storeDir = getFilesDir(); // path "/"
3.En su archivo Java.
<paths>
<files-path name="my_images" path="/" />
</paths>
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
FileProvider
entender
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.
Compruebe cuántos almacenamientos ofrece su dispositivo: no se admite compartir archivos del almacenamiento secundario.
Mire la fuente
FileProvider.java
(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 interfaz
ContextCompat
.
Consulte la
documentation
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 al almacenamiento coincida con la ruta pasada a
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.
Debe asegurarse de que el contenido de su archivo file_paths.xml contenga esta cadena => "/Android/data/com.example.marek.myapplication/files/Pictures/"
Desde el mensaje de error, esa es la ruta donde se almacenan sus imágenes. Ver muestra de lo esperado
files_path.xml a continuación:
<external-path name="qit_images" path="Android/data/com.example.marek.myapplication/files/Pictures/" />
Debe cambiar el archivo xml file_paths.xml de
<?xml version="1.0" encoding="utf-8"?>
<paths>
<fexeternal-path name="my_images" path="Android/data/com.example.marek.myapplication/files/Pictures"/>
</paths>
a
<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>
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="camera_image" path="Pictures/"/>
</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 ("/")
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="my_images" path="myfile/"/>
</paths>
Entonces su archivo de proveedor debe ser así:
<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>
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>
El problema podría no ser solo la ruta xml.
Lo siguiente es mi solución:
Buscando en el curso raíz en
android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile()
:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="my_images" path="images/"/>
</paths>
Esto significa que
mRoots
debería contener la etiqueta de uri solicitada.
Entonces escribo un código para imprimir
mRoots
y la etiqueta de uri, y luego encuentro fácilmente que las etiquetas no coinciden
.
¡Resulta que establecer la autoridad del proveedor como
${applicationID}.provider
es una 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.
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"/>
Esto funcionó para mí también. En lugar de dar la ruta completa, di path = "Pictures" y funcionó bien.
<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>
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.
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>
Estoy seguro de que llego tarde a la fiesta, pero a continuación funcionó para mí.
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
</paths>
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
files-path
subdirectorio de la
files-path
será
Context.getFilesDir()
.
Lo funky es que
Context.getFilesDir()
anota uno a otro subdirectorio.
lo que estoy buscando es
data/user/0/com.psh.mTest/app_imageDir/20181202101432629.png
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
name="images"
path="Pictures">
</external-files-path>
</paths>
devuelve
/data/user/0/com.psh.mTest/files
entonces la etiqueta debería ser
....
files-path name="app_imageDir" path="../app_imageDir/" ......
¡Entonces funciona!
Llegaría tarde, pero encontré una solución para ello. 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>
Lo que hice para resolver esto:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="files"
path="/" />
</paths>
filepaths.xml (Permitir que FileProvider comparta todos los archivos que están dentro del directorio de archivos externos de la aplicación)
Uri fileProvider = FileProvider.getUriForFile(getContext(),"com.mydomain.fileprovider",newFile);
y en clase java
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;
}
Mi problema fue que tenía nombres superpuestos en las rutas de archivo para diferentes tipos, como este:
<?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>
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.
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:
<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>
Aquí también tiene un excelente tutorial sobre esta pregunta: https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s
Noté que la política o el comportamiento con respecto al archivo
path.xml
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 argumento depath
. -
Con 27, tuve que usar
<external-files-path>
y solo la subcarpeta en el argumento depath
.
Entonces, ¿qué funcionó específicamente para mí con Support Library 27 como el archivo
path.xml
<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>
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
<paths>
<root-path name="root" path="." />
</paths>
2 - Si intentas muchos caminos sin éxito, prueba con esto:
<cache-path
name="cached_files"
path="." />
<external-cache-path
name="cached_files"
path="." />
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.
Recibía este error.
Failed to find configured root that contains...
El siguiente trabajo soluciona mi problema
res / xml / file_paths.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>
AndroidManifest.xml
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)));
}
ActivityClass.java
Context.getFilesDir()
Si está utilizando caché interna, use.
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="cache" path="/" />
</paths>
Si nada ayuda y obtienes el error
File directory = thisActivity.getDir("images", Context.MODE_PRIVATE);
luego intente cambiar alguna línea como:
File directory = new File(thisActivity.getFilesDir(), "images");
a:
<files-path name="files" path="." />
y en el archivo xml:
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);
}
// ...
}
lo cual es extraño, ya que la carpeta a la que accedo es
/images
.
Su archivo se almacena en
getExternalFilesDir()
.
Eso se asigna a
<external-files-path>
, no a
<files-path>
.
Además, su ruta de archivo no contiene
images/
en ella, por lo que el atributo de
path
en su XML no es válido.
Reemplace
res/xml/file_paths.xml
con:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="my_images" />
</paths>
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
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 Manifest appId era 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>
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 deandroid:authorities
en manifiesto -
atributo de
path
en file_paths.xml -
argumento de
authority
al llamar a FileProvider.getUriForFile ().
ninguno de los anteriores funcionó para mí, después de algunas horas de depuración descubrí que el problema está en
createImageFile()
, específicamente
absolute path
frente a la
relative path
Supongo que ustedes están usando la guía oficial de Android para tomar fotos. https://developer.android.com/training/camera/photobasics
<paths>
<external-path
name="my_images"
path="." />
</paths>
Tome nota del
storageDir
, esta 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á en
onActivityResult
si 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
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();
}
}
y si necesitas el mapa de bits después de tomar una foto
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="media" path="." />
</paths>
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
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="apks" path="." />
</paths>
Provider_paths.xml
<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>
Segundo proveedor
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="storage/emulated/0" path="."/>
</paths>
file_path.xml
failed to find configured root that contains /data/data/...
.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é.
Mi problema era un nombre de archivo incorrecto
: creo
file_paths.xml
en res / xml mientras el recurso se configuró en
provider_paths.xml
en el manifiesto:
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);
Cambié
provider_paths
a
file_paths
y problema resuelto.
- 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+. v25.4.0.2+ 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: Xamarin.Forms a apuntar a Oreo desde Nougat en una aplicación Xamarin.Forms y Xamarin.Forms una foto con Xam.Plugin.Media comenzó a fallar con el mensaje de error anterior, por lo que actualizar los paquetes me funcionó bien.