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

从Download文件夹自动获取单张图片到ImageView时遇文件异常求助

解决MediaStore获取单张图片时的FileNotFoundException问题

这个问题我之前也碰到过,本质是你传给getBitmap()的不是单张图片的具体Uri,而是一个包含多张图片的集合Uri,系统没办法直接定位到单个文件,所以才抛出了FileNotFoundException。下面给你一套完整的解决思路和可直接用的代码:

核心思路

先通过MediaStore查询Download文件夹中的单张图片(比如最新的那一张),拿到它的具体Uri,再用这个Uri加载图片到ImageView,而不是直接传入集合Uri。

完整代码实现

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ImageView imageView = findViewById(R.id.image_view);

    // 从Download文件夹获取第一张图片的Uri
    Uri targetImageUri = getFirstImageFromDownload();
    if (targetImageUri != null) {
        // 将图片加载到ImageView
        loadImageToView(targetImageUri, imageView);
    } else {
        // 处理Download文件夹无图片的情况
        Toast.makeText(this, "Download文件夹里没找到图片哦", Toast.LENGTH_SHORT).show();
    }
}

// 查询Download文件夹中最新的一张图片Uri
private Uri getFirstImageFromDownload() {
    Uri imageCollection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    String[] projection = {MediaStore.Images.Media._ID};
    String sortOrder = MediaStore.Images.Media.DATE_MODIFIED + " DESC"; // 按修改时间倒序,取最新的
    String selection;
    String[] selectionArgs;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        // Android 10及以上,用RELATIVE_PATH定位Download文件夹
        selection = MediaStore.Images.Media.RELATIVE_PATH + " LIKE ?";
        selectionArgs = new String[]{"%Download%"};
    } else {
        // Android 10以下,用DATA字段定位路径
        selection = MediaStore.Images.Media.DATA + " LIKE ?";
        selectionArgs = new String[]{"%Download/%"};
    }

    // 用try-with-resources自动关闭Cursor,避免内存泄漏
    try (Cursor cursor = getContentResolver().query(
            imageCollection,
            projection,
            selection,
            selectionArgs,
            sortOrder
    )) {
        if (cursor != null && cursor.moveToFirst()) {
            // 通过图片ID构建单个图片的Uri
            long imageId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
            return ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageId);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

// 将图片加载到ImageView,兼容新旧版本
private void loadImageToView(Uri imageUri, ImageView imageView) {
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            // Android 9及以上,推荐用ImageDecoder替代已废弃的getBitmap
            ImageDecoder.Source source = ImageDecoder.createSource(getContentResolver(), imageUri);
            Bitmap bitmap = ImageDecoder.decodeBitmap(source);
            imageView.setImageBitmap(bitmap);
        } else {
            // 兼容旧版本系统
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
            imageView.setImageBitmap(bitmap);
        }
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(this, "图片加载失败", Toast.LENGTH_SHORT).show();
    }
}

关键细节说明

  • 查询条件适配:Android 10引入分区存储后,不能直接访问文件路径,所以用RELATIVE_PATH来定位Download文件夹;旧版本则用DATA字段匹配路径。
  • 取单张图片:通过DATE_MODIFIED DESC排序,取查询结果的第一条,也就是最新的图片;如果想取特定图片,可以修改selection条件(比如按文件名筛选)。
  • 避免内存泄漏:用try-with-resources自动关闭Cursor,不用手动调用close()。
  • 废弃方法替代:MediaStore.Images.Media.getBitmap()已经被废弃,Android 9及以上推荐用ImageDecoder来加载图片,性能更好也更稳定。

内容的提问来源于stack exchange,提问作者techtechie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:54:22