尽管使用了 ContentProvider,但无法从内部存储共享图像
Cannot share images from internal storage despite using a ContentProvider
我的 Android 应用程序使用 facebook 的 Fresco 库从互联网上下载一些图像。为了在 WebView
中显示这些图像并共享它们,我使用 Fresco 检索图像并将它们写入我应用程序的内部缓存目录中的临时文件:
final File tempFile = new File(new File(cx.getCacheDir(), "fresco_cache/"), filename);
saveInputStream(tempFile, is, new FileSaverCallback() {
@Override
public void onSuccess() {
Uri localUri = CacheContentProvider.getContentUriFromUrlOrUri(url);
callback.onSuccess(url, localUri.toString());
}
@Override
public void onFailure() {
callback.onFailure(url);
}
});
然后,我有一个自定义 ContentProvider
来提供对这些文件的访问。提供商成功解析了 Uri
,因为我在内部使用图像的内容 URI 而不是真实的文件路径。但是,当我尝试使用
共享图像时
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(ARG_IMAGE_URI));
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, "Share"));
共享不适用于大多数应用程序,但适用于少数应用程序。例如,我可以使用 K-9 将文件附加到电子邮件,但不能与 Google Keep 共享(它说:"Error importing data")。
我的ContentProvider
是这样注册的:
<provider
android:name=".helpers.CacheContentProvider"
android:authorities="my.app.files"
android:exported="true"
android:grantUriPermissions="true"/>
我检查过 openFile()
函数被正确调用并且 returns 一个有效的 ParcelFileOpener
:
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
final File f = getFileForUri(getContentUriFromUrlOrUri(uri.toString()));
if (f.exists())
return ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
throw new FileNotFoundException(uri.getPath());
}
我该如何调试该问题?我能做错什么?
编辑: 共享用于我的代码的旧实现,我使用 Universal Image Loader 而不是 Fresco。我看到的唯一区别是现在图像被保存到内部缓存,而之前它们被保存到 /sdcard/data/my.app/..
.
当某些包想要访问我的应用程序的内部文件时,发现缺少权限。我无法弄清楚如何正确授予这些权限,尽管尝试了我在有关该主题的许多 SO 帖子中找到的所有内容。切换到外部存储而不是内部存储解决了这个问题。
我的 Android 应用程序使用 facebook 的 Fresco 库从互联网上下载一些图像。为了在 WebView
中显示这些图像并共享它们,我使用 Fresco 检索图像并将它们写入我应用程序的内部缓存目录中的临时文件:
final File tempFile = new File(new File(cx.getCacheDir(), "fresco_cache/"), filename);
saveInputStream(tempFile, is, new FileSaverCallback() {
@Override
public void onSuccess() {
Uri localUri = CacheContentProvider.getContentUriFromUrlOrUri(url);
callback.onSuccess(url, localUri.toString());
}
@Override
public void onFailure() {
callback.onFailure(url);
}
});
然后,我有一个自定义 ContentProvider
来提供对这些文件的访问。提供商成功解析了 Uri
,因为我在内部使用图像的内容 URI 而不是真实的文件路径。但是,当我尝试使用
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(ARG_IMAGE_URI));
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, "Share"));
共享不适用于大多数应用程序,但适用于少数应用程序。例如,我可以使用 K-9 将文件附加到电子邮件,但不能与 Google Keep 共享(它说:"Error importing data")。
我的ContentProvider
是这样注册的:
<provider
android:name=".helpers.CacheContentProvider"
android:authorities="my.app.files"
android:exported="true"
android:grantUriPermissions="true"/>
我检查过 openFile()
函数被正确调用并且 returns 一个有效的 ParcelFileOpener
:
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
final File f = getFileForUri(getContentUriFromUrlOrUri(uri.toString()));
if (f.exists())
return ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
throw new FileNotFoundException(uri.getPath());
}
我该如何调试该问题?我能做错什么?
编辑: 共享用于我的代码的旧实现,我使用 Universal Image Loader 而不是 Fresco。我看到的唯一区别是现在图像被保存到内部缓存,而之前它们被保存到 /sdcard/data/my.app/..
.
当某些包想要访问我的应用程序的内部文件时,发现缺少权限。我无法弄清楚如何正确授予这些权限,尽管尝试了我在有关该主题的许多 SO 帖子中找到的所有内容。切换到外部存储而不是内部存储解决了这个问题。