title: Android Q: Get image from gallery and process it
body: <p>I know it seems like a very basic question, but it's specifically for Android Q.</p>
  
  <p>I just want to get an image from Gallery and compress it and send to the server. But because of the Android Q's Scoped Storage, it's harder than I thought. I'll first explain what I did with code:</p>
  
  <p>First I send out the intent to pick the image.</p>
  
  <pre><code>fun openGallery(fragment: Fragment){
      val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
      intent.type = "*/*"
      val mimeTypes = arrayOf("image/*")
      intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
      fragment.startActivityForResult(intent, REQUEST_IMAGE_PICK)
  }
  </code></pre>
  
  <p>It works fine, and I'm able to get the image in the onActivityResult method</p>
  
  <pre><code>override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  
      if (requestCode == REQUEST_IMAGE_PICK &amp;&amp; resultCode == Activity.RESULT_OK &amp;&amp; null != data) {
          val selectedImage = data.data
  
          val source = ImageDecoder.createSource(activity!!.contentResolver, selectedImage)
          val bitmap = ImageDecoder.decodeBitmap(source)
          mBinding.circularProfileImage.setImageBitmap(bitmap)
      }
  }
  </code></pre>
  
  <p>Okay now the question is how can I access this image in File format, so I can further process/compress it.</p>
  
  <p>Following things I've tried:</p>
  
  <pre><code>val mImagePath = getImagePathFromUri(activity!!, selectedImage)
  </code></pre>
  
  <p>This is the path I've got:</p>
  
  <pre><code>/storage/emulated/0/DCIM/Camera/IMG_20191022_152437.jpg
  </code></pre>
  
  <p>I created a file from it, in the following way:</p>
  
  <pre><code>val file = File(mImagePath)
  </code></pre>
  
  <p>And Following is my custom logic to compress and upload image:</p>
  
  <pre><code>val mNewFile = MediaCompressor.compressCapturedImage(activity!!, file, "ProfilePictures")
  uploadProfile(mNewFile)
  </code></pre>
  
  <p>In this custom logic, I have a method to handle sampling and rotation of the image as follows:</p>
  
  <pre><code>fun handleSamplingAndRotationBitmap(context: Context, selectedImage: File, reqWidth: Int, reqHeight: Int): Bitmap {
  
      val mUri = Uri.fromFile(selectedImage)
  
      // First decode with inJustDecodeBounds=true to check dimensions
      val options = BitmapFactory.Options()
      options.inJustDecodeBounds = true
      var imageStream = context.contentResolver.openInputStream(mUri)
      BitmapFactory.decodeStream(imageStream, null, options)
      imageStream!!.close()
  
      // Calculate inSampleSize
      options.inSampleSize =
          calculateInSampleSize(options, reqWidth, reqHeight)
  
      // Decode bitmap with inSampleSize set
      options.inJustDecodeBounds = false
      imageStream = context.contentResolver.openInputStream(mUri)
  
      var img = BitmapFactory.decodeStream(imageStream, null, options)
  
      img = rotateImageIfRequired(context, img!!, mUri)
      return img
  }
  </code></pre>
  
  <p>But when I'm trying to open the stream using <strong>context.contentResolver.openInputStream</strong> 
  I get the following error:</p>
  
  <pre><code>java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20191022_152437.jpg: open failed: EACCES (Permission denied)
  </code></pre>
  
  <p>I know I'm getting this because in Android 10 we don't have the permission to directly access files from external storage.</p>
  
  <p>So, please help me figure this out, how can I use the image from external storage as a file in Android 10.</p>
  
  <p>Note: I've all the required permissions, so that's not the issue</p>