Android拍照并设置至ImageView时的路径异常问题
解决拍照后FileProvider URI加载Bitmap到ImageView的路径问题
看起来你在拍照后加载图片到ImageView时踩了FileProvider的路径坑,核心问题是真实文件路径和FileProvider生成的Content URI不能直接混用,导致Bitmap加载失败。我帮你拆解问题并给出具体解法:
先搞懂两个路径的区别
- 你通过
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);拿到的是设备真实的文件系统路径:/storage/emulated/0/Android/data/disco.unimib.it.polapp/files/Pictures - 而
FileProvider.getUriForFile()生成的是安全的Content URI,用于跨应用(比如相机APP)访问你的应用私有文件,格式是:
这个URI不是真实文件路径,直接用它去创建content://com.example.android.fileprovider/images/Android/data/disco.unimib.it.polapp/files/Pictures/JPEG_20180201_120724_1953425230.jpgFile对象或者调用BitmapFactory.decodeFile()肯定会报错。
正确加载Bitmap到ImageView的方法
不要尝试把Content URI转成真实路径(Android 10+还会有存储权限限制),直接用ContentResolver打开输入流加载Bitmap:
// 假设photoUri是你拿到的FileProvider生成的Content URI try { InputStream inputStream = getContentResolver().openInputStream(photoUri); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); // 将Bitmap设置到ImageView yourImageView.setImageBitmap(bitmap); // 记得关闭流 if (inputStream != null) { inputStream.close(); } } catch (IOException e) { e.printStackTrace(); // 加载失败时的 fallback 处理,比如显示默认图片 yourImageView.setImageResource(R.drawable.default_image); }
检查FileProvider配置是否正确
你的FileProvider authority是com.example.android.fileprovider,要确保res/xml/file_paths.xml的配置和存储目录对应,目前看你的URI格式是对的,配置应该类似这样:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- name对应URI里的"images"部分,path对应Pictures目录 --> <external-files-path name="images" path="Pictures/" /> </paths>
这个配置是正确的,不用修改。
(可选)如果必须获取真实文件路径(不推荐Android 10+)
如果你因为特殊需求一定要拿到真实文件路径,可以通过ContentResolver查询,但注意Android 10及以上版本限制了直接访问外部存储,这个方法可能失效:
public String getRealPathFromUri(Context context, Uri uri) { String filePath = ""; if (DocumentsContract.isDocumentUri(context, uri)) { String docId = DocumentsContract.getDocumentId(uri); if ("com.android.externalstorage.documents".equals(uri.getAuthority())) { String[] split = docId.split(":"); String type = split[0]; if ("primary".equalsIgnoreCase(type)) { filePath = Environment.getExternalStorageDirectory() + "/" + split[1]; } } } else if ("content".equalsIgnoreCase(uri.getScheme())) { String[] projection = {MediaStore.Images.Media.DATA}; Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null); if (cursor != null) { int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); filePath = cursor.getString(columnIndex); cursor.close(); } } return filePath; }
再次强调:Android 10及以上推荐直接使用Content URI操作文件,避免权限问题和适配麻烦。
内容的提问来源于stack exchange,提问作者omar ghetti
相关产品推荐
相关产品推荐

