OnActivityResult Fragment 中的方法已执行,但 View 中没有发生任何事情
Posted
技术标签:
【中文标题】OnActivityResult Fragment 中的方法已执行,但 View 中没有发生任何事情【英文标题】:Method from OnActivityResult Fragment executed, but nothing happend in 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
的父 Activityoverride 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)
......
感谢您回答我的问题。,
【问题讨论】:
【参考方案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】:我认为你应该:
-
在函数开始时打印日志并打印所有参数以始终知道代码将如何分支。类似
Log.i("onActivityResult: ", "requestCode=" + requestCode + “, resultCode=” + resultCode + “, data=” + data);
在检查结果代码之前检查您的请求代码,因为不同的请求可能有不同的结果。
您假设结果为Activity.RESULT_CANCELED
或Activity.RESULT_OK
,但结果代码可能是自定义结果,因此请在检查Activity.RESULT_CANCELED
后添加另一个else
分支以确保您覆盖所有结果。
如果您的活动继承自 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 但这是你的代码风格,所以我不会评判:)
【讨论】:
以上是关于OnActivityResult Fragment 中的方法已执行,但 View 中没有发生任何事情的主要内容,如果未能解决你的问题,请参考以下文章
fragment之间的信息交互——onActivityResult()不经过Activity
关于Fragment的onActivityResult 不执行
当在Fragment中使用startActivityForResult()方法打开一个Activity,但是这个Fragment的onActivityResult方法不执行
fragment里层级套的太深没办法执行onactivityresult怎么办