使用 FileProvider 共享缓存的图像
Posted
技术标签:
【中文标题】使用 FileProvider 共享缓存的图像【英文标题】:Sharing cached images using FileProvider 【发布时间】:2013-11-08 12:04:37 【问题描述】:我有一个应用程序,它使用Universal Image Loader 从互联网下载照片,将它们缓存到 data/data/com.myapp/cache 并显示在 ImageViews 中。
我还想在我的应用中添加共享(WhatsApp、Facebook、Instagram、Dropbox 等),所以我尝试使用以下代码:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, photoUri);
intent.setType("image/jpeg");
startActivity(Intent.createChooser(intent, "Share image"));
photoUri 是缓存文件夹中的 uri,其他应用无权读取。
所以我搜索/***ed 和 found out 我需要使用 FileProvider。
我在清单中按如下方式配置了 FileProvider (as was written here):
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.myapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
还有file_paths.xml:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="photo_cache" path="/"/>
</paths>
然后我在按钮 onClickListener 的活动中使用以下代码:
File photoFile = ImageLoader.getInstance().getDiscCache().get("HTTP LINK HERE");
// returns File of "/data/data/com.myapp/cache/-1301123243"
Uri photoUri = FileProvider.getUriForFile(MyActivity.this, "com.myapp.fileprovider", photoFile);
// returns Uri of "content://com.myapp.fileprovider/photo_cache/-1301123243"
photoUri = Uri.parse(photoUri.toString() + ".jpg");
// then I add .jpg to file name
// Create intent
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, photoUri);
intent.setType("image/jpeg");
// Grant permissions to all apps that can handle this intent
// thanks to this answer http://***.com/a/18332000
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList)
String packageName = resolveInfo.activityInfo.packageName;
grantUriPermission(packageName, photoUri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
// And start
startActivity(Intent.createChooser(intent, "Share image"));
但是,根据应用程序,我会遇到奇怪的异常。像这样:
1974-1974/com.whatsapp W/Bundle﹕ Key android.intent.extra.STREAM expected ArrayList but value was a android.net.Uri$HierarchicalUri. The default value <null> was returned.
1974-1974/com.whatsapp W/Bundle﹕ Attempt to cast generated internal exception:
java.lang.ClassCastException: android.net.Uri$HierarchicalUri cannot be cast to java.util.ArrayList
at android.os.Bundle.getParcelableArrayList(Bundle.java:1223)
at android.content.Intent.getParcelableArrayListExtra(Intent.java:4425)
at com.whatsapp.ContactPicker.d(ContactPicker.java:320)
at com.whatsapp.ContactPicker.onCreate(ContactPicker.java:306)
at android.app.Activity.performCreate(Activity.java:5104)
或者我只是看到这样的日志:
591-963/system_process W/ActivityManager﹕ Permission denied: checkComponentPermission()
当然,应用程序本身也会给我带来错误(它们无法打开或下载文件)。
我试过很多次,用谷歌搜索过,***ed 很多,所以现在我在这里发帖。 我想我做得对,也许只是一些小事是错的......
任何帮助将不胜感激!
【问题讨论】:
你能把互联网权限放在android xml文件中 @kTekkie 我认为你没有正确理解这个问题,抱歉 @Makks129 您是否使用 JSON 获取图像,如果是,您可以与我分享示例代码吗?或者我可以在 github 上分叉吗?我的要求是:Universal Image Loader + with JSON in a GridView ---- 不想对图片使用固定链接 【参考方案1】:我认为这可能是 FileProvider 基础架构或您与之共享的应用程序的问题。
我一直在尝试使用此支持与其他应用程序共享图像。它与 Gallery、Drive、Gmail 和 Keep 配合使用时效果很好。照片和 Google+ 失败。
我在 LogCat 中看到如下条目,这让我相信 Uri 正在从一个 Activity 传递到另一个 Activity。但是,Intent 中设置的(临时)权限正在丢失。
11-19 21:14:06.031:I/ActivityManager(433):显示 com.google.android.apps.plus/.phone.HostPhotoViewIntentActivity:+848 毫秒
【讨论】:
您是否在 Instagram、Facebook 或 Messenger 上尝试过这种方法?它应该可以工作,但它看起来不是这样。以上是关于使用 FileProvider 共享缓存的图像的主要内容,如果未能解决你的问题,请参考以下文章
android 7.0 关闭严格模式绕过fileprovider共享文件的限制
Android 7.0 通过FileProvider实现应用间文件共享
Android N 7.0 应用间共享文件(FileProvider)
java.lang.ClassNotFoundException:在Adone AIR本机扩展中未找到类“android.support.v4.content.FileProvider”错误(示例代码