【问题标题】:Method from OnActivityResult Fragment executed, but nothing happend in ViewOnActivityResult Fragment 中的方法已执行,但 View 中没有发生任何事情
【发布时间】:2021-06-01 20:26:00
【问题描述】:

你能帮帮我吗? 我是开发 Android 使用 kotlin 的新手,还在学习中。,

这是我在片段上的代码。,

......
  private fun takePhotoFromCamera() {

        Dexter.withActivity(requireActivity())
            .withPermissions(
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA
            )
            .withListener(object : MultiplePermissionsListener {
                override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
                    // Here after all the permission are granted launch the CAMERA to capture an image.
                    if (report!!.areAllPermissionsGranted()) {
                        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                        intent.putExtra("Document", 2)
                        startActivityForResult(intent, CAMERA)
                    }
                }

                override fun onPermissionRationaleShouldBeShown(
                    permissions: MutableList<PermissionRequest>?,
                    token: PermissionToken?,
                ) {
                    showRationalDialogForPermissions()
                }
            }).onSameThread()
            .check()
    }

    private fun choosePhotoFromGallery() {
        Dexter.withActivity(activity)
            .withPermissions(
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
            .withListener(object : MultiplePermissionsListener {
                override fun onPermissionsChecked(report: MultiplePermissionsReport?) {

                    // Here after all the permission are granted launch the gallery to select and image.
                    if (report!!.areAllPermissionsGranted()) {

                        val galleryIntent = Intent(
                            Intent.ACTION_PICK,
                            MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                        )
                     galleryIntent.putExtra("Document", 2)
                     startActivityForResult(galleryIntent, GALLERY)
                    }
                }

                override fun onPermissionRationaleShouldBeShown(
                    permissions: MutableList<PermissionRequest>?,
                    token: PermissionToken?,
                ) {
                    showRationalDialogForPermissions()
                }
            }).onSameThread()
            .check()
    }

这个 onActivityResult 来自 Fragment

的父 Activity
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        for (fragment in supportFragmentManager.fragments) {
            fragment.onActivityResult(requestCode, resultCode, data)
        }
    }

这个OnActivityResult来自Fragment

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == GALLERY) {
            if (data != null) {
                val contentURI = data.data
                try {
                    // Here this is used to get an bitmap from URI
                    @Suppress("DEPRECATION")
                    val selectedImageBitmap =
                        MediaStore.Images.Media.getBitmap(requireActivity().contentResolver,
                            contentURI)

                    // TODO (Step 3 : Saving an image which is selected from GALLERY. And printed the path in logcat.)
                    // START
                    val saveImageToInternalStorage =
                        saveImageToInternalStorage(selectedImageBitmap)
                    Log.i("Saved Image : ", "Path :: $saveImageToInternalStorage")
                    // END
                    binding.btnNpwpCaptureAgain.visibility=View.VISIBLE
                    binding.ivPvNpwp.foreground.clearColorFilter()
                    binding.cvNpwp.visibility=View.GONE
                    binding.btnCaptureNpwp.visibility=View.GONE
                    binding.ivNpwpPreview.setImageBitmap(selectedImageBitmap) // Set the selected image from GALLERY to imageView.
                } catch (e: IOException) {
                    e.printStackTrace()
                    Toast.makeText(requireActivity(), "Failed!", Toast.LENGTH_SHORT).show()
                }
            }
        } else if (requestCode == CAMERA) {

            val thumbnail: Bitmap = data!!.extras!!.get("data") as Bitmap // Bitmap from camera

            // TODO (Step 4 : Saving an image which is selected from CAMERA. And printed the path in logcat.)
            // START
            val saveImageToInternalStorage =
                saveImageToInternalStorage(thumbnail)
            Log.i("Saved Image : ", "Path :: $saveImageToInternalStorage")
            //binding.btnCaptureKtp.text = getString(R.string.regist_step_2_KTP_retake).toString()
            // END
            binding.btnNpwpCaptureAgain.visibility=View.VISIBLE
            binding.ivPvNpwp.foreground.clearColorFilter()
            binding.btnCaptureNpwp.visibility=View.GONE
            binding.cvNpwp.visibility=View.GONE
            binding.ivNpwpPreview.setImageBitmap(thumbnail) // Set to the imageView.
        }
    } else if (resultCode == Activity.RESULT_CANCELED) {
        Log.e("Cancelled", "Cancelled")
    }
    //
}

我的问题是为什么这个块被执行了,但是什么也没发生??

 ....
binding.btnNpwpCaptureAgain.visibility=View.VISIBLE
        binding.ivPvNpwp.foreground.clearColorFilter()
        binding.btnCaptureNpwp.visibility=View.GONE
        binding.cvNpwp.visibility=View.GONE
        binding.ivNpwpPreview.setImageBitmap(thumbnail)
......

感谢您回答我的问题。,

【问题讨论】:

    标签: android kotlin android-fragments android-camera imagepicker


    【解决方案1】:

    尝试对“contentURI”进行另一个空检查。喜欢:-

    if(contentURI != null){
    
            try {
                // Here this is used to get an bitmap from URI
                @Suppress("DEPRECATION")
                val selectedImageBitmap =
                    MediaStore.Images.Media.getBitmap(requireActivity().contentResolver,
                        contentURI)
    
                // TODO (Step 3 : Saving an image which is selected from GALLERY. And printed the path in logcat.)
                // START
                val saveImageToInternalStorage =
                    saveImageToInternalStorage(selectedImageBitmap)
                Log.i("Saved Image : ", "Path :: $saveImageToInternalStorage")
                // END
                binding.btnNpwpCaptureAgain.visibility=View.VISIBLE
                binding.ivPvNpwp.foreground.clearColorFilter()
                binding.cvNpwp.visibility=View.GONE
                binding.btnCaptureNpwp.visibility=View.GONE
                binding.ivNpwpPreview.setImageBitmap(selectedImageBitmap) // Set the selected image from GALLERY to imageView.
            } catch (e: IOException) {
                e.printStackTrace()
                Toast.makeText(requireActivity(), "Failed!", Toast.LENGTH_SHORT).show()
            }
        }
    

    由于不推荐使用 onActivityResult() 方法,最好使用registerForActivityResult()。如下:

        private val startForResultToLoadImage = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK) {
            try {
                val selectedImage: Uri? = result.data?.data
                if (selectedImage != null){
                     // From Gallery
                     // Use uri to get the image
    
                }else{
                      // From Camera code goes here.
                      // Get the bitmap directly from camera
                    val bitmap: Bitmap = result.data?.extras?.get("data") Bitmap
                }
            } catch (error: Exception) {
                Log.d("log==>>", "Error : ${error.localizedMessage}")
            }
        }
    }
    

    对于画廊,可以这样称呼:

    val intent = Intent (Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI) 
    

    startForResultToLoadImage.launch(intent)

    对于相机,可以这样称呼:

    val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                intent.putExtra(MediaStore.EXTRA_OUTPUT, it)
    startForResultToLoadImage.launch(intent)
    

    【讨论】:

      【解决方案2】:

      我认为你应该:

      1. 在函数开始时打印日志并打印所有参数以始终知道代码将如何分支。类似Log.i("onActivityResult: ", "requestCode=" + requestCode + “, resultCode=” + resultCode + “, data=” + data);
      2. 在检查结果代码之前检查您的请求代码,因为不同的请求可能有不同的结果。
      3. 您假设结果为Activity.RESULT_CANCELEDActivity.RESULT_OK,但结果代码可能是自定义结果,因此请在检查Activity.RESULT_CANCELED 后添加另一个else 分支以确保您覆盖所有结果。
      4. 如果您的活动继承自 AppCompatActivity,请不要从 Activity.onActivityResult 调用 Fragment.onActivityResult。 Activity 会自动将结果转发到 Fragment(它甚至允许请求跨 Fragment 的代码重复,而无需混合 Fragment)。

      onActivityResult的结构主要应该是:

      if (requestCode == REQUEST_1) {
          if (resultCode == RESULT_1) {
              // Do your thing
          } else if (resultCode == RESULT_2) {
              // Do your thing
          } else if (resultCode == RESULT_LAST) {
              // Do your thing
          } else {
              // Important!! Expect the unexpected
          }
      } else if (requestCode == REQUEST_2) {
          ...
      } else if (requestCode == REQUEST_LAST) {
          ...
      }
      

      我会使用 switch-case 而不是 if-else 但这是你的代码风格,所以我不会评判:)

      【讨论】:

        猜你喜欢
        • 2016-10-22
        • 2021-10-12
        • 1970-01-01
        • 1970-01-01
        • 2021-01-18
        • 1970-01-01
        • 2021-05-13
        • 1970-01-01
        • 2019-12-07
        相关资源
        最近更新 更多