You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 13:43:14