使用 Glide 库从 OnActivityResult 检索的 Uri 时访问被拒绝
Accessed denied when using Uri retrieved from OnActivityResult using Glide library
我已经使用标记 uses-permission 和 uses-permission-sdk-23 在 Android 清单下声明了 READ_EXTERNAL_STORAGE。我还向用户请求 READ_EXTERNAL_STORAGE 权限。我也使用了标志 FLAG_GRANT_READ_URI_PERMISSION.
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
photoPickerIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (photoPickerIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(photoPickerIntent, REQUEST_IMAGE_GALLERY);
}
这就是我请求用户在 onActivityResult 中检索照片的方式。我还使用 glide 库从用户那里检索照片。
requestMgr.load(new File(uri.getPath())).into(imageView);
这是我检查从 onActivityResult 返回的 intent 是否为 null 后写的内容。
if(intent != null){
Uri uri = intent.getData();
requestMgr.load(new File(uri.getPath())).into(imageView);
} else {
displayImageStorageErrorMessage();
loadProfileImage();
}
loadProfileImage() 只是一个备用方法,以防万一我尝试加载图像时发生任何事情。 Glide.with() 是在检查意图之前写的,因为我也在用户想要自拍时使用它。
但是,imageView 不显示用户选择的图像。在我将请求监听器附加到 Glide 之后的结果如下:
java.io.FileNotFoundException: open failed: EACCES (Permission denied)
at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1498)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1420)
at com.bumptech.glide.load.data.AssetFileDescriptorLocalUriFetcher.loadResource(AssetFileDescriptorLocalUriFetcher.java:20)
at com.bumptech.glide.load.data.AssetFileDescriptorLocalUriFetcher.loadResource(AssetFileDescriptorLocalUriFetcher.java:11)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailed(SourceGenerator.java:83)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:167)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:154)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:49)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailed(SourceGenerator.java:83)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:167)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:154)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:49)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory.run(GlideExecutor.java:393)
我是否缺少一些我尚未完成的权限?
问题 #1:ACTION_PICK
不使用 MIME 类型
问题 #2:ACTION_PICK
确实使用了 Uri
来指示您从中挑选的集合,而您没有提供
问题 #3:ACTION_PICK
很可能通过 onActivityResult()
return 一个 content
Uri
,而不是带有文件系统路径的东西
问题 #4:setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
毫无意义,因为您没有向另一个应用程序提供 content
Uri
,更不用说您已经授予读取权限的应用程序了
要解决这些问题,请将您的第一个代码片段替换为:
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
photoPickerIntent.setType("image/*");
if (photoPickerIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(photoPickerIntent, REQUEST_IMAGE_GALLERY);
}
将您的第二个代码片段替换为:
if(intent != null){
Uri uri = intent.getData();
requestMgr.load(uri).into(imageView);
} else {
displayImageStorageErrorMessage();
loadProfileImage();
}
我已经使用标记 uses-permission 和 uses-permission-sdk-23 在 Android 清单下声明了 READ_EXTERNAL_STORAGE。我还向用户请求 READ_EXTERNAL_STORAGE 权限。我也使用了标志 FLAG_GRANT_READ_URI_PERMISSION.
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
photoPickerIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (photoPickerIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(photoPickerIntent, REQUEST_IMAGE_GALLERY);
}
这就是我请求用户在 onActivityResult 中检索照片的方式。我还使用 glide 库从用户那里检索照片。
requestMgr.load(new File(uri.getPath())).into(imageView);
这是我检查从 onActivityResult 返回的 intent 是否为 null 后写的内容。
if(intent != null){
Uri uri = intent.getData();
requestMgr.load(new File(uri.getPath())).into(imageView);
} else {
displayImageStorageErrorMessage();
loadProfileImage();
}
loadProfileImage() 只是一个备用方法,以防万一我尝试加载图像时发生任何事情。 Glide.with() 是在检查意图之前写的,因为我也在用户想要自拍时使用它。
但是,imageView 不显示用户选择的图像。在我将请求监听器附加到 Glide 之后的结果如下:
java.io.FileNotFoundException: open failed: EACCES (Permission denied)
at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1498)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1420)
at com.bumptech.glide.load.data.AssetFileDescriptorLocalUriFetcher.loadResource(AssetFileDescriptorLocalUriFetcher.java:20)
at com.bumptech.glide.load.data.AssetFileDescriptorLocalUriFetcher.loadResource(AssetFileDescriptorLocalUriFetcher.java:11)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailed(SourceGenerator.java:83)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:167)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:154)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:49)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailed(SourceGenerator.java:83)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:167)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:154)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:49)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory.run(GlideExecutor.java:393)
我是否缺少一些我尚未完成的权限?
问题 #1:ACTION_PICK
不使用 MIME 类型
问题 #2:ACTION_PICK
确实使用了 Uri
来指示您从中挑选的集合,而您没有提供
问题 #3:ACTION_PICK
很可能通过 onActivityResult()
return 一个 content
Uri
,而不是带有文件系统路径的东西
问题 #4:setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
毫无意义,因为您没有向另一个应用程序提供 content
Uri
,更不用说您已经授予读取权限的应用程序了
要解决这些问题,请将您的第一个代码片段替换为:
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
photoPickerIntent.setType("image/*");
if (photoPickerIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(photoPickerIntent, REQUEST_IMAGE_GALLERY);
}
将您的第二个代码片段替换为:
if(intent != null){
Uri uri = intent.getData();
requestMgr.load(uri).into(imageView);
} else {
displayImageStorageErrorMessage();
loadProfileImage();
}