You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android中如何使用setImageDrawable()加载不同路径图片?

解决Android加载外部存储图片时的FileNotFoundException问题

嘿,我来帮你搞定这个报错!你遇到的BitmapFactory: Unable to decode stream: java.io.FileNotFoundException,大概率是路径、权限或者文件本身的问题,咱们一步步排查:

1. 先确认文件路径和实际文件是否匹配

首先得搞清楚,代码里写的路径对应的文件是不是真的存在。你可以先把要加载的文件路径打印出来:

File targetFile = new File("/storage/emulated/0/Sensia_Sniffer/18_04_2018/18_56_18_photo.JPEG");
Log.d("ImagePathCheck", "目标文件路径:" + targetFile.getAbsolutePath());

然后打开Android Studio的Device File Explorer,顺着这个路径找过去,看看:

  • 文件是不是真的在这个目录里
  • 文件名有没有大小写错误(Android文件系统是区分大小写的,比如photo.JPEGphoto.jpeg是两个不同的文件)
  • 路径里的文件夹名称有没有写错(比如Sensia_Sniffer是不是拼对了)

2. 检查存储访问权限

你访问的/storage/emulated/0/...属于外部存储(不是app私有的内部存储),所以必须确保你有访问外部存储的权限:

静态权限声明

AndroidManifest.xml里添加权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 如果是Android 13及以上,还需要添加这个 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

动态权限申请

Android 6.0(API 23)及以上,光有静态声明还不够,得在代码里动态申请权限:

// 检查权限是否已授予
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    // 申请权限
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1001);
}

分区存储适配(Android 10+)

从Android 10(API 29)开始,系统默认启用了分区存储,直接访问外部存储的自定义目录会被限制。如果还没适配分区存储,可以先在AndroidManifest.xml<application>标签里加一句兼容代码:

<application
    ...
    android:requestLegacyExternalStorage="true">

当然,长期来看还是建议适配MediaStore API来访问图片,这样更符合系统规范。

3. 确认文件是否真的存在

在加载图片前,先判断文件是否存在,避免报错:

File imageFile = new File("/storage/emulated/0/Sensia_Sniffer/18_04_2018/18_56_18_photo.JPEG");
if (imageFile.exists() && imageFile.isFile()) {
    // 文件存在,加载图片
    Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
    holder.picture.setImageBitmap(bitmap);
} else {
    Log.e("ImageError", "文件不存在或者不是文件:" + imageFile.getAbsolutePath());
    // 这里可以设置一张默认占位图
    holder.picture.setImageDrawable(getResources().getDrawable(R.drawable.default_image));
}

如果这里打印了“文件不存在”,那你得检查保存图片的代码是不是有问题——比如保存路径写错了,或者保存时没有成功写入(比如IO异常没处理)。

4. 试试用图片加载库简化操作

自己用BitmapFactory加载不仅要处理权限、路径,还要考虑内存溢出的问题。推荐用Glide或者Picasso这类成熟的图片加载库,它们会帮你搞定所有细节:
比如用Glide的话,代码非常简洁:

Glide.with(context)
     .load(imageFile)
     .placeholder(R.drawable.loading_image) // 加载时的占位图
     .error(R.drawable.error_image) // 加载失败时的图
     .into(holder.picture);

Glide会自动处理权限检查、文件存在性判断、内存缓存等问题,省心很多。

先从路径和权限这两个最常见的原因排查,应该就能解决问题啦!

内容的提问来源于stack exchange,提问作者Iván de la Cruz

火山引擎 最新活动