Ouvrir le fichier téléchargé sur Android N à l'aide de FileProvider

J'ai à fixer notre Application pour Android N en raison de la FileProvider changements. J'ai fait tout lu sur ce sujet pour la dernière de la nôtre, mais pas de solution a fonctionné pour moi.

Voici notre code précédent qui commence téléchargements à partir de notre application, les stocke dans la Download dossier et appelle une ACTION_VIEW l'intention de soons comme le DownloadManager dit qu'il est fini le téléchargement:

BroadcastReceiver onComplete = new BroadcastReceiver() {
    public void onReceive(Context ctxt, Intent intent) {
        Log.d(TAG, "Download commplete");

        //Check for our download
        long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
        if (mDownloadReference == referenceId) {
            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(mDownloadReference);
            Cursor c = mDownloadManager.query(query);
            if (c.moveToFirst()) {
                int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
                if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
                    String localUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                    String fileExtension = MimeTypeMap.getFileExtensionFromUrl(localUri);
                    String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);

                    if (mimeType != null) {
                        Intent openFileIntent = new Intent(Intent.ACTION_VIEW);
                        openFileIntent.setDataAndTypeAndNormalize(Uri.parse(localUri), mimeType);
                        openFileIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

                        try {
                            mAcme.startActivity(openFileIntent);
                        }
                        catch (ActivityNotFoundException e) {
                            //Ignore if no activity was found.
                        }
                    }
                }
            }
        }
    }
};

Cela fonctionne sur Android M, mais les pauses N en raison de la populaire FileUriExposedException. J'ai maintenant essayé de résoudre ce problème en utilisant la FileProvider, mais je ne peux pas le faire fonctionner. C'est la rupture, lorsque j'essaie d'obtenir le contenu d'URI:

Failed to find configured root that contains /file:/storage/emulated/0/Download/test.pdf

La localUri retourné à partir de la DownloadManager pour le fichier est:

file:///storage/emulated/0/Download/test.pdf

La Environment.getExternalStorageDirectory() retourne /storage/emulated/0 et c'est le code pour la conversion:

File file = new File(localUri);
Log.d(TAG, localUri + " - " + Environment.getExternalStorageDirectory());
Uri contentUri = FileProvider.getUriForFile(ctxt, "my.file.provider", file);

De AndroidManifest.xml

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

La file_paths.xml:

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

Et j'ai essayé toutes les valeurs que j'ai pu trouver dans ce fichier xml. 🙁

Assurez-vous que vous êtes sur la dernière version de l'Android bibliothèques de prise en charge. Si vous êtes, en improvisant, cela se sent comme un bug dans le courant FileProvider.
file:///storage/emulated/0/Download/test.pdf. Vous ne pouvez pas l'utiliser comme est. Supprimer "file://". Vous devez utiliser un fichier valide chemin: /storage/emulated/0/Download/test.pdf.
Je suis en cours d'exécution sur v24.2.1
L'homme qui vous a sauvé ma vie! Je déteste le code de réduction exemple dans les docs officielles. :/
qu'est-ce que mDownloadReference?

OriginalL'auteur althaus | 2016-10-12