Récupérer le chemin du fichier à partir de l'intention de DownloadManager détectée

Depuis Android 4.2 si un utilisateur télécharge un fichier dans le navigateur, le DownloadManager est utilisé. Si l'utilisateur clique sur la notification «télécharger complet», une intention est et a toujours été lancée. Avant l'Android 4.2, l'intention était d'avoir le chemin du fichier téléchargé dans le contenu, de sorte que:

intent.getData() 

file:///storage/emulated/0/Download/some_file.ext une chaîne telle que un file:///storage/emulated/0/Download/some_file.ext . Cependant, depuis Android 4.2, le gestionnaire de téléchargement diffuse et tente avec un schéma de content , tel que le content://downloads/all_downloads/2334 .

  • Notifications de l'utilisateur GCM: champ "registration_ids" manquant
  • Comment réussir à nuire au projet avec Dagger 2.0 à l'aide de Proguard?
  • Erreur lors de la construction du projet Xamarin.Android avec Google Play Services
  • Comment éviter onCreateView () lors de la glissade dans les onglets
  • Afficher la barre d'outils du marqueur Google Maps automatiquement
  • Le stockage local d'une application Phonegap sur un périphérique Android est-il distinct du navigateur intégré?
  • Comment puis-je récupérer le chemin de fichier local pour un fichier téléchargé?

    J'ai essayé ce qui suit:

     public static String getRealPathFromURI(Uri contentUri, Activity activity) { DownloadManager downloadManager = (DownloadManager) activity.getSystemService(Activity.DOWNLOAD_SERVICE); String[] contentParts = contentUri.getEncodedPath().split("/"); Cursor q = downloadManager.query(new DownloadManager.Query().setFilterById(Integer.parseInt(contentParts[contentParts.length - 1]))); if (q == null) { // Download no longer exists return null; } q.moveToFirst(); return q.getString(q.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME)); } 

    Mais le curseur ne renvoie jamais de lignes (donc q.getCount() == 0 et la déclaration de return précédente lance une exception). En outre, le hack en analysant l'ID du fichier de téléchargement de l'Uri semble étrange.

    MISE À JOUR: J'ai également essayé:

     input = getActivity().getContentResolver().openInputStream(contentUri); 

    Mais cela renvoie une erreur indiquant

    Déni de permission: lecture com.android.providers.downloads.DownloadProvider uri content: // téléchargements / all_downloads / 2334 de pid = 30950, uid = 10064 nécessite android.permission.ACCESS_ALL_DOWNLOADS ou grantUriPermission ()

    De toute évidence, je ne peux pas accéder aux téléchargements (car mon application ne les a pas lancés – le navigateur a fait) via ContentProvider .

    3 Solutions collect form web for “Récupérer le chemin du fichier à partir de l'intention de DownloadManager détectée”

    Le fait de passer par le résolveur de contenu est la bonne chose. Chaque URL de contenu ne sera pas un fichier. Par exemple, l'application Gallery vous donnera uri qui se traduit par un appel réseau ou un fichier local en fonction de la source.

    Même si vous obtenez le chemin du fichier réel, vous ne pourrez probablement pas le lire, en raison des autorisations de fichier, bien que vous soyez chanceux, il est sur le stockage externe. Avez-vous essayé d'ajouter android.permission.ACCESS_ALL_DOWNLOADS à votre application, comme l'indique l'exception? Cela ne fonctionnera pas, puisque la permission est au niveau de la signature 🙁

    Voici ce qui a fonctionné. Tout d'abord, vous ne pouvez pas (et ne voulez pas) obtenir le chemin du fichier comme botteaap correctement souligné. (Crédits à lui pour me mettre sur le bon chemin). Au lieu de cela, vous obtenez automatiquement une autorisation provisoire pour accéder au contenu du fichier, en utilisant:

     InputStream input = getContentResolver().openInputStream(intent.getData()); 

    Vous pouvez lire ce InputStream comme n'importe quel autre en Java. Il semble qu'il n'y ait aucun moyen d'obtenir le nom du fichier. Si vous avez besoin d'un fichier, écoutez d'abord le flux d'entrée dans un fichier (temporaire).

    SecurityException est lancé lorsque votre accès temporaire a été révoqué. Cela s'est passé pour moi sur certains fichiers que j'ai essayé de lire de manière incorrecte avant et spécifiquement lorsque l'intention a été prise en compte dans la suite d' onNewIntent .

    Je veux simplement ajouter à la réponse de @erickok car il m'a fallu plusieurs heures pour comprendre cela. Comme l'a déclaré @jcesarmobile, vous êtes seul à pouvoir obtenir le nom et la taille du fichier, et non le chemin complet.

    Vous pouvez obtenir le nom et la taille comme suit, puis enregistrer dans un fichier temporaire:

     String filename = null; Long filesize = null; Cursor cursor = null; try { cursor = this.getContentResolver().query(intent.getData(), new String[] { OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}, null, null, null ); if (cursor != null && cursor.moveToFirst()) { filename = cursor.getString(0); filesize = cursor.getLong(1); } } finally { if (cursor != null) cursor.close(); } 
    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.