Résolution de FileUriExposedException lors de l'installation d'APK sur Android N+

Une exception FileUriExposedException peut se produire lors de l'installation d'un fichier APK sur les appareils exécutant Android 7.0 (Nougat) ou supérieur. Cette erreur survient en raison des politiques de sécurité qui restreignent le partage direct de fichiers via des URI de type file://.

À partir d'Android N, le système applique des restrictions strictes sur l'accès aux répertoires privés. Si une intention contenant une URI file:// est envoyée hors de l'application, elle déclenche cette exception. Pour contourner cela, il faut utiliser des URI sécurisées fournies par un FileProvider.

1. Déclarer le FileProvider dans AndroidManifest.xml

Ajoutez une balise provider dans votre fichier AndroidManifest.xml pour gérer les URI sécurisées :

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.monapplication.installeur.fileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/chemins_fichiers" />
</provider>

Assurez-vous que android:authorities est unique et correspond à votre package. grantUriPermissions doit être true pour permettre l'accès temporaire, et exported doit rester false pour des raisons de sécurité.

2. Configurer les chemins d'accès autorisés

Créez un fichier XML sous res/xml/chemins_fichiers.xml pour spécifier les répertoires accessibles :

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

Ici, path="." autorise l'accès à tous les fichiers sous ce répertoire. Adaptez ces chemins selon vos besoins, par exemple pour cibler un dossier spécifique.

3. Adapter le code d'installation pour Android N et supérieur

Modifiez votre logique d'installation pour utiliser FileProvider sur les versoins compatibles :

Intent installationIntent = new Intent(Intent.ACTION_VIEW);
File fichierApk = new File(getExternalFilesDir(null), "application.apk");

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    Log.d("Installeur", "Chemin du fichier : " + fichierApk.getAbsolutePath());
    installationIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Uri uriProvider = FileProvider.getUriForFile(
        this,
        "com.monapplication.installeur.fileprovider",
        fichierApk
    );
    installationIntent.setDataAndType(uriProvider, "application/vnd.android.package-archive");
} else {
    installationIntent.setDataAndType(
        Uri.fromFile(fichierApk),
        "application/vnd.android.package-archive"
    );
}

installationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(installationIntent);

Cette approche utilise FileProvider.getUriForFile pour générer une URI sécurisée, et attribue le drapeau FLAG_GRANT_READ_URI_PERMISSION pour accorder un accès temporaire.

4. Demander les permissions nécessaires

Pour permettre l'installation d'APK depuis des sources inconnues, déclarez la permission dans AndroidManifest.xml :

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

Sans cette permission, l'application ne pourra pas lancer l'interface d'installation sur les appareils récents.

Étiquettes: Android FileProvider AndroidManifest intent APK

Publié le 20 juin à 21h01