从 Uri 读取文件给出 java.io.FileNotFoundException:打开失败:ENOENT

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

使用 ACTION_GET_CONTENT 意图选取图像时,我得到一个无法从中打开文件的 URI。如果我尝试打开文件,如下所示:

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

它给出了以下异常:

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好像确实是个不正确的路径,但是怎么才能得到正确的路径呢?

我使用这个逻辑打开图像选择器:

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

然后像这样在 onActivityResult 中检索 Uri:

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

我需要获取文件进行解码以使其更小。

If I try to open the file, like this:

这不适用于大多数现代 Android 设备。您很可能收到 content: Uri。这在 Android 的较新版本上是相当正常的。 Android 的未来版本可能会阻止 file: Uri 值。

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

不一定要有与给定 Uri 关联的文件。 Uri 可能指向:

  • 外部存储上的本地文件
  • 另一个应用程序的内部存储上的本地文件
  • 可移动存储上的本地文件
  • 本地加密文件,需要即时解密
  • 数据库中 BLOB 列中保存的字节流
  • 一段内容需要对方先下载
  • ...等等

使用 ContentResolveropenInputStream()Uri 指向的内容上获得 InputStream。然后,将其传递给您的解码逻辑,例如 BitmapFactory 及其 decodeStream() 方法。