从持久性 Uri 加载图像时出错

Error loading image from presistent Uri

程序流程是用户从图库中选择一张图片,显示在图片视图中。这很好用。同时将Uri写入数据库。

稍后,当程序再次运行或再次显示activity时,从数据库中检索Uri并再次显示图像。图像的第二次显示是导致异常的原因:

requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS

我给manifest添加了权限,还是出现异常

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />

同一过程尝试显示两个图像,当它来自选择器时它可以工作,但当它来自数据库中的持久性 Uri 时失败。

选择器意图

    try {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(
                Intent.createChooser(intent, "Select Picture"),
                PICK_IMAGE);
    } catch (Exception e) {
        Toast.makeText(getApplicationContext(),
                "Error",
                Toast.LENGTH_LONG).show();
        Log.e(e.getClass().getName(), e.getMessage(), e);
    }

根据我使用的选择器意图的结果

Uri selectedImageUri = data.getData();

用我用的数据库读取。 localImage 是一个字符串。

Uri.parse(localImage)

我阅读了这个错误报告 https://issues.apache.org/jira/browse/CB-5398,但我不确定如何使用它来解决这种情况。下面来自另一个线程的代码似乎试图通过权限和照片选择器解决类似的问题,但在我的例子中我没有再次选择,我只需要显示来自 Uri 的图像。

我猜这是重置权限的问题。我不太确定。我有清单中的权限。也许我需要不同的代码来显示不是从选择器获得的 Uri 中的图像?也许我需要针对不同的 API?我的 build.gradle 说 targetSdkVersion 21,minSdkVersion 15。这些是默认值。我在 Android Studio 1.0.2.

我被难住了。感谢任何帮助。

public static final String KITKAT_VALUE = 1002;

    Intent intent;

    if (Build.VERSION.SDK_INT < 19){
                            intent = new Intent();
                            intent.setAction(Intent.ACTION_GET_CONTENT);
                            intent.setType("*/*");
                            startActivityForResult(intent, KITKAT_VALUE);
                        } else {
                            intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                            intent.addCategory(Intent.CATEGORY_OPENABLE);
                            intent.setType("*/*");
                            startActivityForResult(intent, KITKAT_VALUE);
                    }

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (requestCode == KITKAT_VALUE ) {
         if (resultCode == Activity.RESULT_OK) {
             // do something here
         }
      }
    }

At the same time, the Uri is written to a database.

这在 API 级别 19 之前是行不通的,并且只有在您使用存储访问框架 (ACTION_OPEN_DOCUMENT) 并获得提供的持久权限时才行。鉴于您现有的代码,您获得的临时权限 Uri 将最迟在您的进程终止时到期。

I added the permission to the manifest and the exception still occurs.

您无法持有 MANAGE_DOCUMENTS,除非您使用签署固件的签名密钥进行签名。