Android:不存储到外部存储分享文件失败问题排查
问题分析与修复方案
你的代码存在两个核心问题,导致文件无法被正确传递:
1. 跨应用分享私有文件的URI格式错误
应用的缓存目录属于私有存储区域,其他应用无法通过file://格式的URI直接访问。从Android 7.0(API 24)开始,系统严格禁止跨应用传递file:// URI,否则会触发FileUriExposedException,且目标应用根本无法读取到文件内容。必须使用FileProvider生成content://格式的URI来实现跨应用文件共享。
2. 权限标记被覆盖
代码中intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK是直接赋值flags,这会覆盖之前添加的Intent.FLAG_GRANT_READ_URI_PERMISSION,导致目标应用没有读取该文件的权限。
修复后的完整实现
第一步:配置FileProvider
在AndroidManifest.xml中添加FileProvider的声明:
<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>
第二步:创建文件路径配置文件
在res/xml/目录下新建file_paths.xml,指定允许共享的缓存目录:
<?xml version="1.0" encoding="utf-8"?> <paths> <cache-path name="shared_cache" path="." /> </paths>
第三步:修改分享逻辑代码
private fun generateNoteOnSD(fileName: String, content: String) { try { val file = File(requireActivity().cacheDir, fileName) // 用Kotlin的use函数自动管理流,避免手动关闭的资源泄漏问题 FileWriter(file).use { writer -> writer.append(content) } val intent = Intent(Intent.ACTION_SEND).apply { // 使用addFlags添加标记,避免覆盖权限标记 addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) type = "text/plain" // 通过FileProvider生成合法的content:// URI val fileUri = FileProvider.getUriForFile( requireContext(), "${requireContext().packageName}.fileprovider", file ) putExtra(Intent.EXTRA_STREAM, fileUri) } startActivity(intent) } catch (e: IOException) { e.printStackTrace() } }
额外优化建议
- 直接使用
File(requireActivity().cacheDir, fileName)替代路径拼接,避免路径错误。 - 可以在写入文件后添加文件存在性和内容校验,确保文件生成成功。
内容的提问来源于stack exchange,提问作者Leonardo Sibela
相关产品推荐
相关产品推荐

