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

Android实现文件分享功能时遇文件访问权限被拒报错

问题核心原因
  • Android 7.0(API24)及以上版本系统强制禁止跨应用传递file://格式的文件Uri,这种直接拼接文件路径的写法不会给接收方应用授予文件访问权限,对方尝试读取文件时会直接被系统拦截,和你是否添加ScopedStorage忽略配置、是否申请读写外部存储权限无关:读写存储权限仅授权你自己的应用访问存储,不会给第三方应用开放对应路径的访问资格。
  • 你看到的Permission to access file is denied报错,本质是接收方应用拿到你传的file://路径后,没有权限直接访问公共存储目录下的文件,被MediaProvider拦截导致的。
修复方案

1. 清单文件注册FileProvider

FileProvider是安卓官方提供的跨应用文件分享组件,专门用来生成带临时访问授权的content://格式Uri,替换不安全的file://传递方式。
在AndroidManifest.xml的<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>

2. 配置可分享的文件路径

在项目res目录下新建xml子目录,在其中创建file_paths.xml文件,配置你需要分享的文件所在目录的映射。你当前要分享的文件在Download公共目录,配置如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 映射外部存储Download目录 -->
    <external-path name="download_files" path="Download/"/>
    
    <!-- 如果后续需要分享其他目录的文件,对应添加映射即可:
    应用内部files目录用<files-path>
    应用外部私有存储目录用<external-files-path>
    外部存储根目录用<external-path>
    -->
</paths>

3. 修改分享逻辑代码

把原来直接拼接file://的逻辑替换为FileProvider生成授权Uri,同时主动给接收方添加临时读权限:

public void buttonShareFile(View view) {
    File file = new File(stringFile);
    if(!file.exists()) {
        Toast.makeText(this, "No file!", Toast.LENGTH_LONG).show();
        return;
    }

    Intent intentShare = new Intent(Intent.ACTION_SEND);
    intentShare.setType("text/csv");
    // 生成带授权的content格式Uri
    Uri shareUri = FileProvider.getUriForFile(
            this,
            BuildConfig.APPLICATION_ID + ".fileprovider",
            file
    );
    intentShare.putExtra(Intent.EXTRA_STREAM, shareUri);
    // 给目标应用授予该Uri的临时读取权限
    intentShare.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    startActivity(Intent.createChooser(intentShare, "Share the file...."));
}
额外适配注意事项
  • Android 13(API33)及以上版本上,旧版READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限已经失效,如果分享的是应用自身生成的文件,不需要申请这两个权限,也不需要添加ScopedStorage忽略标记,直接通过FileProvider分享即可正常工作。
  • 如果文件由你的应用生成,优先存到应用自身的外部私有目录(context.getExternalFilesDir()对应路径),再通过FileProvider分享,这种方式完全不需要申请任何存储权限,适配所有安卓版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:36:18