Android Kotlin调用BitmapFactory.decodeFile加载相册选中图片显示空白问题
问题排查及解决方案
核心问题原因
- 权限适配问题:Android 13(API 33及以上)系统中,
READ_EXTERNAL_STORAGE权限已被废弃,替换为图片专属的READ_MEDIA_IMAGES权限,你的代码没有适配高版本系统权限规则,会导致无法获取图片访问权限。 - 路径获取方式过时:通过
MediaStore.Images.Media.DATA查询本地绝对路径的方式从Android 10(API 29)开始就不支持分区存储规则,拿到的路径属于无效路径,BitmapFactory.decodeFile会返回null,所以ImageView显示空白。
修复步骤
1. 修改AndroidManifest.xml权限配置
添加对应权限声明:
<!-- 安卓12及以下版本权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- 安卓13及以上版本权限 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
2. 修改权限校验逻辑
适配不同系统版本的权限申请:
private fun checkPermission() { val targetPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { android.Manifest.permission.READ_MEDIA_IMAGES } else { android.Manifest.permission.READ_EXTERNAL_STORAGE } if (Build.VERSION.SDK_INT >= 23) { if (ActivityCompat.checkSelfPermission(this, targetPermission) != PackageManager.PERMISSION_GRANTED) { requestPermissions(arrayOf(targetPermission), READ_IMAGE) return } } loadImage() }
3. 修改图片加载逻辑
不需要查询本地路径,直接用返回的Uri加载图片即可:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == PICK_IMAGE_CODE && data != null && resultCode == RESULT_OK) { val selectedImageUri = data.data // 方式1:直接用Uri设置给ImageView binding.imageView.setImageURI(selectedImageUri) // 方式2:用Picasso加载Uri(如果需要裁剪、占位图等效果推荐用这个) // Picasso.get().load(selectedImageUri).fit().into(binding.imageView) } }
额外注意点
- 你的代码中导入了
ActivityStudentClassroomBinding但实际使用的是ActivityMainBinding,请确认和你设置的布局文件匹配,避免绑定错误。 - 如果加载的图片过大,直接设置可能导致OOM,建议用Glide/Picasso等图片加载框架自动处理采样压缩。
内容的提问来源于stack exchange,提问作者Phearum
相关产品推荐
相关产品推荐

