1

I'm allowing the user to pick an image from their photo gallery:

    Intent pickIntent = new Intent();
    pickIntent.setType("image/*");
    pickIntent.setAction(Intent.ACTION_GET_CONTENT);

    Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
    Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
    chooserIntent.putExtra
            (
                    Intent.EXTRA_INITIAL_INTENTS,
                    new Intent[] { takePhotoIntent }
            );

    startActivityForResult(chooserIntent, SELECT_PICTURE);

And in onActivityResult I want to create a new File from the selected image. Here is what I am doing:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
        if (data == null) {
            return;
        }

        Uri selectedImageUri = data.getData();
        File mediaFile = new File(selectedImageUri.getPath());

        if(!mediaFile.exists())
            Log.d("File", "File doesn't exist");
    }
}

My check mediaFile.exists() is returning false. What am I doing wrong here?

Update

I tried doing this as well:

String fullPath = getRealPathFromURI(selectedImageUri);

with this method from enter link description here question:

public String getRealPathFromURI(Uri contentUri) {
    Cursor cursor = null;
    try {
        String[] proj = { MediaStore.Images.Media.DATA };
        cursor = getContentResolver().query(contentUri, proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
    return null;
}

However, this method returns null.

Community
  • 1
  • 1
Harry
  • 772
  • 10
  • 32
  • try `uri = data.getData(); Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);` and then set this `bitmap` to ImageView. – ELITE Feb 25 '16 at 02:11
  • I'm not trying to get a Bitmap from the URI, I just posted that to clarify that I have the correct URI. I feel a `File` from the URI – Harry Feb 25 '16 at 02:12
  • duplicate question of http://stackoverflow.com/questions/26965016/get-file-path-from-uri – ELITE Feb 25 '16 at 02:13
  • ...That is for getting the absolute path from a URI. Not a file. – Harry Feb 25 '16 at 02:15
  • then you can convert it to file using `File file = new File(fullPath);`.. – ELITE Feb 25 '16 at 02:16
  • @ELITE I've tried using this method but the method used in that question to get the full path returns null for my URI. I've updated my question – Harry Feb 25 '16 at 02:21
  • use solution code from that question. don't use question code. – ELITE Feb 25 '16 at 02:23

2 Answers2

2

Add this class to your project.

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

and get image path from uri using relative method of android api.

EDIT :: Check SDK Version of your phone

And get path using

int version = Build.VERSION.SDK_INT;
String fullPath;
if(version >= 19) {
    //call api 19 code here
    fullPath = getRealPathFromURI_API19(this, uri);
} else if(version <= 18 && version >= 11) {
    // call api 11-18 code here
    fullPath = getRealPathFromURI_API11to18(this, uri);
} else {
    // call below api 11 code here
    fullPath = getRealPathFromURI_BelowAPI11(this, uri);
}
File mediaFile = new File(fullPath);

Reference from this

Community
  • 1
  • 1
ELITE
  • 5,815
  • 3
  • 19
  • 29
  • Even with this, I am getting null. My test device is using API 17 and it is using `getRealPathFromURI_API11to18` as it should. fullPath still is null – Harry Feb 25 '16 at 02:59
  • make sure the permissions in manifest file `` – ELITE Feb 25 '16 at 03:03
  • Actually, this works but only for screenshots in my Photo Gallery on my device. If I choose an image from another "album", it returns null – Harry Feb 25 '16 at 03:12
  • To add to that, it looks like it works for photos stored on the phone and not albums that are pulled from elsewhere (i.e. there is a "Hangouts" album in my Gallery on my device). Which makes sense because those photos aren't on the external storage device. – Harry Feb 25 '16 at 03:16
  • i also observed such thing. when i upload photo from gallary it shows filepath correctly but if i select photo using `photo` or `recent` app it doesn't show the path. – ELITE Feb 25 '16 at 03:18
  • Looks like the URI it is failing for is something like com.google.android.gallery3d.provider/picasa/item – Harry Feb 25 '16 at 03:32
1

It requires no special permissions, and works with the Storage Access Framework, as well as the unofficial ContentProvider pattern (file path in _data field).

/**
 * 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.
 *
 * @param context The context.
 * @param uri The Uri to query.
 * @author rahul
 */
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)) {
        // ExternalStorageProvider
        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;
}

/**
 * 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.
 */
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()) {
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    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());
}

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

Hope it will help you !

Rahul
  • 510
  • 3
  • 8
  • thanks a lot..this should be the solution. It worked for me and solved lots of problems. I was trying another logic for video browse..thanks a lot... – ELITE Feb 25 '16 at 10:22
  • @ELITE, Great ! Welcome my friend ! – Rahul Feb 25 '16 at 10:30