Android: Obtenir un URI de fichier à partir d’un URI de contenu?

Dans mon application, l’utilisateur doit sélectionner un fichier audio que l’application gère ensuite. Le problème est que pour que l’application fasse ce que je veux avec les fichiers audio, j’ai besoin que l’URI soit au format de fichier. Lorsque j’utilise le lecteur de musique natif d’Android pour rechercher le fichier audio dans l’application, l’URI est un URI de contenu, qui ressemble à ceci:

content://media/external/audio/media/710 

Cependant, en utilisant l’application de gestionnaire de fichiers populaire Astro, j’obtiens les éléments suivants:

 file:///sdcard/media/audio/ringtones/GetupGetOut.mp3 

Ce dernier est beaucoup plus accessible pour moi, mais je veux bien sûr que l’application soit compatible avec le fichier audio choisi par l’utilisateur, quel que soit le programme utilisé pour parcourir sa collection. Donc, ma question est la suivante: existe-t-il un moyen de convertir le content:// URI de style dans un file:// URI? Sinon, que recommanderiez-vous pour résoudre ce problème? Voici le code qui appelle le sélecteur, à titre de référence:

 Intent ringIntent = new Intent(); ringIntent.setType("audio/mp3"); ringIntent.setAction(Intent.ACTION_GET_CONTENT); ringIntent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(Intent.createChooser(ringIntent, "Select Ringtone"), SELECT_RINGTONE); 

Je fais ce qui suit avec l’URI de contenu:

 m_ringerPath = m_ringtoneUri.getPath(); File file = new File(m_ringerPath); 

Ensuite, faites des choses avec FileInputStream avec ce fichier.

Utilisez simplement getContentResolver().openInputStream(uri) pour obtenir un InputStream depuis un URI.

http://developer.android.com/reference/android/content/ContentResolver.html#openInputStream(android.net.Uri)

Vous pouvez utiliser le résolveur de contenu pour obtenir un file:// chemin à partir du content:// URI:

 Ssortingng filePath = null; Uri _uri = data.getData(); Log.d("","URI = "+ _uri); if (_uri != null && "content".equals(_uri.getScheme())) { Cursor cursor = this.getContentResolver().query(_uri, new Ssortingng[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null); cursor.moveToFirst(); filePath = cursor.getSsortingng(0); cursor.close(); } else { filePath = _uri.getPath(); } Log.d("","Chosen path = "+ filePath); 

Essayer de gérer l’URI avec le schéma content: // en appelant ContentResolver.query() n’est pas une bonne solution. Sur HTC Desire 4.2.2, vous pouvez obtenir NULL comme résultat de requête.

Pourquoi ne pas utiliser ContentResolver à la place? https://stackoverflow.com/a/29141800/3205334

Si vous avez un contenu Uri avec un content://com.externalstorage... vous pouvez utiliser cette méthode pour obtenir le chemin absolu d’un dossier ou d’un fichier sur Android 19 ou supérieur .

 public static Ssortingng getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { System.out.println("getPath() uri: " + uri.toSsortingng()); System.out.println("getPath() uri authority: " + uri.getAuthority()); System.out.println("getPath() uri path: " + uri.getPath()); // ExternalStorageProvider if ("com.android.externalstorage.documents".equals(uri.getAuthority())) { final Ssortingng docId = DocumentsContract.getDocumentId(uri); final Ssortingng[] split = docId.split(":"); final Ssortingng type = split[0]; System.out.println("getPath() docId: " + docId + ", split: " + split.length + ", type: " + type); // This is for checking Main Memory if ("primary".equalsIgnoreCase(type)) { if (split.length > 1) { return Environment.getExternalStorageDirectory() + "/" + split[1] + "/"; } else { return Environment.getExternalStorageDirectory() + "/"; } // This is for checking SD Card } else { return "storage" + "/" + docId.replace(":", "/"); } } } return null; } 

Vous pouvez vérifier que chaque partie d’Uri utilise println. Les valeurs renvoyées pour ma carte SD et la mémoire principale de l’appareil sont répertoriées ci-dessous. Vous pouvez accéder et supprimer si le fichier est en mémoire, mais je n’ai pas pu supprimer le fichier de la carte SD en utilisant cette méthode, seulement lire ou ouvrir l’image en utilisant ce chemin absolu. Si vous avez trouvé une solution à supprimer en utilisant cette méthode, partagez-la. CARTE SD

 getPath() uri: content://com.android.externalstorage.documents/tree/612E-B7BF%3A/document/612E-B7BF%3A getPath() uri authority: com.android.externalstorage.documents getPath() uri path: /tree/612E-B7BF:/document/612E-B7BF: getPath() docId: 612E-B7BF:, split: 1, type: 612E-B7BF 

MÉMOIRE PRINCIPALE

 getPath() uri: content://com.android.externalstorage.documents/tree/primary%3A/document/primary%3A getPath() uri authority: com.android.externalstorage.documents getPath() uri path: /tree/primary:/document/primary: getPath() docId: primary:, split: 1, type: primary 

Si vous souhaitez obtenir Uri avec le file:/// après avoir utilisé le chemin

 DocumentFile documentFile = DocumentFile.fromFile(new File(path)); documentFile.getUri() // will return a Uri with file Uri 

Eh bien, je suis un peu en retard pour répondre, mais mon code est testé

schéma de contrôle de uri:

  byte[] videoBytes; if (uri.getScheme().equals("content")){ InputStream iStream = context.getContentResolver().openInputStream(uri); videoBytes = getBytes(iStream); }else{ File file = new File(uri.getPath()); FileInputStream fileInputStream = new FileInputStream(file); videoBytes = getBytes(fileInputStream); } 

Dans la réponse ci-dessus, j’ai converti l’uri vidéo en tableau d’octets, mais ce n’est pas lié à la question, j’ai simplement copié mon code complet pour montrer l’utilisation de FileInputStream et InputStream car les deux fonctionnent dans mon code.

J’ai utilisé le contexte variable qui est getActivity () dans mon fragment et dans Activity il s’agit simplement de ActivityName.this

context=getActivity(); // en fragment

context=ActivityName.this; // en activité

Vous devez utiliser getContentResolver().openInputStream(uri) pour obtenir un InputStream partir d’un URI. Parce que c’est très facile et facile à comprendre. Pour plus openInputStream(android.net.Uri)