部分Android设备从相册选图时图片显示空白/红色的问题求助
Android部分设备相册选图后显示空白/红色的问题排查与解决
选取的图片在多数设备上正常显示,但部分Android设备从相册选图时,图片会显示空白或红色。当前实现代码如下:
图片选取代码
Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
图片显示代码
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICK_IMAGE && resultCode == RESULT_OK) { Uri selectedImageURI = data.getData(); try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { bitmap= ImageDecoder.decodeBitmap(ImageDecoder.createSource(mActivity.getContentResolver(), selectedImageURI)); } else { bitmap= MediaStore.Images.Media.getBitmap(mActivity.getContentResolver(), selectedImageURI); } }catch (Exception e){ e.printStackTrace(); } Glide.with(activity).load(imageUrl) .thumbnail(Glide.with(activity).load(R.drawable.loading)) .error(R.drawable.loading) .override(bitmap.getWidth(),bitmap.getHeight()) .into(imageView); } }
问题原因分析
- Glide加载数据源错误:代码中调用
Glide.load(imageUrl),但imageUrl未定义,实际应加载选中的selectedImageURI或解码后的bitmap,这是导致加载失败的核心原因。 - 手动解码Bitmap的兼容性问题:
MediaStore.Images.Media.getBitmap已被废弃,且手动解码易受设备图片格式(如WebP、HEIC)、内存限制影响,解码失败后bitmap为空,调用bitmap.getWidth()会触发空指针,进而Glide显示错误图。 - 相册URI兼容性问题:部分设备相册返回的URI存在权限限制或格式不标准,手动解码时无法正确读取图片数据。
- 异常处理不完善:仅打印异常未做后续处理,
bitmap为空时仍执行Glide加载逻辑,引发连锁错误。
解决方案
1. 修正Glide加载逻辑(推荐)
直接用选中的Uri让Glide处理加载,Glide会自动兼容版本、适配格式并优化内存,无需手动解码Bitmap:
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICK_IMAGE && resultCode == RESULT_OK && data != null) { Uri selectedImageURI = data.getData(); if (selectedImageURI == null) { imageView.setImageResource(R.drawable.loading); return; } Glide.with(activity) .load(selectedImageURI) .thumbnail(Glide.with(activity).load(R.drawable.loading)) .error(R.drawable.loading) .into(imageView); } else { imageView.setImageResource(R.drawable.loading); } }
2. 优化图片选取Intent
添加Intent.CATEGORY_OPENABLE确保返回可读取的标准URI,避免部分相册返回无效地址:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
3. 完善权限处理
- Android 10(API 29)及以上:无需申请
READ_EXTERNAL_STORAGE权限,通过ContentResolver即可访问相册图片。 - Android 9(API 28)及以下:需在Manifest中声明
READ_EXTERNAL_STORAGE权限,并在运行时动态申请。
4. 手动解码场景的兼容处理(若业务必须)
如果需要手动处理Bitmap,需完善空值判断和内存优化:
try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { ImageDecoder.Source source = ImageDecoder.createSource(mActivity.getContentResolver(), selectedImageURI); bitmap = ImageDecoder.decodeBitmap(source, (decoder, info, source1) -> { decoder.setTargetSampleSize(2); // 设置采样率,避免内存溢出 }); } else { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; // 降低图片分辨率,节省内存 bitmap = MediaStore.Images.Media.getBitmap(mActivity.getContentResolver(), selectedImageURI); } } catch (Exception e) { e.printStackTrace(); bitmap = null; } if (bitmap != null) { Glide.with(activity) .load(bitmap) .thumbnail(Glide.with(activity).load(R.drawable.loading)) .error(R.drawable.loading) .into(imageView); } else { imageView.setImageResource(R.drawable.loading); }
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

