如何在没有权限拒绝的情况下通过存储在数据库中的 URI 从库中加载图像

How can I load Images from the Gallery by URIs stored in the db without permission denial

我目前正在创建自己的图库应用程序。我使用一个自定义对象,它包含画廊的所有必需信息,包括来自本地 android 画廊的图像的 url。

public class GalleryDTO {
   private Long id;
   private String name;
   private List<Uri> photos = new ArrayList<>();

我将这个图库对象存储在 sql 精简版数据库中。

我有一个 activity 可以查看此图库对象。在此 activity 中,我加载了我想要显示的画廊 - 这有效。

但是当尝试加载图像时:

   GalleryDTO galleryDTO=vrGalleryApp.getGalleryService().loadGalleryById(displayedGalleryId);

    if(galleryDTO.getPhotos()!=null&&!galleryDTO.getPhotos().isEmpty()){
        for(int i=0;i<galleryDTO.getPhotos().size();i++){
            Uri imageUrl = galleryDTO.getPhotos().get(i);
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),  imageUrl);

然后抛出以下异常:

java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.contentprovider.MediaContentProvider from ProcessRecord{3585e48d 8727:at....vrgallery.vrgallery/u0a137} (pid=8727, uid=10137) that is not exported from uid 10071

甚至我在清单中声明了所需的权利:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

对于在查看之前刚刚保存的画廊,不会发生此异常。但是当我关闭我的应用程序(例如使用任务管理器)并重新打开它时,这些新画廊也会抛出异常。

我哪里错了?

I store this gallery object in a sql lite db.

这在很多情况下是行不通的。

Uri 视为类似于网络应用程序中经过用户验证的 URL。 URL 现在可能有用 ,但是一旦用户的会话超时,URL 就变得无用了。同样的道理在这里也适用:默认情况下,Uri 可能只有在您的进程终止之前才有用。

Then the following exception is thrown :

那是因为您对该 Uri 的权利已过期,可能是因为您的进程已终止。

此外,请记住 Uri 可能会因其他原因而失效,例如:

  • 用户删除了内容

  • 用户移动了内容,Uri现在会有所不同

  • 给你 Uri 的应用程序只保留本地内容缓存,它最终会将该内容从缓存中逐出,要求重新下载

What do I am wrong?

你假设 Uri 永远存在。

你可以try takePersistableUriPermission()。这将需要 minSdkVersion 19 (Android 4.4+),可能不适用于许多 Uri 值(因为提供者不提供持久权限),并且它不会解决所有问题问题(例如,用户删除了内容)。

或者,您可以在获得 Uri 后立即制作自己的内容本地副本,而不是依赖其他应用程序的 Uri 值。