Reading File from Uri gives java.io.FileNotFoundException: open failed: ENOENT
Asked Answered
O

1

1

When picking an image using an ACTION_GET_CONTENT intent, I get a URI that I can't open the file from. If I try to open the file, like this:

InputStream in = new FileInputStream(new File(uri.getPath()));

It gives the following exception:

03-11 15:14:36.132  20557-20557/my.package W/System.err﹕ java.io.FileNotFoundException: /document/image:9537: open failed: ENOENT (No such file or directory)
03-11 15:14:36.138  20557-20557/my.package W/System.err﹕ at libcore.io.IoBridge.open(IoBridge.java:456)
03-11 15:14:36.138  20557-20557/my.package W/System.err﹕ at java.io.FileInputStream.<init>(FileInputStream.java:76)

/document/image:9537 seems to indeed be an incorrect path, but how do I get the correct path?

I use this logic to open the image picker:

Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("return-data", false);
startActivityForResult(Intent.createChooser(photoPickerIntent, "Complete action using"), PICK_FROM_FILE);

And retrieve the Uri in the onActivityResult like this:

public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    ....
    Uri uri = data.getData();

I need to get the file to do decoding to make it smaller.

Ogpu answered 11/3, 2016 at 14:40 Comment(0)
N
4

If I try to open the file, like this:

That will not work for most modern Android devices. Most likely, you received a content: Uri. This is fairly normal on newer versions of Android. Future versions of Android might block file: Uri values.

I need to get the file to do decoding to make it smaller.

There does not have to be a file associated with a given Uri. That Uri might point to:

  • A local file on external storage
  • A local file on internal storage for the other app
  • A local file on removable storage
  • A local file that is encrypted and needs to be decrypted on the fly
  • A stream of bytes held in a BLOB column in a database
  • A piece of content that needs to be downloaded by the other app first
  • ...and so on

Use a ContentResolver and openInputStream() to get an InputStream on the content pointed to by the Uri. Then, pass that to your decoding logic, such as BitmapFactory and its decodeStream() method.

Naumann answered 11/3, 2016 at 14:44 Comment(2)
That is awesome. I just had a misconception of how these uri's work.Ogpu
@wvdz: Yeah, it's best to treat them as opaque handles, akin to a URL to a Web site.Naumann

© 2022 - 2024 — McMap. All rights reserved.