android obtenir un vrai chemin par Uri.getPath ()

J’essaie d’obtenir une image de la galerie.

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

Après mon retour de cette activité, j’ai une donnée qui contient Uri. Ça ressemble à:

 content://media/external/images/1 

Comment puis-je convertir ce chemin vers le chemin réel (comme ” /sdcard/image.png “)?

Merci

    Est-ce vraiment nécessaire pour vous d’avoir un chemin physique?
    Par exemple, ImageView.setImageURI() et ContentResolver.openInputStream() vous permettent d’accéder au contenu d’un fichier sans connaître son vrai chemin.

    C’est ce que je fais:

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

    et:

     private Ssortingng getRealPathFromURI(Uri contentURI) { Ssortingng 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.getSsortingng(idx); cursor.close(); } return result; } 

    REMARQUE: la méthode managedQuery() est obsolète, donc je ne l’utilise pas.

    Dernière modification: amélioration. Nous devrions fermer le curseur !!

    @ René Juuse – ci-dessus dans les commentaires … Merci pour ce lien!

    . Le code pour obtenir le vrai chemin est un peu différent d’un SDK à l’autre; par conséquent, nous avons trois méthodes qui traitent différents SDK.

    getRealPathFromURI_API19 (): renvoie le chemin réel de l’API 19 (ou supérieur mais non testé) getRealPathFromURI_API11to18 (): renvoie le chemin réel de l’API 11 vers l’API 18

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

    police: http://hmkcode.com/android-display-selected-image-and-its-real-path/


    MISE À JOUR 2016 Mars

    Pour résoudre tous les problèmes avec le chemin des images, j’essaie de créer une galerie personnalisée en tant que facebook et autres applications. C’est parce que vous ne pouvez utiliser que des fichiers locaux (fichiers réels, pas virtuels ou temporaires), je résous tous les problèmes avec cette bibliothèque.

    https://github.com/nohana/Laevatein (cette bibliothèque doit prendre des photos depuis un appareil photo ou choisir une galerie, si vous choisissez de la galerie, il a un tiroir avec des albums et affiche juste des fichiers locaux)

    Note Ceci est une amélioration de la réponse de @ user3516549 et je l’ai vérifiée sur Moto G3 avec Android 6.0.1
    J’ai ce problème, donc j’ai essayé de répondre à @ user3516549 mais dans certains cas, cela ne fonctionnait pas correctement. J’ai trouvé que dans Android 6.0 (ou supérieur) lorsque nous commençons l’intention de choisir l’image de la galerie alors un écran s’ouvrira qui montre les images récentes lorsque l’utilisateur sélectionne l’image de cette liste, nous allons obtenir uri comme

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

    alors que si l’utilisateur choisit la galerie du tiroir coulissant au lieu de récente, alors nous aurons uri comme

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

    Je l’ai donc getRealPathFromURI_API19() dans getRealPathFromURI_API19()

     public static Ssortingng getRealPathFromURI_API19(Context context, Uri uri) { Ssortingng filePath = ""; if (uri.getHost().contains("com.android.providers.media")) { // Image pick from recent Ssortingng wholeID = DocumentsContract.getDocumentId(uri); // Split at colon, use second item in the array Ssortingng id = wholeID.split(":")[1]; Ssortingng[] column = {MediaStore.Images.Media.DATA}; // where id is equal to Ssortingng sel = MediaStore.Images.Media._ID + "=?"; Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new Ssortingng[]{id}, null); int columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { filePath = cursor.getSsortingng(columnIndex); } cursor.close(); return filePath; } else { // image pick from gallery return getRealPathFromURI_BelowAPI11(context,uri) } } 

    EDIT: si vous essayez d’obtenir le chemin de l’image du fichier dans la carte SD externe dans la version supérieure, alors vérifiez ma question

    Il n’y a pas de véritable chemin .

    Un Uri avec un schéma de content est une poignée opaque à certains contenus. Si cet Uri représente un contenu pouvant être ContentResolver , vous pouvez utiliser ContentResolver et openInputStream() pour obtenir un InputStream sur ce contenu. De même, un Uri avec un schéma http ou https ne représente pas un fichier local et vous devez utiliser une API client HTTP pour y accéder.

    Seul un Uri avec un schéma de file identifie un fichier (sauf cas où le fichier a été déplacé ou supprimé après la création de Uri ).

    Ce que les gens stupides font est d’essayer de dériver un chemin de système de fichiers en essayant de décoder le contenu de l’ Uri , éventuellement couplé avec des sorts de $EVIL_DEITY pour invoquer $EVIL_DEITY . Au mieux, cela ne sera pas fiable, pour trois raisons:

    1. Les règles de décodage des valeurs Uri peuvent changer avec le temps, comme avec les versions Android, car la structure de l’ Uri représente un détail d’implémentation et non une interface.

    2. Même si vous obtenez un chemin de système de fichiers, vous ne pouvez pas avoir les droits d’access au fichier

    3. Toutes les valeurs Uri ne peuvent pas être décodées via des algorithmes fixes, car de nombreuses applications ont leurs propres fournisseurs, et celles-ci peuvent pointer sur des éléments allant des colonnes BLOB aux données qui doivent être diffusées depuis Internet.

    Si vous disposez d’une API limitée nécessitant un fichier, utilisez InputStream partir de openInputStream() pour en faire une copie. Que ce soit une copie transitoire (par exemple, utilisée pour une opération de téléchargement de fichier, puis supprimée) ou une copie durable (par exemple, pour une fonctionnalité “d’importation” de votre application), c’est à vous de décider.

    EDIT: Utilisez cette solution ici: https://stackoverflow.com/a/20559175/2033223 Fonctionne parfaitement!

    Tout d’abord, merci pour votre solution @luizfelipetx

    J’ai un peu changé votre solution. Cela fonctionne pour moi:

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

    Note: Nous avons donc des documents et des images, selon que l’image provient de «recents», «gallery» ou autre. Donc, j’extrais d’abord l’identifiant de l’image avant de le chercher.

    Hii voici mon code complet pour prendre des photos depuis une caméra ou un galeery

    // Ma déclaration de variable

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

    //Sur clic

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

    // corps de la méthode

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

    // Et le rest des choses

     @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 resortingeve!", 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 Ssortingng getRealPathFromUri(Uri tempUri) { Cursor cursor = null; try { Ssortingng[] 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.getSsortingng(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); Ssortingng path = MediaStore.Images.Media.insertImage(youractivity.getContentResolver(), bitmap, "Title", null); return Uri.parse(path); } 

    Cela m’a aidé à obtenir uri de la galerie et à convertir en fichier pour le téléchargement multipart

     File file = FileUtils.getFile(this, fileUri); 

    https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java

    Essaye ça

    Cependant, si vous rencontrez le problème pour obtenir le vrai chemin, vous pouvez essayer mes réponses. Les réponses ci-dessus ne m’ont pas aidé.

    Explication : – Cette méthode récupère l’URI, puis vérifie le niveau de l’API de votre appareil Android, après quoi, selon le niveau de l’API, il générera le chemin réel. Le code pour générer un chemin réel est différent selon les niveaux de l’API.

    Voici ma réponse