Android开发中Uri ArrayList转Bitmap ArrayList触发FileNotFoundException如何解决
问题解决方法
报错根因
你调用MediaStore.Images.Media.getBitmap()时报No content provider错误,是因为你生成Uri的方式不对:你直接把本地文件的绝对路径传给Uri.parse(),生成的Uri没有file://协议前缀,系统的ContentResolver无法识别这是本地文件路径,以为是内容提供者(ContentProvider)的Uri,自然找不到对应的资源。
修复步骤
1. 修正Uri生成逻辑
把你生成Uri的代码换成用Uri.fromFile()方法,生成合法的带协议的本地文件Uri:
ArrayList<Uri> uris = new ArrayList<>(); for (int i = 0; i < f.size(); i++) { // 替换原来的Uri.parse,f.get(i)是文件路径字符串 File imageFile = new File(f.get(i)); Uri uri = Uri.fromFile(imageFile); uris.add(uri); }
2. 遍历所有Uri生成处理后的Bitmap列表
你当前代码只处理了第一个Uri,要循环处理整个uris列表,才能得到完整的Bitmap集合:
ArrayList<Bitmap> processedBitmaps = new ArrayList<>(); if (uris != null && !uris.isEmpty()) { Log.d("PreviewImageAdapter", "uri: " + uris); try { // 循环处理所有Uri for (Uri uri : uris) { // 读取Bitmap Bitmap bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); // 你的OpenCV处理逻辑 Mat selected_image = new Mat(bmp.getHeight(), bmp.getWidth(), CvType.CV_8UC4); Utils.bitmapToMat(bmp, selected_image); selected_image = objectDetectorClass.recognizePhoto(selected_image); Bitmap processedBmp = Bitmap.createBitmap(selected_image.cols(), selected_image.rows(), Bitmap.Config.ARGB_8888); Utils.matToBitmap(selected_image, processedBmp); // 加入结果列表 processedBitmaps.add(processedBmp); // 可选:回收原始Bitmap节省内存 bmp.recycle(); } } catch (IOException e) { e.printStackTrace(); } }
3. 权限适配注意
如果你的App运行在Android 10(API 29)及以上版本,需要在AndroidManifest.xml的application节点添加以下属性适配分区存储:
<application ... android:requestLegacyExternalStorage="true">
同时要确保已经动态申请了READ_EXTERNAL_STORAGE存储权限,否则还是会读不到文件。
可选优化
如果你的图片尺寸很大,直接加载容易触发OOM(内存溢出),建议加载Bitmap时添加采样压缩逻辑,缩小图片尺寸降低内存占用。
内容的提问来源于stack exchange,提问作者ami
相关产品推荐
相关产品推荐

