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 qu'elle fasse 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 gestion de fichiers Astro, je reçois ce qui suit:
file:///sdcard/media/audio/ringtones/GetupGetOut.mp3
Ce dernier est beaucoup plus accessible pour moi, mais je souhaite bien sûr que l'application dispose des fonctionnalités du fichier audio choisi par l'utilisateur, quel que soit le programme utilisé pour parcourir sa collection. Ma question est donc 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, pour 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 trucs FileInputStream avec ce fichier.
Utilisez simplement getContentResolver().openInputStream(uri)
pour obtenir un InputStream
à partir d'un URI.
Vous pouvez utiliser le résolveur de contenu pour obtenir un file://
chemin depuis le content://
URI:
String filePath = null;
Uri _uri = data.getData();
Log.d("","URI = "+ _uri);
if (_uri != null && "content".equals(_uri.getScheme())) {
Cursor cursor = this.getContentResolver().query(_uri, new String[] { Android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
cursor.moveToFirst();
filePath = cursor.getString(0);
cursor.close();
} else {
filePath = _uri.getPath();
}
Log.d("","Chosen path = "+ filePath);
Si vous avez un contenu Uri avec content://com.externalstorage...
vous pouvez utiliser cette méthode pour obtenir le chemin absolu d’un dossier ou d’un fichier on Android 19 ou plus).
public static String 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.toString());
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 String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String 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 la 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 que je n’ai pas pu supprimer le fichier de la carte SD en utilisant cette méthode, uniquement en lecture ou en image à l’aide de ce chemin absolu. Si vous avez trouvé une solution à supprimer à l'aide de 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 avoir Uri avec file:///
après avoir utilisé le chemin
DocumentFile documentFile = DocumentFile.fromFile(new File(path));
documentFile.getUri() // will return a Uri with file Uri
Essayer de gérer l'URI avec le schéma content: // en appelant ContentResolver.query()
n'est pas une bonne solution. Sur HTC Desire sous 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
Eh bien, je suis un peu en retard pour répondre, mais mon code est testé
schéma de vérification 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 le tableau uri vidéo en tableau d'octets, mais cela n'a rien à voir avec la question. Je viens de copier mon code complet pour montrer l'utilisation de FileInputStream
et InputStream
, car les deux fonctionnent de la même manière mon code.
J'ai utilisé le contexte de variable qui est getActivity () dans mon fragment et dans Activity, il s'agit simplement de NomActivité.
context=getActivity();
// dans le fragment
context=ActivityName.this;
// en activité