Android平台文件已存在却提示‘File not found’问题排查求助
解决Android中「File not found, but file exists」异常的方案
咱们来一步步拆解你遇到的这个头疼问题——文件明明存在,却提示找不到。结合你的代码和Android存储机制的特性,我整理了几个核心问题点和对应的解决方案:
1. 先搞定Scoped Storage的权限限制(Android 10+必看)
从Android 10开始,Scoped Storage限制了App对外部存储的直接访问,哪怕文件是你自己App创建的,直接用File类跨Activity读取也可能触发权限问题,导致“文件找不到”的假象。
修复建议:
- 用系统API获取可靠路径:不要硬编码
/storage/emulated/0/Android/media/one.empty3.feature.app/,换成Context.getExternalMediaDirs()来获取App专属的媒体目录,适配所有设备和系统版本:// 获取App的外部媒体目录 File mediaDir = getExternalMediaDirs()[0]; // 创建data子目录 File dataDir = new File(mediaDir, "data"); if (!dataDir.exists() && !dataDir.mkdirs()) { System.err.println("创建目录失败:" + dataDir.getAbsolutePath()); return null; } // 生成最终文件路径 File file2 = new File(dataDir, name + "_" + n + ".jpg"); - 跨Activity传递文件用FileProvider:直接传文件路径容易踩权限坑,换成FileProvider生成可共享的Uri,让第二个Activity能安全读取:
- 第一步:在
AndroidManifest.xml注册FileProvider:<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> - 第二步:在
res/xml下新建file_paths.xml,配置可共享的目录:<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-media-path name="app_images" path="data/" /> </paths> - 第三步:第一个Activity中生成Uri并传递给ChooseEffects:
File targetFile = writePhoto(photo, "MyFilePicture"); Uri fileUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", targetFile); Intent intent = new Intent(this, ChooseEffects.class); intent.setData(fileUri); // 授予读取权限 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent); - 第四步:在ChooseEffects中用ContentResolver读取:
val fileUri = intent.data ?: return contentResolver.openInputStream(fileUri)?.use { inputStream -> val bitmap = BitmapFactory.decodeStream(inputStream) // 后续处理逻辑 }
- 第一步:在
2. 修复代码中的路径拼接bug
看你的writePhoto方法里,dirName2的路径没写完(后半部分被注释掉了),这会导致生成的文件路径不完整,比如变成/storage/emulated/0/Android/media/one.empty3.feature.app/,这根本不是一个合法的文件路径!赶紧把这个路径补全,或者直接用上面提到的系统API生成路径,避免手动拼接出错。
3. 替换自定义ImageIO为Android原生API
你在fillGallery里用的ImageIO.read()应该是自定义工具类?Android SDK本身没有这个类,这类自定义工具很可能没有适配Scoped Storage的权限规则,导致读取失败。换成Android原生的BitmapFactory来读取文件,兼容性更好:
// 替换原来的ImageIO.read逻辑 Bitmap read = BitmapFactory.decodeFile(allFiles[i].getAbsolutePath()); if (read != null) { imageView.setImageBitmap(read); currentFile = allFiles[i]; } else { System.err.println("读取文件失败:" + allFiles[i].getAbsolutePath()); }
4. 别忘了触发媒体扫描(可选)
如果你的文件需要被系统媒体库识别,写入后发送一个媒体扫描广播,确保系统能感知到文件的存在:
MediaScannerConnection.scanFile(this, new String[]{file2.getAbsolutePath()}, new String[]{"image/jpeg"}, (path, uri) -> System.out.println("文件已被媒体库扫描:" + path));
按照上面的步骤逐一排查,应该就能解决你遇到的「文件存在却找不到」的问题啦!
内容的提问来源于stack exchange,提问作者Obi Two
相关产品推荐
相关产品推荐

