with visor studio para libreria imagenes glide galeria from ejemplo codigo app android image-gallery

android - visor - load image from gallery with glide



android get real path por Uri.getPath() (9)

Estoy tratando de obtener una imagen de la galería.

Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select picture"), resultCode );

Después de regresar de esta actividad, tengo una información que contiene Uri. Parece que:

content://media/external/images/1

¿Cómo puedo convertir esta ruta en real (como '' /sdcard/image.png '')?

Gracias


Prueba esto

Aún así, si obtiene el problema para obtener la ruta real, puede probar mis respuestas. Las respuestas anteriores no me ayudaron.

Explicación : - Este método obtiene el URI y luego verifica el nivel de la API de su dispositivo Android luego de que, de acuerdo con el nivel de API, generará la ruta real. El código para generar una ruta real es diferente según los niveles de API.

Aquí está mi respuesta


¿Es realmente necesario que obtengas un camino físico?
Por ejemplo, ImageView.setImageURI() y ContentResolver.openInputStream() permiten acceder al contenido de un archivo sin conocer su ruta real.


@Rene Juuse - arriba en comentarios ... ¡Gracias por este enlace!

. el código para obtener la ruta real es un poco diferente de un SDK a otro, por lo que a continuación tenemos tres métodos que tratan con diferentes SDK.

getRealPathFromURI_API19 (): devuelve una ruta real para API 19 (o superior pero no probado) getRealPathFromURI_API11to18 (): devuelve la ruta real para API 11 a API 18 getRealPathFromURI_below11 (): devuelve una ruta real para API por debajo de 11

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); 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); }

fuente: link

ACTUALIZACIÓN 2016 de marzo

Para solucionar todos los problemas con la ruta de las imágenes, intento crear una galería personalizada como Facebook y otras aplicaciones. Esto se debe a que puede usar solo archivos locales (archivos reales, no virtuales o temporales), resuelvo todos los problemas con esta biblioteca.

https://github.com/nohana/Laevatein (esta biblioteca es para tomar fotos de la cámara o elegir entre galery, si eliges de la galería tiene un cajón con álbumes y solo muestra los archivos locales)


Esto es lo que hago:

Uri selectedImageURI = data.getData(); imageFile = new File(getRealPathFromURI(selectedImageURI));

y:

private String getRealPathFromURI(Uri contentURI) { String result; Cursor cursor = getContentResolver().query(contentURI, null, null, null, null); if (cursor == null) { // Source is Dropbox or other similar local file path result = contentURI.getPath(); } else { cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); result = cursor.getString(idx); cursor.close(); } return result; }

NOTA: el método managedQuery() está en desuso, por lo que no lo estoy usando.

Última edición: Mejora. ¡Deberíamos cerrar el cursor!



Hii aquí está mi código completo para tomar la imagen de la cámara o galeery

// Mi declaración de variables

protected static final int CAMERA_REQUEST = 0; protected static final int GALLERY_REQUEST = 1; Bitmap bitmap; Uri uri; Intent picIntent = null;

//Al hacer clic

if (v.getId()==R.id.image_id){ startDilog(); }

// cuerpo del método

private void startDilog() { AlertDialog.Builder myAlertDilog = new AlertDialog.Builder(yourActivity.this); myAlertDilog.setTitle("Upload picture option.."); myAlertDilog.setMessage("Where to upload picture????"); myAlertDilog.setPositiveButton("Gallery", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { picIntent = new Intent(Intent.ACTION_GET_CONTENT,null); picIntent.setType("image/*"); picIntent.putExtra("return_data",true); startActivityForResult(picIntent,GALLERY_REQUEST); } }); myAlertDilog.setNegativeButton("Camera", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(picIntent,CAMERA_REQUEST); } }); myAlertDilog.show(); }

// Y el resto de las cosas

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode==GALLERY_REQUEST){ if (resultCode==RESULT_OK){ if (data!=null) { uri = data.getData(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; try { BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); options.inSampleSize = calculateInSampleSize(options, 100, 100); options.inJustDecodeBounds = false; Bitmap image = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); imageofpic.setImageBitmap(image); } catch (FileNotFoundException e) { e.printStackTrace(); } }else { Toast.makeText(getApplicationContext(), "Cancelled", Toast.LENGTH_SHORT).show(); } }else if (resultCode == RESULT_CANCELED) { Toast.makeText(getApplicationContext(), "Cancelled", Toast.LENGTH_SHORT).show(); } }else if (requestCode == CAMERA_REQUEST) { if (resultCode == RESULT_OK) { if (data.hasExtra("data")) { bitmap = (Bitmap) data.getExtras().get("data"); uri = getImageUri(YourActivity.this,bitmap); File finalFile = new File(getRealPathFromUri(uri)); imageofpic.setImageBitmap(bitmap); } else if (data.getExtras() == null) { Toast.makeText(getApplicationContext(), "No extras to retrieve!", Toast.LENGTH_SHORT) .show(); BitmapDrawable thumbnail = new BitmapDrawable( getResources(), data.getData().getPath()); pet_pic.setImageDrawable(thumbnail); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(getApplicationContext(), "Cancelled", Toast.LENGTH_SHORT).show(); } } } private String getRealPathFromUri(Uri tempUri) { Cursor cursor = null; try { String[] proj = { MediaStore.Images.Media.DATA }; cursor = this.getContentResolver().query(tempUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } finally { if (cursor != null) { cursor.close(); } } } public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; } private Uri getImageUri(YourActivity youractivity, Bitmap bitmap) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); String path = MediaStore.Images.Media.insertImage(youractivity.getContentResolver(), bitmap, "Title", null); return Uri.parse(path); }


EDITAR: Utilice esta solución aquí: https://.com/a/20559175/2033223 Funciona perfecto!

Primero de, gracias por su solución @luizfelipetx

Cambié tu solución un poco. Esto funciona para mí:

public static String getRealPathFromDocumentUri(Context context, Uri uri){ String filePath = ""; Pattern p = Pattern.compile("(//d+)$"); Matcher m = p.matcher(uri.toString()); if (!m.find()) { Log.e(ImageConverter.class.getSimpleName(), "ID for requested image not found: " + uri.toString()); return filePath; } String imgId = m.group(); String[] column = { MediaStore.Images.Media.DATA }; String sel = MediaStore.Images.Media._ID + "=?"; Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ imgId }, null); int columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { filePath = cursor.getString(columnIndex); } cursor.close(); return filePath; }

Nota: Así que tenemos documentos e imágenes, dependiendo, si la imagen proviene de ''recientes'', ''galería'' o cualquier otra cosa. Así que extraigo la identificación de la imagen primero antes de buscarla.


No hay un camino real

Un Uri con un esquema de content es un identificador opaco para algunos contenidos. Si ese Uri representa contenido que se puede ContentResolver , puede usar ContentResolver y openInputStream() para obtener un InputStream en ese contenido. De forma similar, un Uri con un esquema http o https no representa un archivo local, y usted necesitaría usar una API de cliente HTTP para acceder a él.

Solo un Uri con un esquema de file identifica un archivo (salvo casos donde el archivo fue movido o eliminado después de que se creó el Uri ).

Lo que las personas estúpidas hacen es tratar de derivar una ruta del sistema de archivos intentando decodificar el contenido del Uri , posiblemente junto con conjuros de lanzamiento para invocar $EVIL_DEITY . En el mejor de los casos, esto no será confiable, por tres razones:

  1. Las reglas para decodificar los valores de Uri pueden cambiar con el tiempo, como con las versiones de Android, ya que la estructura de Uri representa un detalle de implementación, no una interfaz

  2. Incluso si obtiene una ruta del sistema de archivos, es posible que no tenga derechos para acceder al archivo

  3. No todos los valores de Uri pueden decodificarse mediante algoritmos fijos, ya que muchas aplicaciones tienen sus propios proveedores, y pueden indicar desde columnas de activos hasta columnas BLOB y datos que deben transmitirse desde Internet.

Si tiene alguna API limitada que requiere un archivo, use el InputStream de openInputStream() para hacer una copia de ese contenido. Ya sea que se trate de una copia transitoria (por ejemplo, utilizada para una operación de carga de archivos, luego eliminada) o una copia duradera (por ejemplo, para una función de "importación" de su aplicación), depende de usted.


Nota: esta es una mejora en la respuesta de @ user3516549 y la he comprobado en Moto G3 con Android 6.0.1
Tengo este problema, así que he intentado con la respuesta de @ user3516549, pero en algunos casos no funcionaba correctamente. He encontrado que en Android 6.0 (o superior) cuando comenzamos la intención de selección de imágenes de galería, se abre una pantalla que muestra imágenes recientes cuando el usuario selecciona la imagen de esta lista, obtendremos uri como

content://com.android.providers.media.documents/document/image%3A52530

mientras que si el usuario selecciona la galería del cajón deslizante en lugar de reciente, obtendremos uri como

content://media/external/images/media/52530

Así que lo he manejado en getRealPathFromURI_API19()

public static String getRealPathFromURI_API19(Context context, Uri uri) { String filePath = ""; if (uri.getHost().contains("com.android.providers.media")) { // Image pick from recent 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; } else { // image pick from gallery return getRealPathFromURI_BelowAPI11(context,uri) } }

EDITAR: si está tratando de obtener la ruta de imagen del archivo en una tarjeta SD externa en una versión superior, entonces verifique mi pregunta