图像共享意图适用于 Gmail,但会导致 FB 和 twitter 崩溃 [英] Image share intent works for Gmail but crashes FB and twitter

查看:31
本文介绍了图像共享意图适用于 Gmail,但会导致 FB 和 twitter 崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试允许用户将图像共享给设备上的其他应用程序.该图像位于我的应用程序内部存储区域的 files/子目录中.它在 Gmail 上运行良好,但 Facebook 和 Twitter 在响应我的意图时都崩溃了.

I am trying to allow the user to share an image to other apps on the device. The image is inside the files/ subdirectory of my app's internal storage area. It works just fine with Gmail, but Facebook and Twitter both crash when responding to my intent.

Google+ 也能正常工作.

Google+ also works fine.

这里是相关的代码部分.

Here are the relevant sections of code.

在 Application.xml 中

In Application.xml

<provider 
    android:name="android.support.v4.content.FileProvider"
    android:authorities="org.iforce2d.myapp.MyActivity"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepaths" />
</provider>

xml/filepaths.xml

xml/filepaths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="shared" path="shared"/>
</paths>

这是我活动中的分享代码:

Here is the sharing code in my activity:

File imagePath = new File(getContext().getFilesDir(), "shared");
File newFile = new File(imagePath, "snapshot.jpg");
Uri contentUri = FileProvider.getUriForFile(getContext(),
                     "org.iforce2d.myapp.MyActivity", newFile);    

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("image/jpeg");
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

List<ResolveInfo> resInfos = 
    getPackageManager().queryIntentActivities(shareIntent,
                                              PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo info : resInfos) {
    getContext().grantUriPermission(info.activityInfo.packageName, 
                                    contentUri,
                                    Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

startActivity(Intent.createChooser(shareIntent, "Share image..."));

记录时contentUri的值为:

content://org.iforce2d.myapp.MyActivity/shared/snapshot.jpg

我只使用 Gmail、Facebook 和 Twitter 作为接收应用程序进行了检查,但结果在广泛的操作系统版本(从 2.2.1 到 4.4.3)和包括 Kindle 的 7 台设备上都非常一致.

I have only checked this with Gmail, Facebook and Twitter as the receiving apps, but the results have been very consistent over a wide range of OS versions (from 2.2.1 to 4.4.3) and 7 devices include a Kindle.

Gmail 效果很好.图片缩略图出现在邮件撰写中,发送时成功附加到邮件中.

Gmail works great. Image thumbnail appears in mail composition, and successfully attaches to mail when sent.

Twitter 和 Facebook 都崩溃了,如下所示.

Twitter and Facebook both crash, as below.

这是来自 logcat 的堆栈跟踪,显示了这两个应用程序所遇到的问题,它们似乎是相同的问题(这是从 4.​​4.3 中获取的,但错误实际上一直是相同的)到 2.2.1,尽管错误消息的措辞略有不同):

Here are the stack traces from logcat showing the problem these two apps are having, it appears to be the same problem for both of them (this is taken from 4.4.3, but the errors were practically the same all the way back to 2.2.1 albeit with slightly different wording of the error message):

Caused by: 
  java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. 
  Make sure the Cursor is initialized correctly before accessing data from it.
    at android.database.CursorWindow.nativeGetString(Native Method)
    at android.database.CursorWindow.getString(CursorWindow.java:434)
    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
    at android.database.CursorWrapper.getString(CursorWrapper.java:114)
    at com.twitter.library.media.util.f.a(Twttr:95)
    ...

Caused by: 
  java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.
  Make sure the Cursor is initialized correctly before accessing data from it.
    at android.database.CursorWindow.nativeGetString(Native Method)
    at android.database.CursorWindow.getString(CursorWindow.java:434)
    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
    at android.database.CursorWrapper.getString(CursorWrapper.java:114)
    at com.facebook.photos.base.media.MediaItemFactory.b(MediaItemFactory.java:233)
    ...

鉴于在 Facebook 和 Twitter 上分享图片是数百万人整天都在做的事情,我感到非常震惊,因为它很难实施:/

Given that sharing images on Facebook and Twitter is something that millions of people do all day long, I'm pretty shocked that it's so hard to implement :/

有人能发现我在这里做错了什么吗?

Can anybody spot something I'm doing wrong here?

推荐答案

EDIT -- 此答案中描述的解决方法有效,但 Stefan 提供的解决方案 更优雅.这应该是公认的答案.

EDIT -- The workaround described in this answer works, but the solution provided by Stefan is more elegant. It should be the accepted answer.

此外,截至 2015 年 1 月,Facebook 应用程序不再存在此错误(现在可与标准 FileProvider 配合使用),但 Twitter 仍然存在.希望将来它会完全消失,而且这些都不是必需的.

Also, as of January 2015, the Facebook app no longer has this bug (and now works with the standard FileProvider) but Twitter still does. Hopefully it will go completely away in the future, and neither of these will be necessary.

虽然 FileProvider 对象在理论上看起来很棒,但在共享到许多第三方应用程序时它似乎不起作用(而谷歌应用程序,如 G+、Gmail 和 c 工作完美).要么它没有公开足够的信息,要么那些应用程序只是假设您正在共享文件,从而导致崩溃.

While the FileProvider object looks wonderful in theory, it doesn't seem to work when sharing to many third-party applications (while Google ones, like G+, Gmail, &c work perfectly). Either it doesn't expose sufficient information, or those applications just assume you're sharing files, and thus crash.

真的很郁闷!:/

我发现共享图像文件的唯一可靠方法是将它们复制到外部存储目录(您可以创建一个 .nomedia 子目录以避免它们出现在 Gallery 应用程序中).

The only reliable way I've found to share image files is to copy them to the external storage directory (you can create a .nomedia subdirectory to avoid them appearing in the Gallery app).

例如:

Bitmap bitmapToShare = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

File pictureStorage = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File noMedia = new File(pictureStorage, ".nomedia");
if (!noMedia.exists())
    noMedia.mkdirs();

File file = new File(noMedia, "shared_image.png");
saveBitmapAsFile(bitmapToShare, file);

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
shareIntent.setType("image/png");

startActivity(shareIntent);

附录:当然,在尝试写入/复制文件之前,您还应该检查 getExternalStorageState().

Addendum: of course, you should also check getExternalStorageState() before trying to write/copy the file there.

这篇关于图像共享意图适用于 Gmail,但会导致 FB 和 twitter 崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆