I Can't send request code with RegisterActivityForResult

Viewed 111

I have multiple ImageViews in a fragment in my application. I want the user to select an image for each imageView. The question is, I don't know for which ImageView the user selected an image.

I thought that if I add a request code, I can fix this problem according to the code received.

I can't add request code to the method I'm using for the user to select an image.

I do a permission check first when the button is pressed , I open the gallery if it's permission granted. :

// First ImageView onClick 
bind.addQuestionImage.setOnClickListener{
        if (!checkPermission()) 
  requestSinglePermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
        else openGallery()
    }
// Second ImageView onClick 
bind.addAnswerImage.setOnClickListener{
        if (!checkPermission()) 
    requestSinglePermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
        else openGallery()
    }

My Permission request method :

   private fun checkPermission() = ContextCompat.checkSelfPermission(
     requireContext(),
     Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED 
    
   

The method where I listen to the response to the request :

   private val requestSinglePermissionLauncher = 
   registerForActivityResult(
   ActivityResultContracts.RequestPermission()) { isGranted ->
   
    if (isGranted) {
        toaster("Permission Granted.")
    } else {
        toaster("Permission Denied.")
    }
  }

I open the gallery if the user has permission :

  private fun openGallery(){
    val galleryIntent = Intent(Intent.ACTION_PICK, 
  MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
     getContent.launch(galleryIntent)
  }

I get the content in this method :

  // get content
private val getContent = 
registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
   val myUri : Uri? = it.data?.data

   // Which ImageView is this incoming uri ?

}

How can I solve this problem ? Or is there a better method ?

2 Answers

If you have two ImageView, you have to create two registerForActivityResult variables because there is no request code

// First ImageView onClick 
bind.addQuestionImage.setOnClickListener{
        if (!checkPermission()) 
  firstPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
        else openGallery()
    }
// Second ImageView onClick 
bind.addAnswerImage.setOnClickListener{
        if (!checkPermission()) 
    secondPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
        else openGallery()
    }

And

private val firstPermissionLauncher = 
   registerForActivityResult(
   ActivityResultContracts.RequestPermission()) { isGranted ->
   
    if (isGranted) {
        toaster("Permission Granted.")
    } else {
        toaster("Permission Denied.")
    }
  }
private val secondPermissionLauncher = 
   registerForActivityResult(
   ActivityResultContracts.RequestPermission()) { isGranted ->
   
    if (isGranted) {
        toaster("Permission Granted.")
    } else {
        toaster("Permission Denied.")
    }
  }

You can add the data you require to the Intent, like so:

  private fun openGallery(source: String){
      val galleryIntent = Intent(Intent.ACTION_PICK, 
      MediaStore.Images.Media.EXTERNAL_CONTENT_URI).apply{
          putExtra(IMAGE_VIEW_SOURCE, source)
      }
      getContent.launch(galleryIntent)
  }

and then read it on your response:

private val getContent = 
registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
   val intent : Intent? = it.data
   val myUri : Uri? = intent?.data

   val source = intent?.getStringExtra(IMAGE_VIEW_SOURCE)

   source?.let{
      if(it == ANSWER_BUTTON){ 
          //.. do stuff
      } 
      else if(it == QUESTION_BUTTON) {
          //do other stuff
      }
   }

}

and your calling code:

// First ImageView onClick 
bind.addQuestionImage.setOnClickListener{
        if (!checkPermission()) 
  requestSinglePermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
        else openGallery(QUESTION_BUTTON)
    }
// Second ImageView onClick 
bind.addAnswerImage.setOnClickListener{
        if (!checkPermission()) 
    requestSinglePermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
        else openGallery(ANSWER_BUTTON)
    }

Of course QUESTION_BUTTON, ANSWER_BUTTON and IMAGE_VIEW_SOURCE would be constants you define

Related