Résolution de l'erreur de configuration FileProvider sur Android

À partir d'Android 7.0 (Nougat), le système impose des restrictions strictes sur le partage de fichires entre applications via des URI file://. Pour contourner cette limitation, le composant FileProvider est utilisé pour générer des URI content://. L'erreur "Failed to find configured root that contains" survient généralement lorsque le répertoire cible du fichier n'est pas correctement mappé dans le fichier XML de configuraton, ou qu'il y a une inadéquation entre le type de chemin déclaré et la méthode d'accès au répertoire utilisée dans le code.

Correspondance entre les nœuds XML et les répertoires système

Pour résoudre ce problème, il est crucial d'aligner les balises du fichier XML (généralement placé dans res/xml/) avec les méthodes de l'API Android utilisées pour obtenir les chemins.

1. Stockage interne privé (Fichiers)

Correspond à Context.getFilesDir() (ex: /data/data/fr.tech.demo/files).

<files-path name="internal_media" path="images/" />

2. Stockage interne privé (Cache)

Correspond à Context.getCacheDir() (ex: /data/data/fr.tech.demo/cache).

<cache-path name="internal_cache" path="temp/" />

3. Stockage externe partagé (Racine)

Correspond à Environment.getExternalStorageDirectory() (ex: /storage/emulated/0).

<external-path name="shared_storage" path="Documents/" />

4. Stockage externe privé (Fichiers)

Correspond à Context.getExternalFilesDir(null) (ex: /storage/emulated/0/Android/data/fr.tech.demo/files).

<external-files-path name="external_media" path="Pictures/" />

5. Stockage externe privé (Cache)

Correspond à Context.getExternalCacheDir() (ex: /storage/emulated/0/Android/data/fr.tech.demo/cache).

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

Prise en charge des cartes SD amovibles

Les balises standard ne couvrent pas les chemins absolus des cartes SD physiques. Si votre application doit accéder à une carte SD externe, vous devez utiliser la balise non documentée root-path pour autoriser l'accès à la racine du système de fichiers.

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

Gestion de multiples répertoires avec un seul FileProvider

Il n'est pas nécessaire de déclarer plusieurs fournisseurs si votre application interagit avec différents dossiers (par exemple, un dossier pour les captures d'écran et un autre pour les mises à jour APK). Vous pouvez regrouper toutes les configurations dans un seul fichier XML et utiliser une autorité unique.

Configuration du fichier res/xml/provider_paths.xml :

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="camera_captures" path="DCIM/" />
    <external-files-path name="app_updates" path="Updates/" />
</paths>

Déclaration dans le AndroidManifest.xml (en utilisant AndroidX) :

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

Lors de la génération de l'URI dans votre code Java ou Kotlin, utilisez la même autorité pour tous les fichiers, quel que soit leur répertoire cible :

File updateFile = new File(context.getExternalFilesDir("Updates"), "release_v2.apk");
Uri contentUri = FileProvider.getUriForFile(
    context, 
    "fr.tech.demo.fileprovider", 
    updateFile
);

Étiquettes: Android FileProvider content-uri androidx xml-configuration

Publié le 7 septembre à 12h08