【发布时间】:2017-09-21 06:14:02
【问题描述】:
我想使用设备中任何可用的图像查看器打开我的应用资产中的图像。使用 cwac-provider 库,我已经能够毫无问题地对资产中的某些 .pps 文件执行相同的操作,但是图像不能完全按需要工作。我查看了演示和几乎所有可用的documentation。我什至搜索了网络和 SO 问题,但并没有真正得到解决。
我以 API 26 为目标。
这是我设置提供程序的方式。
AndroidManifest
<provider
android:name="com.commonsware.cwac.provider.StreamProvider"
android:authorities="com.justsomeproj.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="com.commonsware.cwac.provider.STREAM_PROVIDER_PATHS"
android:resource="@xml/asset_file_meta" />
</provider>
asset_file_meta
<paths>
<asset
name="gallery_a"
path="gallery/a" />
<asset
name="gallery_b"
path="gallery/b" />
...
</paths>
文件提供者
public class FileProvider {
private static final String AUTHORITY =
"com.justsomeproj.provider";
private static final Uri PROVIDER =
Uri.parse("content://" + AUTHORITY);
public static Uri buildUri(String path, String fileName) {
return (PROVIDER
.buildUpon()
.appendPath(StreamProvider.getUriPrefix(AUTHORITY))
.appendPath(path).appendPath(fileName)
.build());
}
public static boolean isIntentResolvable(Context context, Intent intent) {
PackageManager pm = context.getPackageManager();
return intent.resolveActivity(pm) != null;
}
}
意向调用
Intent intent = new Intent(Intent.ACTION_VIEW, FileProvider.buildUri(path, fileName));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (FileProvider.isIntentResolvable(this, intent))
startActivity(intent);
问题
因此,在执行意图时,图库确实会显示,但上面有空白预览和“无缩略图”消息。我尝试了多个图库应用,但都遇到了相同的结果,并且在 logcat 中看到了类似或相同的错误。
即使他们无法加载缩略图,他们也会收到文件。
我这样说是因为,在图库应用程序的空白预览中,如果我尝试查看文件信息,它确实会显示有关文件的正确信息。尝试从同一屏幕“共享”图像也可以,并且下一个应用程序(用于共享)可以毫无问题地获取图像文件。
然而,谷歌照片应用程序完美地显示了图像。很奇怪。
问题出现在 API 21、25、26 上,很可能也出现在这两者之间的其他版本上(未经测试)。
URI 生成
content://com.justsomeproj.provider/30b6ac14-6bec-4e54-a1d3-445367f69ccc/gallery_a/image1.jpeg
异常
java.io.FileNotFoundException: Not a whole file
Logcat
09-21 10:21:16.453 1214-2098/? I/PackageManager: Setting last chosen activity com.android.gallery3d/.app.GalleryActivity for user 0:
09-21 10:21:16.453 1214-2098/? I/PackageManager: Action: "android.intent.action.VIEW"
09-21 10:21:16.453 1214-2098/? I/PackageManager: Category: "android.intent.category.DEFAULT"
09-21 10:21:16.453 1214-2098/? I/PackageManager: Type: "image/jpeg"
09-21 10:21:16.453 1214-2098/? I/PackageManager: AutoVerify=false
09-21 10:21:16.461 1214-2677/? I/ActivityManager: START u0 {act=android.intent.action.VIEW dat=content://com.justsomeproj.provider/30b6ac14-6bec-4e54-a1d3-445367f69ccc/gallery_a/image1.jpeg flg=0x3000001 cmp=com.android.gallery3d/.app.GalleryActivity} from uid 10233 on display 0
09-21 10:21:16.675 14814-14814/? V/StateManager: startState class com.android.gallery3d.app.SinglePhotoPage
09-21 10:21:16.727 14814-15533/? W/UriImage: fail to open: content://com.justsomeproj.provider/30b6ac14-6bec-4e54-a1d3-445367f69ccc/gallery_a/image1.jpeg
java.io.FileNotFoundException: Not a whole file
at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:856)
at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:793)
at com.android.gallery3d.data.UriImage.openOrDownloadInner(UriImage.java:108)
at com.android.gallery3d.data.UriImage.openFileOrDownloadTempFile(UriImage.java:83)
at com.android.gallery3d.data.UriImage.prepareInputFile(UriImage.java:170)
at com.android.gallery3d.data.UriImage.-wrap0(UriImage.java)
at com.android.gallery3d.data.UriImage$RegionDecoderJob.run(UriImage.java:185)
at com.android.gallery3d.data.UriImage$RegionDecoderJob.run(UriImage.java:176)
at com.android.gallery3d.util.ThreadPool$Worker.run(ThreadPool.java:133)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
at com.android.gallery3d.util.PriorityThreadFactory$1.run(PriorityThreadFactory.java:44)
09-21 10:21:16.727 14814-15533/? W/SinglePhotoDataAdapter: fail to get region decoder, try to request thumb image
09-21 10:21:16.739 14814-14814/? W/SinglePhotoDataAdapter: fail to decode thumb
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
at com.android.gallery3d.app.SinglePhotoDataAdapter.onDecodeThumbComplete(SinglePhotoDataAdapter.java:151)
at com.android.gallery3d.app.SinglePhotoDataAdapter.-wrap1(SinglePhotoDataAdapter.java)
at com.android.gallery3d.app.SinglePhotoDataAdapter$3.handleMessage(SinglePhotoDataAdapter.java:70)
at android.os.Handler.dispatchMessage(Handler.java:102)
at com.android.gallery3d.ui.SynchronizedHandler.dispatchMessage(SynchronizedHandler.java:36)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6236)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
logcat 来自物理 API 25 设备。
我尝试了文档中有关支持旧版应用程序的建议,但没有成功。 我还尝试了对意图的一些调整,也没有任何乐趣。
@CommonsWare 我有点坚持这个所以寻求建议。我错过了什么?
我的意图好吗?
为什么它不起作用?
为什么 Google 相册应用运行良好?
这是图库应用程序还是库中的问题?
有解决方法吗?
目前我正在考虑将文件写入缓存并尝试通过 Android 的 FileProvider(而不是 cwac-provider 的 StreamProvider)查看它是否有效。
【问题讨论】:
标签: android image android-intent commonsware-cwac