In my app, I am opening a Contact activity to pick a contact using the new Activity Result API like this
registerForActivityResult(ActivityResultContracts.PickContact()) { it ->
viewModel.setContact(it)
}.launch(null)
The Contact activity opens, I can retrieve the contact, all this works just fine. But while in the Contact activity, pressing the back button (either the android back button or the back arrow at the top), instead of closing just the contact activity, it exits my app.
I found fixes online for this issue, but only for the old startActivityForResult
and onActivityResult
APIs. Is there a way I can change the behavior of the back button when opening an activity for result for the new API as well?
Edit: Noticed the behavior both on emulator and on physical device
Adrian kindly provided me with a sample of his project. This answer is based on the results of debugging the sample project.
There is one "invisible" issue in the code that is caused as the result of interoperability of Java and Kotlin languages. When we call Java function from Kotlin code we get return type of T!
- where T!
means "T or T?".
Java allows returning null
values as we wish. In order for Kotlin to know that the value is explicitly optional Java programmers must use @Nullable
annotation. Kotlin will pick it up and return T?
instead.
Since registerForActivityResult
is Java function we get in return, for registerForActivityResult(ActivityResultContracts.PickContact())
, result of type Uri!
.
Again, Uri!
means "Uri or Uri?" - "value or null".
To handle this value in a Kotlin style we can safely unwrap it by using question mark ?
:
activityResultLauncher = registerForActivityResult(ActivityResultContracts.PickContact()) {
it?.let { contactUri ->
viewModel.setContact(contactUri)
}
}