URI from Intent.ACTION_GET_CONTENT into File

  1. Launch photo picker using Intent.ACTION_GET_CONTENT
  2. Retrieve URI of selected item
  3. Retrieve PATH of URI so that I can POST it to my webserver

    Code to launch browse

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    startActivityForResult(intent, BROWSE_IMAGE_REQUEST_CODE);
    

    Code to retrieve selected image

    if (RESULT_OK == resultCode &&
                 BROWSE_IMAGE_REQUEST_CODE == requestCode) {
    Uri uri = data.getData();
    

    Code to send to the webserver

    File file = new File(uri.getPath());
    new FileSystemResourceFile(file);
    

I am currently able to retrieve the PATH from the URI no prob /external/images/media/24 but for some weird reason file is always null, help please?


I've done this method to convert Uri from Intent.ACTION_GET_CONTENT to real path:

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

Which in turn converted into File:

Uri filePathFromActivity = (Uri) extras.get(Intent.EXTRA_STREAM);
filePathFromActivity = Uri.parse(FileUtil.getRealPathFromUri( (Activity) IntentActivity.this, filePathFromActivity));
File imageFile = new File(filePathFromActivity.getPath());

I know its been a long time since the answer, but I faced the same wall and this is the solution I ended up with. The main benefit of this code is that avoids having parametrized (and hard-coded) all possible providers types and locations across all different android versions.

    val act = getActivity() as Activity
    object: AsyncTask<Uri, Void, File?>() {
        override fun doInBackground(uris: Array<Uri>): File? {
            if(act.isFinishing()) return null
            try {
                val dir = act.getCacheDir()
                val file = File.createTempFile("PREFIX", "SUFFIX", dir)
                val inputStream = act.getContentResolver().openInputStream(uris[0])
                val fos = FileOutputStream(file)
                BitmapFactory.decodeStream(inputStream)
                        .compress(Bitmap.CompressFormat.JPEG, 90, fos)
                return file
            } catch(e: Exception) { e.printStackTrace() }
            return null
        }
        override fun onPostExecute(result: File?) {
            result?.let { doSomethingWithFile(it) }
        }
    }.execute(uri)

I put it wrapped inside of an AsyncTask for the purpose of leaving unblocked ui thread during bitmap compress. Please be aware that using Bitmap.CompressFormat.JPEG means lossing alpha channel.

Hope it helps!