Convertir archivo: Uri en Archivo en Android

¿Cuál es la forma más fácil de convertir un file: android.net.Uri a un File en Android?

Probé lo siguiente pero no funciona:

  final File file = new File(Environment.getExternalStorageDirectory(), "read.me"); Uri uri = Uri.fromFile(file); File auxFile = new File(uri.toString()); assertEquals(file.getAbsolutePath(), auxFile.getAbsolutePath()); 

Lo que quieres es …

 new File(uri.getPath()); 

… y no…

 new File(uri.toString()); 

NOTA: uri.toString() devuelve un String en el formato: "file:///mnt/sdcard/myPicture.jpg" , mientras que uri.getPath() devuelve un String en el formato: "/mnt/sdcard/myPicture.jpg" .

Después de buscar durante mucho tiempo, esto es lo que funcionó para mí:

 File file = new File(getPath(uri)); public String getPath(Uri uri) { String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); if (cursor == null) return null; int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String s=cursor.getString(column_index); cursor.close(); return s; } 

EDITAR: Perdón, debería haber probado mejor antes. Esto debería funcionar:

 new File(new URI(androidURI.toString())); 

URI es java.net.URI.

Nada de esto funciona para mí. Encontré que esta es la solución de trabajo. Pero mi caso es específico para las imágenes .

 String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = getActivity().getContentResolver().query(uri, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String filePath = cursor.getString(columnIndex); cursor.close(); 

utilizar

 InputStream inputStream = getContentResolver().openInputStream(uri); 

directamente y copie el archivo. Ver también:

https://developer.android.com/guide/topics/providers/document-provider.html

Con Kotlin es aún más fácil:

 val file = File(uri.path) 

O si está utilizando extensiones de Kotlin para Android :

 val file = uri.toFile() 

Hice esto de la siguiente manera:

 try { readImageInformation(new File(contentUri.getPath())); } catch (IOException e) { readImageInformation(new File(getRealPathFromURI(context, contentUri))); } public static String getRealPathFromURI(Context context, Uri contentUri) { String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } 

Entonces, básicamente, primero trato de usar un archivo, es decir, una foto tomada por la cámara y guardada en una tarjeta SD. Esto no funciona para la imagen devuelta por: Intent photoPickerIntent = new Intent (Intent.ACTION_PICK); En ese caso, hay una necesidad de convertir getRealPathFromURI() en ruta real mediante la función getRealPathFromURI() . Entonces, la conclusión es que depende del tipo de URI que quieras convertir a File.

@CommonsWare explicó todas las cosas bastante bien. Y realmente deberíamos usar la solución que él propuso.

Por cierto, solo la información en la que podemos confiar cuando se ContentResolver es el nombre y el tamaño de un archivo como se menciona aquí: Recuperación de información de archivo | Desarrolladores de Android

Como puede ver, hay una interfaz OpenableColumns que contiene solo dos campos: DISPLAY_NAME y SIZE.

En mi caso, necesitaba recuperar información EXIF ​​sobre una imagen JPEG y rotarla si era necesario antes de enviarla a un servidor. Para hacer eso, copié el contenido de un archivo en un archivo temporal usando ContentResolver y openInputStream()

Puede obtener el archivo del archivo Uri utilizando el siguiente método. Tiene DocumentFile para el parámetro, pero puedes cambiarlo fácilmente. La forma más fácil de probar este método para crear archivos uri usando DocumentFile.fromFile(Environment.getExternalStorageDirectory()); que tiene un file:///storage/emulated/0 Uri file:///storage/emulated/0

 /** * Gets File from DocumentFile if Uri is file:/// * * @param documentFile Document file that contains Uri to create File from * @return File with absolute path to the physical file on device memory */ public static File getFileFromDocumentFile(DocumentFile documentFile) { try { File file = new File(URI.create(documentFile.getUri().toString())); return file; } catch (Exception e) { return null; } } 

En lugar de crear archivos desde Uri, use DocumentFile.fromTreeUri(Context, Uri) o DocumentFile.fromSingleri(Context, Uri) para crear o eliminar archivos y para las secuencias use getContentResolver().openOutputStream(documentFile.getUri()) y getContentResolver().openInputStream(documentFile.getUri()) para escribir archivos o leer archivos.

cadena pública getRealPathFromURI (Uri uri) {

  String result; Cursor cursor = getContentResolver().query(uri, null, null, null, null); if (cursor == null) { result = uri.getPath(); cursor.close(); return result; } cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); result = cursor.getString(idx); cursor.close(); return result; } 

Luego usando para obtener el archivo de URI:

  File finalFile = newFile(getRealPathFromURI(uri)); 

– LA HOPE PUEDE AYUDARTE —-

Android + Kotlin

  1. Agregue dependencia para las extensiones de Kotlin para Android:

    implementation 'androidx.core:core-ktx:{latestVersion}'

  2. Obtener archivo de uri:

    uri.toFile()

Android + Java

Solo pasar a la cima;)

Cree una clase simple de FileUtil java y utilícela para crear, copiar y cambiar el nombre del archivo

Utilizo uri.toString() y uri.getPath() pero no funcionó para mí. Finalmente encontré esta solución.

 import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.provider.OpenableColumns; import android.util.Log; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class FileUtil { private static final int EOF = -1; private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; private FileUtil() { } public static File from(Context context, Uri uri) throws IOException { InputStream inputStream = context.getContentResolver().openInputStream(uri); String fileName = getFileName(context, uri); String[] splitName = splitFileName(fileName); File tempFile = File.createTempFile(splitName[0], splitName[1]); tempFile = rename(tempFile, fileName); tempFile.deleteOnExit(); FileOutputStream out = null; try { out = new FileOutputStream(tempFile); } catch (FileNotFoundException e) { e.printStackTrace(); } if (inputStream != null) { copy(inputStream, out); inputStream.close(); } if (out != null) { out.close(); } return tempFile; } private static String[] splitFileName(String fileName) { String name = fileName; String extension = ""; int i = fileName.lastIndexOf("."); if (i != -1) { name = fileName.substring(0, i); extension = fileName.substring(i); } return new String[]{name, extension}; } private static String getFileName(Context context, Uri uri) { String result = null; if (uri.getScheme().equals("content")) { Cursor cursor = context.getContentResolver().query(uri, null, null, null, null); try { if (cursor != null && cursor.moveToFirst()) { result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); } } } if (result == null) { result = uri.getPath(); int cut = result.lastIndexOf(File.separator); if (cut != -1) { result = result.substring(cut + 1); } } return result; } private static File rename(File file, String newName) { File newFile = new File(file.getParent(), newName); if (!newFile.equals(file)) { if (newFile.exists() && newFile.delete()) { Log.d("FileUtil", "Delete old " + newName + " file"); } if (file.renameTo(newFile)) { Log.d("FileUtil", "Rename file to " + newName); } } return newFile; } private static long copy(InputStream input, OutputStream output) throws IOException { long count = 0; int n; byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; while (EOF != (n = input.read(buffer))) { output.write(buffer, 0, n); count += n; } return count; } } 

Clase User FileUtil en tu código

 try { File file = FileUtil.from(MainActivity.this,fileUri); Log.d("file", "File...:::: uti - "+file .getPath()+" file -" + file + " : " + file .exists()); } catch (IOException e) { e.printStackTrace(); } 

Con el siguiente código, puedo obtener el archivo pdf compartido de la aplicación de Adobe como una secuencia y guardarlo en la ruta de la aplicación Android

 Android.Net.Uri fileuri = (Android.Net.Uri)Intent.GetParcelableExtra(Intent.ExtraStream); fileuri i am getting as {content://com.adobe.reader.fileprovider/root_external/ data/data/com.adobe.reader/files/Downloads/sample.pdf} string filePath = fileuri.Path; filePath I am gettings as root_external/data/data/com.adobe.reader/files/Download/sample.pdf using (var stream = ContentResolver.OpenInputStream(fileuri)) { byte[] fileByteArray = ToByteArray(stream); //only once you can read bytes from stream second time onwards it has zero bytes string fileDestinationPath =" " convertByteArrayToPDF(fileByteArray, fileDestinationPath);//here pdf copied to your destination path } public static byte[] ToByteArray(Stream stream) { var bytes = new List(); int b; while ((b = stream.ReadByte()) != -1) bytes.Add((byte)b); return bytes.ToArray(); } public static string convertByteArrayToPDF(byte[] pdfByteArray, string filePath) { try { Java.IO.File data = new Java.IO.File(filePath); Java.IO.OutputStream outPut = new Java.IO.FileOutputStream(data); outPut.Write(pdfByteArray); return data.AbsolutePath; } catch (System.Exception ex) { return string.Empty; } } 

Para la gente que está aquí buscando una solución para las imágenes en particular, aquí está.

 private Bitmap getBitmapFromUri(Uri contentUri) { String path = null; String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(contentUri, projection, null, null, null); if (cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); path = cursor.getString(columnIndex); } cursor.close(); Bitmap bitmap = BitmapFactory.decodeFile(path); return bitmap; } 

File imageToUpload = new File (nuevo URI (androidURI.toString ())); funciona si este es un archivo que ha creado en el almacenamiento externo.

Por ejemplo file: /// storage / emulated / 0 / (algún directorio y nombre de archivo)