programacion - Android: ¿Cómo obtener un URI de archivo de un URI de contenido?
manual de android en pdf (6)
En mi aplicación, el usuario debe seleccionar un archivo de audio que luego la aplicación maneja. El problema es que para que la aplicación haga lo que quiero que haga con los archivos de audio, necesito que el URI esté en formato de archivo. Cuando uso el reproductor de música nativo de Android para buscar el archivo de audio en la aplicación, el URI es un URI de contenido, que se ve así:
content://media/external/audio/media/710
Sin embargo, usando la popular aplicación de administración de archivos Astro, obtengo lo siguiente:
file:///sdcard/media/audio/ringtones/GetupGetOut.mp3
Este último es mucho más accesible para mí, pero, por supuesto, quiero que la aplicación tenga funcionalidad con el archivo de audio que el usuario elija independientemente del programa que utilice para explorar su colección. Entonces mi pregunta es, ¿hay alguna manera de convertir el content://
URI de estilo en un file://
URI? De lo contrario, ¿qué me recomendarías para resolver este problema? Aquí está el código que llama al selector, para referencia:
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);
Hago lo siguiente con el URI de contenido:
m_ringerPath = m_ringtoneUri.getPath();
File file = new File(m_ringerPath);
Luego haga algo de FileInputStream con dicho archivo.
Bueno, estoy un poco tarde para responder, pero mi código está probado
verifique el esquema 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);
}
En la respuesta anterior, convertí el video uri a array de bytes, pero eso no está relacionado con la pregunta, simplemente copié mi código completo para mostrar el uso de FileInputStream
y InputStream
ya que ambos funcionan igual en mi código.
Usé el contexto variable que es getActivity () en mi Fragmento y en Activity simplemente es ActivityName.this
context=getActivity();
// en Fragmento
context=ActivityName.this;
// en actividad
Deberías usar getContentResolver().openInputStream(uri)
para obtener un InputStream
desde un URI. Porque es muy fácil y fácil de entender. Para obtener más openInputStream(android.net.Uri)
Intentar manejar el URI con contenido: // esquema llamando a ContentResolver.query()
no es una buena solución. En HTC Desire ejecutando 4.2.2 puede obtener NULL como resultado de la consulta.
¿Por qué no usar ContentResolver en su lugar? https://.com/a/29141800/3205334
Puede usar Content Resolver para obtener una ruta de file://
desde el 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 tiene un contenido Uri con content://com.externalstorage...
puede usar este método para obtener la ruta absoluta de una carpeta o archivo en Android 19 o superior .
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;
}
Puede verificar que cada parte de Uri esté usando println. Los valores devueltos para mi tarjeta SD y la memoria principal del dispositivo se enumeran a continuación. Puede acceder y eliminar si el archivo está en la memoria, pero no pude eliminar el archivo de la tarjeta SD con este método, solo leí o abrí la imagen usando esta ruta absoluta. Si ha encontrado una solución para eliminar utilizando este método, por favor comparta. TARJETA 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
MEMORIA PRINCIPAL
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 desea obtener Uri con el file:///
después de obtener el uso de la ruta
DocumentFile documentFile = DocumentFile.fromFile(new File(path));
documentFile.getUri() // will return a Uri with file Uri
Simplemente use getContentResolver().openInputStream(uri)
para obtener un InputStream
desde un URI.