Search code examples
androidandroid-intentandroid-imageviewandroid-imageandroid-file

Wrong image file path obtained from Android file manager


In my application I would like to open an image and "load" it to the app using File Manager. I've already doneit using Intent.ACTION_GET_CONTENT and onActivityResult() method. Everything works fine, except from the path which I get. It is in a strange format and I can't show the image in ImageView

public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            mFileManagerString = selectedImageUri.getPath();
            showPreviewDialog(mFileManagerString);
        }
}

Here mFileManagerString = /document/image:19552

When I call a method to show the image in the ImageView:

public void setPreviewIV(String pPath) {
        Bitmap bmImg = BitmapFactory.decodeFile(pPath);
        receiptPreviewIV.setImageBitmap(bmImg);
}

I get the following error:

E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /document/image:19552: open failed: ENOENT (No such file or directory)

How to get the proper path to the image, so that I can show it in the ImageView?


Solution

  • How to get the proper path to the image

    You already have it. It is the Uri that is passed into onActivityResult() via the Intent parameter. Pulling just getPath() out of that Uri is pointless. That's akin to thinking that /questions/33827687/wrong-image-file-path-obtained-from-android-file-manager is a path on your hard drive, just because your Web browser shows a URL that contains that path.

    In addition, your current code is loading and decoding the Bitmap on the main application thread. Do not do this, because it freezes the UI while that work is being done.

    I recommend that you use any one of the many image-loading libraries available for Android. All the decent ones (e.g., Picasso, Universal Image Loader) not only take a Uri as input but also will load the image on a background thread for you, applying it to your ImageView on the main application thread only when the bitmap is ready.

    If, for whatever reason, you feel that you have to do this yourself, use ContentResolver and its openInputStream() to get an InputStream for the data represented by the Uri. Then, pass that to decodeStream() on BitmapFactory. Do all of that in a background thread (e.g., doInBackground() of an AsyncTask), and then apply the Bitmap to the ImageView on the main application thread (e.g., onPostExecute() of an AsyncTask).