
android 8.0+(api 26+)因严格限制 file:// uri 暴露,直接传递本地文件路径会导致“media not found”错误;必须使用 fileprovider 生成 content:// uri 并授予临时读取权限才能正常分享媒体文件。
在 Android API 28(即 Android 9)及更高版本中,系统禁止应用通过 file:// 协议向其他应用传递文件 URI(出于安全沙箱机制),否则接收方应用将无法访问该文件,从而抛出 “No media found” 或 “Permission denied” 等错误。你当前代码中直接使用 Uri.parse(selectedFile.getAbsolutePath()).toString() 构造 file:// 地址并传入 EXTRA_STREAM,正是问题根源。
✅ 正确做法是:使用 FileProvider 生成受控的 content:// URI,并显式授予临时读取权限。以下是完整、可落地的解决方案:
✅ 1. 配置 FileProvider(AndroidManifest.xml)
在 application> 标签下添加:
⚠️ 注意:android:authorities 必须与代码中 getUriForFile() 的第二个参数完全一致(建议采用 包名.fileprovider 格式)。
✅ 2. 定义文件访问路径(res/xml/file_paths.xml)
创建 res/xml/file_paths.xml(若目录不存在请先新建):
✅ 3. 修改分享逻辑(关键修复)
替换你原有 SHARED 分支代码为以下健壮实现:
if (item.getTitle().equals("SHARED")) {
File file = selectedFile;
if (!file.exists()) {
Toast.makeText(context, "File not found", Toast.LENGTH_SHORT).show();
return;
}
Uri uri;
try {
// 使用 FileProvider 获取 content:// URI(核心!)
uri = FileProvider.getUriForFile(
context,
"com.example.project.fileprovider", // 必须与 manifest 中 authorities 一致
file
);
} catch (IllegalArgumentException e) {
Log.e(DebugUtils.TAG, "Failed to generate URI for file: " + file, e);
Toast.makeText(context, "Sharing not supported for this file", Toast.LENGTH_SHORT).show();
return;
}
Intent share = new Intent(Intent.ACTION_SEND);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // ⚠️ 必须!授予临时读权限
share.putExtra(Intent.EXTRA_STREAM, uri);
// 自动推断 MIME 类型(比字符串判断更可靠)
String mimeType = getContentResolver().getType(uri);
if (mimeType == null) {
mimeType = getMimeType(file.getAbsolutePath()); // 可补充简易 MIME 推断方法(见下方)
}
share.setType(mimeType);
Intent chooser = Intent.createChooser(share, "Share via");
chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(chooser);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, "No app available to handle this file type", Toast.LENGTH_SHORT).show();
}
}? 补充:简易 MIME 类型推断方法(可选)
private String getMimeType(String path) {
String extension = MimeTypeMap.getFileExtensionFromUrl(path);
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
}⚠️ 重要注意事项
- 不要手动拼接 file:// 或 content:// 字符串:必须调用 FileProvider.getUriForFile()。
- FLAG_GRANT_READ_URI_PERMISSION 不可省略:这是让目标 App 临时获得读取权限的唯一方式。
- FileProvider 的 authorities 必须全局唯一,且与代码、manifest 严格一致。
- 若分享到微信、QQ 等第三方 SDK,部分旧版可能仍存在兼容性问题,建议测试时优先选择系统相册、Gmail、Telegram 等标准 App 验证流程。
- 对于 targetSdkVersion >= 30(Android 11+),还需注意 MANAGE_EXTERNAL_STORAGE 权限策略,但仅限媒体分享场景,通常 FileProvider + 外部路径声明已足够。
通过以上改造,你的图片/视频分享功能即可在 Android 8.0 至最新版本稳定运行,彻底解决 “Media not found” 错误。










