Cómo obtener la ruta del archivo de la imagen de URI en Android Lollipop?
Quiero crear un selector de imágenes para Android Lollipop. Utilizo Intent.ACTION_GET_CONTENT
para elegir mi imagen pero no puedo conseguir la trayectoria de la imagen seleccionada de URI, que el selector del diálogo volvió.
He intentado códigos de estos hilos:
- Cuál es la diferencia entre Java.Net.Uri y Android.Net.Uri
- Obtenga la colección de nombres de parámetros de la url de Java / Android
- CursorLoader, obtiene URI para la base de datos local
- Image uri no muestra imágenes en ImageView en algún dispositivo Android
- Android - ¿Cómo obtener Uri de archivo RAW?
Recuperar la ruta absoluta cuando seleccione la imagen de la galería kitkat android
Picture Selection from Camera & Gallery
pero todos vuelven nulos. ¿Alguien puede ayudarme?
- Actividad de captura de cámara Android devuelve null Uri
- Filtro de intenciones para iniciar mi actividad cuando se hace clic en el URI personalizado
- ¿Existe un esquema URI universal para la aplicación de Facebook, que funciona en todos los dispositivos móviles?
- Obtener la lista de contactos y el estado de skype en android
- Obtener el camino real de URI, KitKat Android nuevo marco de acceso de almacenamiento
- Android: howto parse URL String con espacios al objeto URI?
- ¿Qué hay de malo en esta URL URI? IllegalArgumentException, Caracteres no válidos
- Obtener imagen Uri + miniatura de la foto tomada con la cámara en Android
Tratar
import android.annotation.SuppressLint; import android.content.Context; import android.content.CursorLoader; import android.database.Cursor; import android.net.Uri; import android.provider.DocumentsContract; import android.provider.MediaStore; public class RealPathUtil { @SuppressLint("NewApi") public static String getRealPathFromURI_API19(Context context, Uri uri) { Log.variable("uri", uri.getPath()); String filePath = ""; if (DocumentsContract.isDocumentUri(context, uri)) { String wholeID = DocumentsContract.getDocumentId(uri); Log.variable("wholeID", wholeID); // Split at colon, use second item in the array String[] splits = wholeID.split(":"); if (splits.length == 2) { String id = splits[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(); } } else { filePath = uri.getPath(); } 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); }
y use:
private String uriToFilename(Uri uri) { String path = null; if (Build.VERSION.SDK_INT < 11) { path = RealPathUtil.getRealPathFromURI_BelowAPI11(mContext, uri); } else if (Build.VERSION.SDK_INT < 19) { path = RealPathUtil.getRealPathFromURI_API11to18(mContext, uri); } else { path = RealPathUtil.getRealPathFromURI_API19(mContext, uri); } return path; }
funciona para mí en casos de necesidad ( no funciona para la aplicación de descarga)
Pruebe esta pequeña función:
public static String getRealPathFromUri(Uri uri) { String result = ""; String documentID; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { String[] pathParts = uri.getPath().split("/"); documentID = pathParts[pathParts.length - 1]; } else { String pathSegments[] = uri.getLastPathSegment().split(":"); documentID = pathSegments[pathSegments.length - 1]; } String mediaPath = MediaStore.Images.Media.DATA; Cursor imageCursor = getContentResolver().query(uri, new String[]{mediaPath}, MediaStore.Images.Media._ID + "=" + documentID, null, null); if (imageCursor.moveToFirst()) { result = imageCursor.getString(imageCursor.getColumnIndex(mediaPath)); } return result; }
Este trabajo para mí.
He creado una clase Util RealPathUtil
(hay algunas pequeñas diferencias con la clase en la respuesta @Artem):
import android.annotation.SuppressLint; import android.content.Context; import android.content.CursorLoader; import android.database.Cursor; import android.net.Uri; import android.provider.DocumentsContract; import android.provider.MediaStore; public class RealPathUtil { @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); assert cursor != 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){ Cursor cursor = null; try { String[] proj = { MediaStore.Images.Media.DATA }; cursor = context.getContentResolver().query(contentUri, proj, null, null, null); assert cursor != null; int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } finally { if (cursor != null) { cursor.close(); } } } }
Luego, en el código de mi aplicación, utilicé:
private String getPathFromUri(Uri uri) { if (Build.VERSION.SDK_INT < 11) return RealPathUtil.getRealPathFromURI_BelowAPI11(getContext(), uri); else if (Build.VERSION.SDK_INT < 19) return RealPathUtil.getRealPathFromURI_API11to18(getContext(), uri); else return RealPathUtil.getRealPathFromURI_API19(getContext(), uri); }
¡Asegúrese de que está dando permiso en el manifiesto de Android!
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />