You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android FileUriExposedException问题:旧多CSV文件分享代码新版本失效求助

解决Android 7.0+的FileUriExposedException问题

这个坑我踩过好多次了!你遇到的android.os.FileUriExposedException是Android 7.0(API 24)开始引入的安全限制——系统禁止App直接把file://格式的Uri暴露给其他应用,防止私有文件被随意访问。你的分享代码直接传入了原始的CSV文件Uri,大概率就是file://类型的,所以触发了异常。

下面是完整的修复方案,一步步来:

1. 在AndroidManifest.xml中注册FileProvider

FileProvider是AndroidX提供的工具,用来生成安全的content://格式Uri替代file://。先在你的清单文件里添加这个Provider:

<application>
    <!-- 其他已有的代码 -->
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>
  • android:authorities:用你的应用包名加上.fileprovider,${applicationId}会自动替换成你的包名,避免手动写错。
  • android:exported必须设为false,因为FileProvider不需要对外暴露。
  • android:grantUriPermissions设为true,允许临时授权其他应用访问文件。

2. 创建共享路径配置文件

在res/xml目录下新建file_paths.xml文件(如果xml目录不存在就自己建一个),用来指定哪些目录下的文件可以被共享。根据你的CSV文件存储位置调整:

比如你的CSV文件存在外部存储的MyApp/CSVs/目录下,配置如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 外部存储根目录对应Environment.getExternalStorageDirectory() -->
    <external-path
        name="my_csv_files"
        path="MyApp/CSVs/" />
</paths>

如果你的文件存在应用内部存储的files目录下(比如getFilesDir()),就用<files-path>标签;如果是缓存目录,用<cache-path>。

3. 修改分享代码,替换为安全的Content Uri

把原来的file:// Uri转换成FileProvider生成的content:// Uri,还要添加临时权限:

public static void sendCsvFilesToAnotherApp(final AppCompatActivity activity, final ArrayList<Uri> csvUris) {
    ArrayList<Uri> safeContentUris = new ArrayList<>();
    // 注意这里要和Manifest里的authorities一致
    String authority = activity.getPackageName() + ".fileprovider";

    for (Uri originalUri : csvUris) {
        // 把原始的file:// Uri转换成File对象
        File csvFile = new File(originalUri.getPath());
        // 生成安全的content:// Uri
        Uri safeUri = FileProvider.getUriForFile(activity, authority, csvFile);
        safeContentUris.add(safeUri);
    }

    Intent sendIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
    // 统一设置MIME类型为text/csv即可
    sendIntent.setType("text/csv");
    sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, safeContentUris);
    // 必须添加这个flag,授予接收应用临时读取权限
    sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    // 先检查有没有能处理这个Intent的应用,避免崩溃
    if (sendIntent.resolveActivity(activity.getPackageManager()) != null) {
        activity.startActivity(Intent.createChooser(sendIntent, "分享CSV文件"));
    }
}

额外注意事项

  • 如果你的应用目标SDK是Android 10(API 29)及以上,还要注意Scoped Storage的限制:如果是访问外部存储的公共目录(比如Downloads),可能需要用MediaStore来获取Uri,而不是直接用File;如果是应用自己创建的私有目录,上面的FileProvider方案依然有效。
  • 确保所有要分享的文件都在你配置的共享路径范围内,否则FileProvider会抛出异常。

内容的提问来源于stack exchange,提问作者user9665241

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:48:08