在学习《第一行代码》第九节的内容时,有一部分涉及打开相机或者相册,获取图片,需要唤醒对应应用程序,并根据回调的数据对当前活动的imageView进行操作。
这部分所使用的的startActivityForResult方法目前已被废弃。替换成了Activity Result,经过一番研究,大致了解了对于书中两个操作的替换方法。
首先对于打开相机,书中的代码是
takePhotoBtn.setOnClickListener {
// 创建File对象,用于存储拍照后的图片
outputImage = File(externalCacheDir, "output_image.jpg")
if (outputImage.exists()) {
outputImage.delete()
}
outputImage.createNewFile()
imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {FileProvider.getUriForFile(this, "com.example.cameraalbumtest.
fileprovider", outputImage)
} else {
Uri.fromFile(outputImage)
}
// 启动相机程序
val intent = Intent("android.media.action.IMAGE_CAPTURE")
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
startActivityForResult(intent, takePhoto)
}
重写了onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
takePhoto -> {
if (resultCode == Activity.RESULT_OK) {
// 将拍摄的照片显示出来
val bitmap = BitmapFactory.decodeStream(contentResolver.
openInputStream(imageUri))
imageView.setImageBitmap(rotateIfRequired(bitmap))
}
}
}
}
如果使用Activity Result的话,首先编写对应的启动器
// 拍照回调
private val getPhotoLauncher =
registerForActivityResult(ActivityResultContracts.TakePicturePreview()) { bitmap ->
bitmap?.let {
val imageView = findViewById<ImageView>(R.id.imageView)
imageView.setImageBitmap(it)
}
}
这里这个判断返回的数据是否为空,为空说明用户没有拍照,不进行操作,不为空执行操作。拍照返回使用的方法是TakePicturePreview。
对应的按钮点击事件只需一行代码
getPhotoLauncher.launch(null)
同样的,打开相册的启动器代码
// 相册回调
private val getPictureLauncher =
registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
uri?.let {
val imageView = findViewById<ImageView>(R.id.imageView)
imageView.setImageBitmap(getBitmapFromUri(it))
}
}
对应打开相册按钮的点击事件
getPictureLauncher.launch(arrayOf("image/*"))
总的来说,新的方法对于这些常用的事件进行了优化,大大减少了代码量,对于启动器中需要填入的参数,以及启动器返回的对象类型,可以通过查看源码来了解。例如打开相机那部分的源码
public static class TakePicturePreview extends ActivityResultContract<Void, Bitmap>
第一个参数是启动器填入参数,第二个是返回对象类型。
参考链接:startActivityForResult被标记为弃用后,如何优雅的启动Activity?
Activity Result API详解,是时候放弃startActivityForResult了