Android 6:不能再共享文件了?

时间:2015-10-06 23:04:09

标签: android android-intent share android-6.0-marshmallow

我正在分享图片,此代码适用于Android 6之前的设备:

Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri uri = Uri.fromFile(new File(mFilename));
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));

但是我收到了toast错误" 无法附加空文件"当我尝试使用Android 6分享时。

我确认该文件存在,并且它不是零长度。

任何人都有解决方案吗?

4 个答案:

答案 0 :(得分:37)

我按照@CommonsWare

的建议,通过实施FileProvider解决了这个问题

首先需要配置FileProvider:

  • 首先,将<provider>添加到文件清单XML

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.myfileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths" />
    </provider>
    
  • 第二,在单独的XML文件中定义文件路径,我称之为&#34; file_provider_paths.xml &#34;

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

您可以在此documentation page

中找到完整的说明

在XML中设置文件提供程序后,这是共享图像文件的代码:

Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri fileUri = FileProvider.getUriForFile(mContext, "com.myfileprovider", new File(mFilename));
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));

答案 1 :(得分:22)

Android 6.0运行时权限系统的一个限制是会出现导致问题的极端情况。您遇到的问题是:尝试将外部存储上的文件共享给没有针对该特定UI路径的运行时权限检查的应用程序。

我说这是一个&#34;角落案例&#34;因为,对于接收应用程序中影响用户的此错误,用户以前不能使用该应用程序并授予必要的权限。之一:

  • 用户以前从未使用过该应用,但仍尝试与其共享内容,或

  • 用户通过“设置”撤销了权限,但没有意识到它会破坏这一点功能

这两个都是低概率事件。

作为发件人,您有两个主要选项:

  1. 不再使用file:// Uri值,而是使用ContentProvider这样的文件服务FileProvider,因此不再需要权限,或者

  2. 与角落案一起生活

答案 2 :(得分:2)

或者,您不需要ContentProvider / FileProvider。您只需添加授予共享的uri读取权限的标志即可。 具体来说,share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 应该可以解决问题。

答案 3 :(得分:0)

我用来解决此问题的另一种方法是在将文件写入公共目录后立即使用MediaScannerConnection获取内容提供程序样式URI:

        MediaScannerConnection.scanFile(context, new String[] {imageFile.toString()}, yourMimeType, new OnScanCompletedListener() {
            @Override
            public void onScanCompleted(String path, Uri uri) {
                //uri = "content://" style URI that is safe to attach to share intent
            }
        });

这可能是一个更短的解决方案,满足您的需求。