Activity Result Api при 2 callback

я пытаюсь из старого OnActivityResult сделать миграцию в новую версию свой код, то есть у меня есть ImageView при клике на него открывается галерея , далее при выборе фото , дальше возникает св-во обрезки Фото. Все это я хочу осуществить с помощью Activity Result Api, я пробовал 2 contracta registr создавать, но в таком случае как быть в setOnclickListener он один не может обрабатывать 2 регистра контракта я вообще не могу догнать , пробовал внутри registr contract , написать эти 2 св-во не выходит как быть??

вот мой код при старом activity Result Deprecated

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { /// неед
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == REQUEST_GALLERY) {
                data?.data.let {
                    if (it != null) {
                        imageUri = it  (доступ к галерее)
                        cropImage(it) }
                }

            } else if (requestCode == UCrop.REQUEST_CROP) {  (обрезает фото и загружает в Imageview)
                val resultUri = data?.let {
                    UCrop.getOutput(it) }
                binding.image.loadUrl(resultUri.toString())
            }
        } else {
            toastMessage(requireContext(), getString(R.string.fail_download_image))
        }
    }

    private fun openGallery() {    /// галлерея
        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        startActivityForResult(intent, REQUEST_GALLERY)

тут внутри контракта пытаюсь 2 callbacka вызвать не выходит

 private val resultContract = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result: ActivityResult? ->
        if (result?.resultCode == Activity.RESULT_OK ) {
            result.data?.data.let {
                if (it != null) {
                    imageUri = it
                    cropImage(it) }
                }

        } else if (result?.resultCode == UCrop.REQUEST_CROP){
            val resultUri = result.data?.let {
                UCrop.getOutput(it)
            }
            binding.image.loadUrl(resultUri.toString())
        }
    }

а тут 2 registr contract

private val resultContractTwo = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result: ActivityResult? ->
        if (result?.resultCode == UCrop.REQUEST_CROP) {
            val resultUri = result.data?.let { UCrop.getOutput(it) }
            binding.image.loadUrl(resultUri.toString())
        }
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        shapeImage()
        setupToolbar()
        setupListeners()
    }
  private fun setupListeners() {
        binding.image.setOnClickListener {
            val intent = Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
            resultContract.launch(intent)  // тут 2 callback они двоя не вызываться как быть?
            resultContractTwo.launch(intent)
            binding.imageIcon.visibility = View.GONE
        }
    }

Ответы (1 шт):

Автор решения: woesss

Основные моменты:

  • на каждый requestCode нужно зарегистрировать launcher с колбеком
  • каждый startActivityForResult() заменяем на launch() соответствующего launcher
  • из onActivityResult берём ветки requestCode и переносим их в соответствующие колбеки - то есть не в один колбек всё запихиваем, а каждый requestCode обрабатывается своим колбеком
private val imageCropLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result: ActivityResult? ->
        if (result?.resultCode == Activity.RESULT_OK ) {
            val resultUri = result.data?.let {
                UCrop.getOutput(it)
            }
            binding.image.loadUrl(resultUri.toString())
        } else {
            toastMessage(requireContext(), getString(R.string.fail_download_image))
        }
    }

private val imagePickLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result: ActivityResult? ->
        if (resultCode == Activity.RESULT_OK) {
            data?.data.let {
                if (it != null) {
                    imageUri = it  (доступ к галерее)
                    cropImage(it) }
            }
        } else {
            toastMessage(requireContext(), getString(R.string.fail_download_image))
        }
    }

Лончеры с колбеками зарегистрированы - осталось вызвать, меняем везде:
startActivityForResult(intent, REQUEST_GALLERY) на imagePickLauncher.launch(intent)
startActivityForResult(intent, UCrop.REQUEST_CROP) на imageCropLauncher.launch(intent)

→ Ссылка