【问题标题】:Android 6: cannot share files anymore?Android 6:不能再共享文件了?
【发布时间】:2016-01-04 00:48:17
【问题描述】:

我正在分享一张图片,此代码适用于 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));

但是,当我尝试使用 Android 6 进行共享时,我收到了 toast 错误“无法附加空文件”。

我已验证文件存在且长度不为零。

谁有解决办法?

【问题讨论】:

  • 你是在选择器之前还是之后得到这个Toast?如果之后,您选择了哪个应用程序?另外,mFilename 到底指向哪里?
  • 在选择器之后,我尝试的每个应用都会发生这种情况。至少使用 Gmail 和环聊。
  • 您自己运行过 Gmail 和环聊吗?如果没有,他们将无法访问外部存储,直到您(用户)通过他们的运行时权限请求逻辑。
  • 是的!你说的对!!!!!!!!!!!!!!!!!!!!!!!!我启用了Gmail的外部存储权限,现在可以了!!!!!!
  • 虽然在我尝试分享时 Gmail 不请求许可对我来说似乎很愚蠢

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


【解决方案1】:

按照@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 文件中定义你的文件路径,我称之为“file_provider_paths.xml

    <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));

【讨论】:

  • 非常感谢您发布此信息 - 它对我帮助很大,并且现在可以完美运行。他们唯一需要解决的就是让文件的路径正确。
  • 字符串文件名=mCSVname.getText().toString()+".csv";文件 filelocation = new File(getExternalFilesDir (null), filename); Uri fileUri = FileProvider.getUriForFile(mContext, "com.myfileprovider", filelocation);
【解决方案2】:

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

我说这是一个“极端情况”,因为接收应用程序中的这个错误会影响用户,用户之前不能使用该应用程序并授予必要的权限。要么:

  • 用户以前从未使用过该应用,但它仍在尝试向其分享内容,或者

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

这两个都是低概率事件。

作为发送者,您有两个主要选择:

  1. 放弃使用file:// Uri 值,转而使用ContentProvider 之类的文件服务FileProvider,因此不再需要该权限,或者

  2. 只是生活在角落里

【讨论】:

  • 好的,我实现了 FileProvider,它工作正常!
  • @DanieleB:FWIW,我写了 a blog post 关于这个。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    我用来解决此问题的另一种方法是在将文件写入公共目录后立即使用 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
                }
            });
    

    这可能是满足您需求的较短解决方案。

    【讨论】:

      猜你喜欢
      • 2022-06-16
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 2012-03-20
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多