1

Despite getting the necessary access to the file in Android, when I select a photo from the gallery in Android 11 and above, Android shows the message access denied.

I just select the image and receive it as a bitmap.

I try thease

1 ...
Manifest permissions:

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="29" />

Select image from gallery:

public  void selectImageFromGallery(ImageView view) {
        setResourceImg(view);
        checkListener();

        if (tempFileFromSource == null) {
            try {
                tempFileFromSource = File.createTempFile("choose", "png", mContext.getExternalCacheDir());
                tempUriFromSource = Uri.fromFile(tempFileFromSource);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
        if (fragment == null) {
            mContext.startActivityForResult(intent, REQUEST_PICTURE_FROM_GALLERY);
        } else {
            fragment.startActivityForResult(intent, REQUEST_PICTURE_FROM_GALLERY);
        }
    }

On Activity Result:

 public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if ((requestCode == REQUEST_PICTURE_FROM_GALLERY) && (resultCode == Activity.RESULT_OK)) {

            Log.d(TAG, "Image selected from gallery");
            imageActionListener.onImageSelectedFromGallery(data.getData(), tempFileFromSource);

        } else if ((requestCode == REQUEST_PICTURE_FROM_CAMERA) && (resultCode == Activity.RESULT_OK)) {

            Log.d(TAG, "Image selected from camera");
            imageActionListener.onImageTakenFromCamera(tempUriFromSource, tempFileFromSource);

        } else if ((requestCode == REQUEST_CROP_PICTURE) && (resultCode == Activity.RESULT_OK)) {
            Toast.makeText(mContext, "uryyg: "+data.toString(), Toast.LENGTH_SHORT).show();
            Log.d(TAG, "Image returned from crop");
            imageActionListener.onImageCropped(tempUriFromCrop, tempFileFromCrop);
        }
    }

Crop selected image:

public void requestCropImage(Uri uri, int outputX, int outputY, int aspectX, int aspectY) {
        checkListener();

        if (tempFileFromCrop == null) {
            try {
                tempFileFromCrop = File.createTempFile("crop", "png", mContext.getExternalCacheDir());
                tempUriFromCrop = Uri.fromFile(tempFileFromCrop);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // open crop intent when user selects image
        final Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("output", tempUriFromCrop);
        intent.putExtra("outputX", outputX);
        intent.putExtra("outputY", outputY);
        intent.putExtra("aspectX", aspectX);
        intent.putExtra("aspectY", aspectY);
        intent.putExtra("scale", true);
        intent.putExtra("noFaceDetection", true);
        if (fragment == null) {
            mContext.startActivityForResult(intent, REQUEST_CROP_PICTURE);
        } else {
            fragment.startActivityForResult(intent, REQUEST_CROP_PICTURE);
        }
        //Toast.makeText(mContext, "uri3: "+uri.toString(), Toast.LENGTH_SHORT).show();
    }

And we return the uri of the cropped image in the cache to this method:

  @Override
public void onImageCropped(Uri uri, File imageFile) {
    try {
        Uri selectedImage = uri;
        String[] filePathColumn = { MediaStore.Images.Media.DATA };
        Cursor cursor = getContext().getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);
        cursor.moveToFirst();
        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        cursor.close();
        
        // getting bitmap from uri
        //Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), uri);
        Bitmap bitmap = BitmapFactory.decodeFile(picturePath);
        

    } catch (Exception e) {
        e.printStackTrace();

    }
}
mohammad
  • 35
  • 5
  • You cannot select from gallery in Android. Please just tell which ACTION_... you used. No ... not tell.. post your code. And you will never get a bitmap. You will always get a content scheme uri. – blackapps Feb 05 '23 at 15:31
  • Thank you for your explanation I added the image selection codes – mohammad Feb 05 '23 at 17:17
  • Do you know how I can choose the image? I want to upload to api. – mohammad Feb 05 '23 at 17:20
  • Android will not produce a message access denied when using Intent.ACTION_PICK. Please rewrite your post to tell which statement does. And you still tell that you receive a bitmap then. Which is impossible. Please rewrite your post. – blackapps Feb 05 '23 at 17:24
  • `I added the image selection codes` ?? You posted much more then that. But you did not tell what all that code should do. Please rewrite your post. First tell what all that code should do. – blackapps Feb 05 '23 at 17:27
  • Show logcat error – DiLDoST Feb 06 '23 at 22:48

1 Answers1

1

You will need to use intent with an action set to Intent.ACTION_GET_CONTENT and set the type of this intent to match all the image files i.e. "image/*". If you want that user will able to select only specific image file formats like png or jpeg then use something like "image/png" or "image/jpeg". The code below describes a fully working example that is tested on Android 12L.

Create intent like this

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
pickerActivityResultLauncher.launch(Intent.createChooser(intent, "Select a photo"));

Using the AndroidX activity result register

private ActivityResultLauncher<Intent> pickerActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
    if(result.getResultCode() == RESULT_OK) {
        // This is the URI for the selected photo from the user.
        Uri photoUri = result.getData().getData();
        // Set URI to the image view to display the image.
        imageView.setImageURI(photoUri);
    } else {
        // Handle the no-image selection case.
    }
});

If you want to use the old method (which has no guarantee that it works on every device) then you can use

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select a photo"), REQUEST_PICTURE_FROM_GALLERY)
Shagun Verma
  • 163
  • 1
  • 9