Cómo obtener la ruta completa del archivo desde URI

Me gustaría obtener la ruta completa del archivo, desde un URI. El URI no es una imagen, pero es un archivo de música, pero si lo hago como la solución MediaStore, no funcionará si el usuario de la aplicación selecciona, por ejemplo, Astro como navegador, en lugar de reproductor de música. ¿Cómo puedo solucionar esto?

Utilizar:

String path = yourAndroidURI.uri.getPath() // "/mnt/sdcard/FileName.mp3" File file = new File(new URI(path)); 

o

 String path = yourAndroidURI.uri.toString() // "file:///mnt/sdcard/FileName.mp3" File file = new File(new URI(path)); 

El método PathUtil solo funcionará debajo de oreo y si está en oreo de lo que es probable que se cuelgue porque en oreo no obtendremos el id sino toda la ruta en data.getData () así que todo lo que necesitamos hacer es crear un archivo desde uri y obtener su camino de getPath () y dividir it.below es el código de trabajo: –

 Uri uri = data.getData(); File file = new File(uri.getPath());//create path from uri final String[] split = file.getPath().split(":");//split the path. filePath = split[1];//assign it to a string(your choice). 

El código anterior funcionará en oreo y si está debajo de oreo, PathUtil funcionará. ¡Gracias!

 String filePath=PathUtil.getPath(context,yourURI); 

PathUtil.java

 import android.annotation.SuppressLint; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; import java.net.URISyntaxException; /** * Created by Aki on 1/7/2017. */ public class PathUtil { /* * Gets the file path of the given Uri. */ @SuppressLint("NewApi") public static String getPath(Context context, Uri uri) throws URISyntaxException { final boolean needToCheckUri = Build.VERSION.SDK_INT >= 19; String selection = null; String[] selectionArgs = null; // Uri is different in versions after KITKAT (Android 4.4), we need to // deal with different Uris. if (needToCheckUri && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) { if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); return Environment.getExternalStorageDirectory() + "/" + split[1]; } else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); uri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); } else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("image".equals(type)) { uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } selection = "_id=?"; selectionArgs = new String[]{ split[1] }; } } if ("content".equalsIgnoreCase(uri.getScheme())) { String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = null; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); if (cursor.moveToFirst()) { return cursor.getString(column_index); } } catch (Exception e) { } } else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } } 

Prueba esto.

 public String getRealPathFromURI(Uri contentUri) { String[] proj = { MediaStore.Audio.Media.DATA }; Cursor cursor = managedQuery(contentUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } 

Puede usar get File path desde diferentes versiones de SDk

Use RealPathUtils para ello

 public class RealPathUtils { @SuppressLint("NewApi") public static String getRealPathFromURI_API19(Context context, Uri uri){ String filePath = ""; String wholeID = DocumentsContract.getDocumentId(uri); // Split at colon, use second item in the array String id = wholeID.split(":")[1]; String[] column = { MediaStore.Images.Media.DATA }; // where id is equal to String sel = MediaStore.Images.Media._ID + "=?"; Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null); int columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { filePath = cursor.getString(columnIndex); } cursor.close(); return filePath; } @SuppressLint("NewApi") public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) { String[] proj = { MediaStore.Images.Media.DATA }; String result = null; CursorLoader cursorLoader = new CursorLoader( context, contentUri, proj, null, null, null); Cursor cursor = cursorLoader.loadInBackground(); if(cursor != null){ int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); result = cursor.getString(column_index); } return result; } public static String getRealPathFromURI_BelowAPI11(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); } } 

** Ahora obtenga la ruta del archivo de URI **

  String path = null; if (Build.VERSION.SDK_INT < 11) path = RealPathUtils.getRealPathFromURI_BelowAPI11(MainActivity.this, uri); // SDK >= 11 && SDK < 19 else if (Build.VERSION.SDK_INT < 19) path = RealPathUtils.getRealPathFromURI_API11to18(MainActivity.this, uri); // SDK > 19 (Android 4.4) else path = RealPathUtils.getRealPathFromURI_API19(MainActivity.this, uri); Log.d(TAG, "File Path: " + path); // Get the file instance File file = new File(path); 

Sé que esto ya ha sido respondido. Pero hay algunos problemas que encontré en los comentarios. Encontré una gran solución confiable bifurcada desde aquí

para usarlo File file=FileUtils.getFile(uri);

 public class FileUtils { //replace this with your authority public static final String AUTHORITY = "com.ianhanniballake.localstorage.documents"; private FileUtils() { } //private constructor to enforce Singleton pattern /** * TAG for log messages. */ static final String TAG = "FileUtils"; private static final boolean DEBUG = false; // Set to true to enable logging /** * @return Whether the URI is a local one. */ public static boolean isLocal(String url) { if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) { return true; } return false; } public static boolean isLocalStorageDocument(Uri uri) { return AUTHORITY.equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. * @author paulburke */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. * @author paulburke */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. * @author paulburke */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is Google Photos. */ public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param context The context. * @param uri The Uri to query. * @param selection (Optional) Filter used in the query. * @param selectionArgs (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. * @author paulburke */ public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { if (DEBUG) DatabaseUtils.dumpCursor(cursor); final int column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * Get a file path from a Uri. This will get the the path for Storage Access * Framework Documents, as well as the _data field for the MediaStore and * other file-based ContentProviders.
*
* Callers should check whether the path is local before assuming it * represents a local file. * * @param context The context. * @param uri The Uri to query. * @author paulburke * @see #isLocal(String) * @see #getFile(Context, Uri) */ 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)) { // LocalStorageProvider if (isLocalStorageDocument(uri)) { // The path is the id return DocumentsContract.getDocumentId(uri); } // ExternalStorageProvider else if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } // TODO handle non-primary volumes } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[]{ split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * Convert Uri into File, if possible. * * @return file A local file that the Uri was pointing to, or null if the * Uri is unsupported or pointed to a remote resource. * @author paulburke * @see #getPath(Context, Uri) */ public static File getFile(Context context, Uri uri) { if (uri != null) { String path = getPath(context, uri); if (path != null && isLocal(path)) { return new File(path); } } return null; } }
 package com.utils; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.support.annotation.RequiresApi; import android.text.TextUtils; import android.util.Log; import org.apache.commons.io.IOUtils; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; public class FileUtils { /* Get uri related content real local file path. */ public static String getPath(Context ctx, Uri uri) { String ret; try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // Android OS above sdk version 19. ret = getUriRealPathAboveKitkat(ctx, uri); } else { // Android OS below sdk version 19 ret = getRealPath(ctx.getContentResolver(), uri, null); } } catch (Exception e) { e.printStackTrace(); Log.d("DREG", "FilePath Catch: " + e); ret = getFilePathFromURI(ctx, uri); } return ret; } private static String getFilePathFromURI(Context context, Uri contentUri) { //copy file and send new file path String fileName = getFileName(contentUri); if (!TextUtils.isEmpty(fileName)) { String TEMP_DIR_PATH = Environment.getExternalStorageDirectory().getPath(); File copyFile = new File(TEMP_DIR_PATH + File.separator + fileName); Log.d("DREG", "FilePath copyFile: " + copyFile); copy(context, contentUri, copyFile); return copyFile.getAbsolutePath(); } return null; } public static String getFileName(Uri uri) { if (uri == null) return null; String fileName = null; String path = uri.getPath(); int cut = path.lastIndexOf('/'); if (cut != -1) { fileName = path.substring(cut + 1); } return fileName; } public static void copy(Context context, Uri srcUri, File dstFile) { try { InputStream inputStream = context.getContentResolver().openInputStream(srcUri); if (inputStream == null) return; OutputStream outputStream = new FileOutputStream(dstFile); IOUtils.copy(inputStream, outputStream); // org.apache.commons.io inputStream.close(); outputStream.close(); } catch (Exception e) { // IOException e.printStackTrace(); } } @RequiresApi(api = Build.VERSION_CODES.KITKAT) private static String getUriRealPathAboveKitkat(Context ctx, Uri uri) { String ret = ""; if (ctx != null && uri != null) { if (isContentUri(uri)) { if (isGooglePhotoDoc(uri.getAuthority())) { ret = uri.getLastPathSegment(); } else { ret = getRealPath(ctx.getContentResolver(), uri, null); } } else if (isFileUri(uri)) { ret = uri.getPath(); } else if (isDocumentUri(ctx, uri)) { // Get uri related document id. String documentId = DocumentsContract.getDocumentId(uri); // Get uri authority. String uriAuthority = uri.getAuthority(); if (isMediaDoc(uriAuthority)) { String idArr[] = documentId.split(":"); if (idArr.length == 2) { // First item is document type. String docType = idArr[0]; // Second item is document real id. String realDocId = idArr[1]; // Get content uri by document type. Uri mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; if ("image".equals(docType)) { mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(docType)) { mediaContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(docType)) { mediaContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } // Get where clause with real document id. String whereClause = MediaStore.Images.Media._ID + " = " + realDocId; ret = getRealPath(ctx.getContentResolver(), mediaContentUri, whereClause); } } else if (isDownloadDoc(uriAuthority)) { // Build download uri. Uri downloadUri = Uri.parse("content://downloads/public_downloads"); // Append download document id at uri end. Uri downloadUriAppendId = ContentUris.withAppendedId(downloadUri, Long.valueOf(documentId)); ret = getRealPath(ctx.getContentResolver(), downloadUriAppendId, null); } else if (isExternalStoreDoc(uriAuthority)) { String idArr[] = documentId.split(":"); if (idArr.length == 2) { String type = idArr[0]; String realDocId = idArr[1]; if ("primary".equalsIgnoreCase(type)) { ret = Environment.getExternalStorageDirectory() + "/" + realDocId; } } } } } return ret; } /* Check whether this uri represent a document or not. */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) private static boolean isDocumentUri(Context ctx, Uri uri) { boolean ret = false; if (ctx != null && uri != null) { ret = DocumentsContract.isDocumentUri(ctx, uri); } return ret; } /* Check whether this uri is a content uri or not. * content uri like content://media/external/images/media/1302716 * */ private static boolean isContentUri(Uri uri) { boolean ret = false; if (uri != null) { String uriSchema = uri.getScheme(); if ("content".equalsIgnoreCase(uriSchema)) { ret = true; } } return ret; } /* Check whether this uri is a file uri or not. * file uri like file:///storage/41B7-12F1/DCIM/Camera/IMG_20180211_095139.jpg * */ private static boolean isFileUri(Uri uri) { boolean ret = false; if (uri != null) { String uriSchema = uri.getScheme(); if ("file".equalsIgnoreCase(uriSchema)) { ret = true; } } return ret; } /* Check whether this document is provided by ExternalStorageProvider. */ private static boolean isExternalStoreDoc(String uriAuthority) { boolean ret = false; if ("com.android.externalstorage.documents".equals(uriAuthority)) { ret = true; } return ret; } /* Check whether this document is provided by DownloadsProvider. */ private static boolean isDownloadDoc(String uriAuthority) { boolean ret = false; if ("com.android.providers.downloads.documents".equals(uriAuthority)) { ret = true; } return ret; } /* Check whether this document is provided by MediaProvider. */ private static boolean isMediaDoc(String uriAuthority) { boolean ret = false; if ("com.android.providers.media.documents".equals(uriAuthority)) { ret = true; } return ret; } /* Check whether this document is provided by google photos. */ private static boolean isGooglePhotoDoc(String uriAuthority) { boolean ret = false; if ("com.google.android.apps.photos.content".equals(uriAuthority)) { ret = true; } return ret; } /* Return uri represented document file real local path.*/ @SuppressLint("Recycle") private static String getRealPath(ContentResolver contentResolver, Uri uri, String whereClause) { String ret = ""; // Query the uri with condition. Cursor cursor = contentResolver.query(uri, null, whereClause, null, null); if (cursor != null) { boolean moveToFirst = cursor.moveToFirst(); if (moveToFirst) { // Get columns name by uri type. String columnName = MediaStore.Images.Media.DATA; if (uri == MediaStore.Images.Media.EXTERNAL_CONTENT_URI) { columnName = MediaStore.Images.Media.DATA; } else if (uri == MediaStore.Audio.Media.EXTERNAL_CONTENT_URI) { columnName = MediaStore.Audio.Media.DATA; } else if (uri == MediaStore.Video.Media.EXTERNAL_CONTENT_URI) { columnName = MediaStore.Video.Media.DATA; } // Get column index. int columnIndex = cursor.getColumnIndex(columnName); // Get column value which is the uri related file local path. ret = cursor.getString(columnIndex); } } return ret; } } 

Ahora llame a FileUtils.getPath(context, uri); de tu clase principal.

Me costó mucho tratar de resolver esto con Xamarin. De las sugerencias anteriores, se me ocurrió esta solución.

 private string getRealPathFromURI(Android.Net.Uri contentUri) { string filename = ""; string thepath = ""; Android.Net.Uri filePathUri; ICursor cursor = this.ContentResolver.Query(contentUri, null, null, null, null); if (cursor.MoveToFirst()) { int column_index = cursor.GetColumnIndex(MediaStore.Images.Media.InterfaceConsts.Data);//Instead of "MediaStore.Images.Media.DATA" can be used "_data" filePathUri = Android.Net.Uri.Parse(cursor.GetString(column_index)); filename = filePathUri.LastPathSegment; thepath = filePathUri.Path; } return thepath; } 
 String uri_path = "file:///mnt/sdcard/FileName.mp3"; File f = new removeUriFromPath(uri_path)); public static String removeUriFromPath(String uri) { return uri.substring(7, uri.length()); }