SetImageUri无法显示图片:真机加载本地图片失败但模拟器正常
解决Android真机无法通过路径加载ImageView图片的问题
这个问题我之前也碰到过!核心原因是Android 7.0(API 24)及以上版本对本地文件的file:// Uri访问做了严格限制,直接使用Uri.fromFile()会触发FileUriExposedException(你可以去真机的日志里找找这个报错),而模拟器要么系统版本较低,要么没有严格校验这个规则,所以能正常运行。结合你的代码和路径,给你一套完整的解决方案:
1. 配置FileProvider
首先在AndroidManifest.xml的<application>标签内添加FileProvider的配置,它是Android官方提供的安全共享文件的组件:
<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>
2. 创建文件路径配置文件
在res/xml目录下新建file_paths.xml文件(如果没有xml目录就手动创建),用来指定允许共享的文件路径,你的图片在外部存储根目录下的imagesWarranty文件夹,配置如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 对应外部存储根目录,path="."表示允许访问根目录下的所有文件/文件夹 --> <external-path name="external_files" path="." /> </paths>
3. 修改代码适配FileProvider
把原来直接生成file:// Uri的代码替换成FileProvider生成的安全Uri,同时适配低版本系统:
String imgPath = getIntent().getExtras().getString("imgPath"); System.out.println(imgPath); if(!imgPath.equals("?")) { File img_file = new File(imgPath); ImageView imgView = findViewById(R.id.show_image_war); Uri imageUri; // 区分Android版本处理Uri if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 高版本用FileProvider生成安全Uri imageUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", img_file); // 授予应用临时读取该Uri的权限 grantUriPermission(getPackageName(), imageUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { // 低版本直接使用Uri.fromFile imageUri = Uri.fromFile(img_file); } imgView.setImageURI(imageUri); }
额外注意事项
- 权限检查:确保你的应用已经申请了对应版本的存储权限:
- Android 13及以上:需要申请
READ_MEDIA_IMAGES权限 - Android 6.0到12:需要申请
READ_EXTERNAL_STORAGE权限,并且要在运行时动态申请
- Android 13及以上:需要申请
- 文件存在性:再次确认真机上
/storage/emulated/0/imagesWarranty/img_MyWarranty_ID1.jpg这个文件确实存在,没有被删除或者路径拼写错误
内容的提问来源于stack exchange,提问作者Jochem
相关产品推荐
相关产品推荐

