Android 10调用setImageURI触发FileNotFoundException问题求助
这个问题我之前做项目时刚好碰到过,结合Android 10的特性和你给出的日志信息,咱们一步步来排查解决:
首先得明确一个关键点:你日志里的路径/data/user/0/com.myapp/files/是App的内部私有存储目录,访问这个目录完全不需要READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限——这两个权限是给外部存储用的,所以你加的权限其实和当前问题无关,可以先把这点理清。
1. 优先确认文件是否真的存在
日志里明确提示ENOENT (No such file or directory),这说明系统找不到指定的文件,所以第一步要验证文件的存在性:
- 在调用
setImageURI(uri)之前,通过File file = new File(getFilesDir(), "1585300417998.jpg");(替换成你的实际文件名)检查file.exists()和file.isFile()是否返回true。 - 如果文件不存在,就要排查文件生成的环节:是不是写入时失败了?或者生成文件的路径和你现在调用的路径不一致?比如文件名有没有大小写错误、后缀名写错?
- 另外,你是在
onSizeChanged方法里触发的setImage,这时候有可能文件还没完成写入(比如后台线程还在保存文件),导致读取时文件还不存在。可以加个判断逻辑,等文件完全写入后再调用设置图片的方法。
2. 检查URI的构造是否符合Android规范
如果文件确实存在,那大概率是URI格式的问题。对于App内部存储的文件,不建议直接用Uri.fromFile(file)生成file://格式的URI——虽然在自己App里偶尔能生效,但Android 10及以上对文件URI的处理有更严格的限制,推荐用FileProvider生成content://格式的URI:
- 第一步:在
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文件,配置内部存储的files目录:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="internal_files" path="." /> </paths>
- 第三步:生成正确的Content URI并设置:
File file = new File(getFilesDir(), "1585300417998.jpg"); Uri contentUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileprovider", file); yourAppCompatImageView.setImageURI(contentUri);
3. 替代方案:绕开setImageURI直接读取文件
如果上面的方法还是有问题,可以直接用FileInputStream读取文件并转换为Drawable,避免URI相关的问题:
File file = new File(getFilesDir(), "1585300417998.jpg"); if (file.exists()) { try (FileInputStream fis = new FileInputStream(file)) { Drawable drawable = Drawable.createFromStream(fis, null); yourAppCompatImageView.setImageDrawable(drawable); } catch (IOException e) { e.printStackTrace(); } } else { // 文件不存在时的处理逻辑,比如显示占位图 }
4. 额外提醒:分区存储不影响内部存储
最后再强调下,Android 10的分区存储(Scoped Storage)规则只针对外部存储,完全不影响App的内部私有存储目录,所以你不需要申请MANAGE_EXTERNAL_STORAGE权限,也不需要适配分区存储的其他规则,把重点放在文件存在性和URI正确性上就好。
内容的提问来源于stack exchange,提问作者matdev
相关产品推荐
相关产品推荐

