Android Java:ImageView无法从手机相册加载图片问题求助
Hey there! Let's dig into why your image from the phone album isn't showing up in your ImageView. Even with Manifest permissions set up, there are several common gotchas that could be causing this issue. Let's walk through each possible fix step by step:
1. Don't Forget Runtime Permissions (Android 6.0+)
Manifest permissions alone aren't enough for API level 23 and above. You need to request storage permissions at runtime before accessing the album. Here's how to implement this:
private static final int REQUEST_STORAGE_PERMISSION = 100; // Check and request permission when the add button is clicked private void checkStoragePermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_STORAGE_PERMISSION); } else { // Permission is granted, open the album openAlbum(); } } // Handle permission request result @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_STORAGE_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { openAlbum(); } else { // Show a toast if permission is denied Toast.makeText(this, "Storage permission is required to access images", Toast.LENGTH_SHORT).show(); } } }
2. Fix the Album Intent & Uri Handling
Make sure your intent to open the album is correctly configured, and you're processing the returned Uri properly (especially for Android 10+ with scoped storage):
Correct Album Intent
private static final int PICK_IMAGE_REQUEST = 200; private void openAlbum() { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent.setType("image/*"); startActivityForResult(intent, PICK_IMAGE_REQUEST); }
Handle the Selected Image (Old onActivityResult Method)
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null) { Uri imageUri = data.getData(); // Load the image correctly (avoid direct setImageURI for reliability) loadImageIntoImageView(imageUri); } } private void loadImageIntoImageView(Uri imageUri) { try { ContentResolver contentResolver = getContentResolver(); InputStream inputStream = contentResolver.openInputStream(imageUri); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); yourImageView.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(this, "Failed to load image", Toast.LENGTH_SHORT).show(); } }
For AndroidX (Use ActivityResultContracts Instead)
If you're using AndroidX, the recommended approach is to use ActivityResultContracts instead of the deprecated onActivityResult:
private ActivityResultLauncher<Intent> pickImageLauncher; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize the launcher pickImageLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == RESULT_OK && result.getData() != null) { Uri imageUri = result.getData().getData(); loadImageIntoImageView(imageUri); } }); } // Call this when permission is granted private void openAlbum() { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent.setType("image/*"); pickImageLauncher.launch(intent); }
3. Scoped Storage Adaptation (Android 10+)
On Android 10 (API 29) and above, scoped storage blocks direct access to file paths. Using ContentResolver (as shown above) or a third-party image loading library like Glide is far more reliable:
Using Glide (Simpler & More Robust)
Add Glide to your build.gradle (Module level):
dependencies { implementation 'com.github.bumptech.glide:glide:4.15.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1' }
Then load the image with one line:
Glide.with(this) .load(imageUri) .into(yourImageView);
4. Check ImageView Configuration
Double-check your ImageView's layout properties:
- Ensure it has a defined width and height (not
wrap_contentif the image is large, or useadjustViewBounds="true"). - Set a suitable
scaleType(e.g.,android:scaleType="centerCrop"orfitCenter) to make the image visible.
Start by verifying runtime permissions first, then confirm your intent and Uri handling. If all else fails, using Glide will likely resolve any edge cases with Uri decoding or scoped storage.
内容的提问来源于stack exchange,提问作者Shivam Gupta

