我目前正在创建自己的图库应用。我使用一个自定义对象,它包含一个库的所有必需信息,包括来自本地android库的图像的URL。
public class GalleryDTO {
private Long id;
private String name;
private List<Uri> photos = new ArrayList<>();
我将此图库对象存储在sql lite db中。
我有一个活动来查看此图库对象。在这个活动中,我加载了我想要显示的图库 - 这很有用。
但是当试图加载图片时:
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" />
在查看之前刚刚保存的图库不会发生此异常。但是当我关闭我的应用程序(例如使用任务管理器)并重新打开它时,这些新画廊也会抛出异常。
我错了什么?
答案 0 :(得分:1)
我将此图库对象存储在sql lite db中。
在许多情况下,这不会起作用。
将export function func1() {
...
}
export function func2() {
...
}
// or if you need to rename them:
export default {
funcA: func1,
funcB: func2
};
视为类似于Web应用中用户身份验证的URL。该网址可能很有用现在,但只要用户的会话超时,网址就会变得无用。同样的事情也适用于此:默认情况下,Uri
可能只有在您的流程终止之前才有用。
然后抛出以下异常:
这是因为您对Uri
的权利已过期,可能是因为您的流程已终止。
另外,请注意Uri
可能因其他原因而无效,例如:
用户删除了内容
用户移动了内容,Uri
现在不同了
为您提供Uri
的应用只保留内容的本地缓存,最终将此内容从该缓存中删除,要求再次下载
我错了什么?
您假设Uri
永远存在。
你可以try takePersistableUriPermission()
。这将需要Uri
19(Android 4.4+),可能无法处理许多minSdkVersion
值(因为提供商不提供持久权限),并且它不会解决所有问题(例如,用户删除了内容)。
或者,您可以在获得Uri
后立即制作自己的内容本地副本,而不是依赖其他应用的Uri
值。