8
  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?

lemon
  • 9,155
  • 7
  • 39
  • 47

3 Answers3

20

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());
ariefbayu
  • 21,849
  • 12
  • 71
  • 92
  • 2
    Activity.managedQuery is depreciated. Use: CursorLoader loader=new CursorLoader(activity, contentUri, proj, null, null, null); instead – Patrick Jackson Feb 17 '13 at 21:08
  • 2
    @Patrick It's very much not obvious to me HOW you would use a CursorLoader in this case. Or how to use it at all, frankly. The documentation leaves a lot to be desired. Since I can run this whole task in a thread, I'm going to just ignore your advice and use the deprecated managedQuery(). Because it's much more obvious how to make that work, especially since I need a synchronous result. – SomeCallMeTim Apr 11 '13 at 00:40
  • @SomeCallMeTim to use the CursorLoader just call the loadInBackground() method. It will return a Cursor. http://developer.android.com/reference/android/content/CursorLoader.html#loadInBackground%28%29 – Felipe Vasconcelos Aug 02 '13 at 06:50
  • filePathFromActivity always null , how can I fix this? – onder Jul 19 '15 at 13:58
1

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!

0

Pick any file using System File Picker:

val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
startActivityForResult(intent, 1)

onActivityResult:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
        val file = data?.data?.let {
            getFileFromUri(requireContext().contentResolver, uri, requireContext().cacheDir)
        }
    }
}

Get File:

private fun getFileFromUri(contentResolver: ContentResolver, uri: Uri, directory: File): File {
    val file =
        File.createTempFile("suffix", "prefix", directory)
    file.outputStream().use {
        contentResolver.openInputStream(uri)?.copyTo(it)
    }

    return file
}