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. 🙁
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
Vous devez vous connecter pour publier un commentaire.
Grâce à @greenaps j'ai été en mesure de résoudre le problème. Le local URI (extrait de la
DownlodManager
est le préfixe avecfile://
. Ce doit être abandonné pour la nouvelleFileProvider
:N'hésitez pas à poster votre réponse. Je n'ai pas accepté la mienne encore pour ce but.
vous pouvez poster une réponse complète?
OriginalL'auteur althaus
ici changer dans AndroidManifest.xml
changement dans le chemin d'accès au fichier
OriginalL'auteur Arti
Comment obtenir un fichier chemin d'accès exact de nom de fichier. inférieure et supérieure de l'appareil.
public class RealPathUtil {
}
C'est la solution exacte. Appelez simplement
Uri selectedResume = données.getData();
Chaîne mediaResumePath = RealPathUtil.getRealPath(ce, selectedResume);
OriginalL'auteur mahendren
J'ai eu un problème similaire et résolu par pas automatiquement à l'ouverture du fichier, mais en montrant le "Téléchargement terminé" notification et de laisser le système Android, ouvrez le fichier lorsque l'utilisateur clique sur la notification.
Pour avertir l'utilisateur en outre, je fais preuve d'un Toast lorsque le téléchargement est terminé.
BroadcastReceiver:
OriginalL'auteur Marius
Peut être plus claire à ce sujet une solution ?
avant
après
OriginalL'auteur Vlad