你能帮我吗?,吗?我是一个用kotlin开发Android的新手,还在学习中。
这是我在片段上的代码,
......
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()
}
和thisonActivityResultfrom parentActivity对片段
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
for (fragment in supportFragmentManager.fragments) {
fragment.onActivityResult(requestCode, resultCode, data)
}
}
And thisOnActivityResult从片段
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)
......
谢谢你回答我的问题,
尝试为"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(意图)
对于相机,像这样调用它:
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.putExtra(MediaStore.EXTRA_OUTPUT, it)
startForResultToLoadImage.launch(intent)
我相信你应该:
- 在函数开始时打印日志,打印所有参数,以便始终知道代码将如何分支。比如
Log.i("onActivityResult: ", "requestCode=" + requestCode + “, resultCode=” + resultCode + “, data=” + data);
- 在检查结果代码之前检查请求代码,因为不同的请求可能有不同的结果。
- 你假设结果将是
Activity.RESULT_CANCELED
或Activity.RESULT_OK
,但结果代码可能是一个自定义的结果,所以请添加另一个else
分支后,你检查Activity.RESULT_CANCELED
,以确保你覆盖所有的结果。如果你的活动继承自AppCompatActivity
,不要从Activity.onActivityResult
调用Fragment.onActivityResult
。活动自动将结果转发到片段(它甚至允许请求代码在不混合片段的情况下跨片段复制)。
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,但这是你的代码风格,所以我不会判断:)