Có thể bạn đã quá quen thuộc với các startActivityForResult() khi code các ứng dụng android. Thì gần đây google đã làm mới với Activity Result APIs được giới thiệu trong AndroidX Activity 1.2.0-alpha02
and Fragment 1.3.0-alpha02
. và khuyến nghị chúng ta nên sử dụng nó.
Activity Result APIs cung cấp các thành phần để đăng ký nhận kết quả, khởi chạy và xử lý kết quả sau khi hệ thống gửi về.
Cách cũ:
public void openSomeActivityForResult() { Intent intent = new Intent(this, SomeActivity.class); startActivityForResult(intent, 123); } @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && requestCode == 123) { doSomeOperations(); } }
Cách mới (Kotlin):
val getContent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { val nickName = result.data?.getStringExtra("KEY_NAME") tvUserName.text = nickName } } btnOpenSecondActivity.setOnClickListener { val intent = Intent(this, SecondActivity::class.java) getContent.launch(intent) }
Cách mới này có thể áp dụng cho cả Activity và Fragment.
Ngoài cách phổ thông ở trên thì chúng ta hay cần gọi intent để lấy photo, chụp ảnh, và Permission thì api mới cũng hỗ trợ hết nhé.
StartActivityForResult() RequestMultiplePermissions() RequestPermission() TakePicturePreview() TakePicture() TakeVideo() PickContact() CreateDocument() OpenDocumentTree() OpenMultipleDocuments() OpenDocument() GetMultipleContents() GetContent()
Yêu cầu quyền:
val requestPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestPermission() ) { isGranted: Boolean -> if (isGranted) { } else { } } requestPermissionLauncher.launch(Manifest.permission.BLUETOOTH)
Lấy hình ảnh, content ..:
val getContent = registerForActivityResult(GetContent()) { uri: Uri? -> // Handle the returned Uri } getContent.launch("image/*")
TakePicturePreview :
val takePicture = registerForActivityResult( ActivityResultContracts.TakePicturePreview(), activityResultRegistry ) { bitmap: Bitmap? -> Log.d("takePicture", "bitmap") } //action takePicture.launch(null)
Ngoài ra nếu ứng dụng cần xử lý Lifecycle thì Api mới cũng hỗ trợ để chúng ta quản lý app tốt hơn.
annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.0.0" implementation "androidx.lifecycle:lifecycle-runtime:2.0.0" implementation "androidx.lifecycle:lifecycle-extensions:2.0.0" implementation "androidx.lifecycle:lifecycle-common-java8:2.0.0"
Cách triển khai:
class MyLifecycleObserver(private val registry: ActivityResultRegistry) : DefaultLifecycleObserver { lateinit var getIntent: ActivityResultLauncher<Intent> override fun onCreate(owner: LifecycleOwner) { getIntent = registry.register("KEY_NAME", owner, ActivityResultContracts.StartActivityForResult()) {result -> if (result.resultCode == Activity.RESULT_OK) { val nickName = result.data?.getStringExtra("KEY_NAME") } } } fun startSecondActivity(activity: Activity){ val intent = Intent(activity, SecondActivity::class.java) getIntent.launch(intent) } }
Cách dùng:
lateinit var observer: MyLifecycleObserver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) observer = MyLifecycleObserver(requireActivity().activityResultRegistry) lifecycle.addObserver(observer) //Action observer.startSecondActivity(requireActivity()) }
Tham khảo thêm:
https://developer.android.com/training/basics/intents/result
https://developer.android.com/jetpack/androidx/releases/lifecycle
Demo : Github