fileprovider 的 file_paths.xml 必须置于 res/xml/ 目录下且命名严格匹配 android:resource 引用;android 10+ 需用 替代 以规避分区存储限制,路径匹配基于前缀且须用正斜杠。

FileProvider 的 file_paths.xml 必须放在 res/xml/ 下,且文件名要完全匹配 android:resource 引用
Android 构建系统不会自动识别任意路径下的 XML 文件。如果你把 file_paths.xml 放在 assets/、raw/ 或根 res/ 下,FileProvider 启动时会直接抛 IllegalArgumentException: Missing android:resource attribute 或更隐蔽的 NullPointerException(因找不到资源 ID)。
-
res/xml/file_paths.xml是唯一被 AndroidManifest 中@xml/file_paths正确解析的位置 - 文件名必须小写、无空格、不带扩展名以外的点(比如
file_paths_v2.xml不行) - 如果改了名字,Manifest 里
android:resource="@xml/xxx"的xxx必须同步更新
<external-files-path></external-files-path> 和 <external-path></external-path> 的区别决定你能否在 Android 10+ 上正常分享文件
Android 10(API 29)起强制启用分区存储(Scoped Storage),<external-path></external-path> 指向整个外部存储根目录(如 /sdcard/),即使你声明了 READ_EXTERNAL_STORAGE,FileProvider 也会拒绝解析该路径下的 URI —— 表现为 SecurityException: Permission Denial。
- 想共享 App 自己创建的文件(如下载到
getExternalFilesDir()的 PDF),用<external-files-path></external-files-path>,它不受分区存储限制 - 想共享公共目录(如
DCIM/Camera/)里的文件?别用FileProvider直接暴露路径 —— 改用MediaStore插入后获取content://URI -
<files-path></files-path>对应getFilesDir(),纯内部路径,无需权限,但其他 App 默认无法访问(除非android:grantUriPermissions="true"+Intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION))
path 属性值不是真实路径,而是“路径前缀匹配规则”,末尾斜杠影响匹配结果
<external-files-path path="images/" name="my_images"></external-files-path> 并不表示只允许 images/ 这个文件夹 —— 它实际匹配所有以 images/ 开头的子路径,比如 images/avatar.jpg、images/cache/temp.png 都可以;但 images.jpg(无斜杠)或 my_images/ 就不匹配。
- 如果写成
path=""(空字符串),则匹配该目录下所有文件和子目录 - 如果写成
path=".",反而不生效 ——FileProvider内部会忽略当前目录符号 - Windows 开发者注意:
path值必须用正斜杠/,不能用反斜杠\,否则运行时报XmlPullParserException
targetSdkVersion ≥ 30 时,android:requestLegacyExternalStorage="true" 对 FileProvider 无效
这个 flag 只影响 getExternalStorageDirectory() 等传统 API 的行为,不影响 FileProvider 的 XML 路径解析逻辑。很多开发者误以为加了它就能继续用 <external-path></external-path>,结果在 Android 11 设备上点击分享直接崩溃。
- 真要兼容旧路径逻辑?只能降 targetSdkVersion 到 29(不推荐)
- 更稳妥的做法:把待分享文件先拷贝到
getExternalFilesDir(),再用<external-files-path></external-files-path>暴露 - 别忘了在
AndroidManifest.xml的FileProvider<meta-data></meta-data>中指定正确的android:resource,拼错一个字母就白配
最常被跳过的一步是:生成 URI 时没检查 File 对象是否为 null 或路径是否真实存在 —— FileProvider.getUriForFile() 遇到非法 File 会直接抛 IllegalArgumentException,而不是返回 null。










