Android: obtenir un URI de fichier à partir d'un URI de contenu?
Dans mon application l'utilisateur de sélectionner un fichier audio à 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 parcourir 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 le populaire gestionnaire de fichiers application Astro, j'obtiens ce qui suit:
file:///sdcard/media/audio/ringtones/GetupGetOut.mp3
ce dernier est beaucoup plus accessible pour moi de travailler avec, mais bien sûr je veux que l'application ait la fonctionnalité avec le fichier audio que l'utilisateur choisit indépendamment du programme qu'ils utilisent pour parcourir leur collection. Alors ma question Est, y a-t-il un moyen de transformer L'URI de style content://
en un URI file://
? Sinon, que recommanderiez-vous pour moi à résoudre ce problème? Voici le code qui appelle le chooser, 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 le suivant avec le contenu URI:
m_ringerPath = m_ringtoneUri.getPath();
File file = new File(m_ringerPath);
puis faire quelques trucs FileInputStream avec ce fichier.
6 réponses
il suffit d'utiliser getContentResolver().openInputStream(uri)
pour obtenir un InputStream
d'une URI.
vous pouvez utiliser le résolveur de contenu pour obtenir un chemin file://
à partir du 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);
essayer de gérer L'URI Avec contenu:// schéma en appelant ContentResolver.query()
n'est pas une bonne solution. Sur HTC Desire en cours d'exécution 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 Uri de contenu avec 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 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 chaque partie D'Uri utilise println. Les valeurs retournées pour ma carte SD et ma mémoire principale sont listées ci-dessous. Vous pouvez accéder et supprimer si le fichier est sur la mémoire mais je n'ai pas été en mesure de supprimer le fichier de la carte SD en utilisant cette méthode, seulement lire ou opene d image utilisant ce chemin absolu. Si vous avez trouver une solution pour supprimer en utilisant cette méthode, s'il vous plaît partager. 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 file:///
après l'utilisation du chemin d'accès
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é
vérifier le schéma d'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,
Je viens de copier mon code complet pour montrer l'utilisation de FileInputStream
et InputStream
que les deux travaillent même dans mon code.
j'ai utilisé le contexte variable qui est getActivity () dans mon Fragment et en activité il est tout simplement ActivityName.ce
context=getActivity();
/ / en Fragment
context=ActivityName.this;
/ / en activité
vous devez utiliser
getContentResolver().openInputStream(uri)
pour obtenir un InputStream
d'une URI. Parce qu'il est très simple et facile à comprendre.
Pour plus openInputStream(android.net.Uri)