如何使用 Jetpack Compose 处理 Activity.onActivityResult()?
How to handle Activity.onActivityResult() with Jetpack Compose?
我正在尝试使用 Jetpack Compose 在我的 Android 应用程序中实现 sign-in hints,但是这个 API 需要 Activity
才能工作。
fun showPhoneNumberHint(activity: Activity) {
val hintRequest: HintRequest = HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build()
val intent = Auth.CredentialsApi.getHintPickerIntent(apiClient, hintRequest)
val requestCode = 12345
try {
startIntentSenderForResult(activity, intent.intentSender, requestCode, null, 0, 0, 0, null)
} catch (exception: SendIntentException) {
// Error handling
}
}
所以我想我必须将 Activity 对象一直传递到需要它的可组合项,这看起来不是很干净,但它应该可以工作。
但现在提示的结果将在 Activity 的 onActivityResult()
中收到,我不确定将其返回到需要它的可组合项的正确方法是什么.
有什么 clean/standard/alternative 方法可以做到这一点吗?我最好将所有这些逻辑都包含在可组合项中。
Activity.onActivityResult()
已弃用,即使没有撰写也不应该使用它。您应该使用 AndroidX Activity 和 Fragment.Activity 中引入的 Activity 结果 APIs。
Activity 结果 API 提供 registerForActivityResult()
API 用于注册结果回调。 registerForActivityResult()
需要一个 ActivityResultContract
和一个 ActivityResultCallback
和 returns 一个 ActivityResultLauncher
,您将使用它们来启动另一个 activity.
没有撰写的例子:
val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
// Handle the returned Uri
}
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val selectButton = findViewById<Button>(R.id.select_button)
selectButton.setOnClickListener {
// Pass in the mime type you'd like to allow the user to select
// as the input
getContent.launch("image/*")
}
}
在撰写中使用 rememberLauncherForActivityResult()
而不是 registerForActivityResult
:
val result = remember { mutableStateOf<Bitmap?>(null) }
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.TakePicturePreview()) {
result.value = it
}
Button(onClick = { launcher.launch() }) {
Text(text = "Take a picture")
}
result.value?.let { image ->
Image(image.asImageBitmap(), null, modifier = Modifier.fillMaxWidth())
}
您尝试使用的 API 的问题是它需要使用 onActivityResult。所以,你别无选择,只能使用它。尝试在 github 上打开一个问题,请求更新他们的 API.
我最终使用 rememberLauncherForActivityResult
结合 ActivityResultContracts.StartIntentSenderForResult()
合约来监听结果。这个returns一个可以用来启动intent的launcher
。
而不是 Auth.CredentialsApi
,它需要已弃用的 GoogleApiClient
,我现在使用的是 Credentials.getClient
。为此,我仍然需要一个 Activity
,我使用 LocalContext.current
.
val phoneNumberHintLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartIntentSenderForResult()
) {
if (it.resultCode != RESULT_OK) {
return@rememberLauncherForActivityResult
}
val credential: Credential? = it.data?.getParcelableExtra(Credential.EXTRA_KEY)
val hintResult = credential?.id
if (hintResult !== null) {
phoneNumber = hintResult
}
}
val context = LocalContext.current
LaunchedEffect(Unit) {
val hintRequest: HintRequest = HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build()
val phoneNumberHintIntent = Credentials.getClient(context)
.getHintPickerIntent(hintRequest)
phoneNumberHintLauncher.launch(
IntentSenderRequest.Builder(phoneNumberHintIntent)
.build()
)
}
我正在尝试使用 Jetpack Compose 在我的 Android 应用程序中实现 sign-in hints,但是这个 API 需要 Activity
才能工作。
fun showPhoneNumberHint(activity: Activity) {
val hintRequest: HintRequest = HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build()
val intent = Auth.CredentialsApi.getHintPickerIntent(apiClient, hintRequest)
val requestCode = 12345
try {
startIntentSenderForResult(activity, intent.intentSender, requestCode, null, 0, 0, 0, null)
} catch (exception: SendIntentException) {
// Error handling
}
}
所以我想我必须将 Activity 对象一直传递到需要它的可组合项,这看起来不是很干净,但它应该可以工作。
但现在提示的结果将在 Activity 的 onActivityResult()
中收到,我不确定将其返回到需要它的可组合项的正确方法是什么.
有什么 clean/standard/alternative 方法可以做到这一点吗?我最好将所有这些逻辑都包含在可组合项中。
Activity.onActivityResult()
已弃用,即使没有撰写也不应该使用它。您应该使用 AndroidX Activity 和 Fragment.Activity 中引入的 Activity 结果 APIs。
Activity 结果 API 提供 registerForActivityResult()
API 用于注册结果回调。 registerForActivityResult()
需要一个 ActivityResultContract
和一个 ActivityResultCallback
和 returns 一个 ActivityResultLauncher
,您将使用它们来启动另一个 activity.
没有撰写的例子:
val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
// Handle the returned Uri
}
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val selectButton = findViewById<Button>(R.id.select_button)
selectButton.setOnClickListener {
// Pass in the mime type you'd like to allow the user to select
// as the input
getContent.launch("image/*")
}
}
在撰写中使用 rememberLauncherForActivityResult()
而不是 registerForActivityResult
:
val result = remember { mutableStateOf<Bitmap?>(null) }
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.TakePicturePreview()) {
result.value = it
}
Button(onClick = { launcher.launch() }) {
Text(text = "Take a picture")
}
result.value?.let { image ->
Image(image.asImageBitmap(), null, modifier = Modifier.fillMaxWidth())
}
您尝试使用的 API 的问题是它需要使用 onActivityResult。所以,你别无选择,只能使用它。尝试在 github 上打开一个问题,请求更新他们的 API.
我最终使用 rememberLauncherForActivityResult
结合 ActivityResultContracts.StartIntentSenderForResult()
合约来监听结果。这个returns一个可以用来启动intent的launcher
。
而不是 Auth.CredentialsApi
,它需要已弃用的 GoogleApiClient
,我现在使用的是 Credentials.getClient
。为此,我仍然需要一个 Activity
,我使用 LocalContext.current
.
val phoneNumberHintLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartIntentSenderForResult()
) {
if (it.resultCode != RESULT_OK) {
return@rememberLauncherForActivityResult
}
val credential: Credential? = it.data?.getParcelableExtra(Credential.EXTRA_KEY)
val hintResult = credential?.id
if (hintResult !== null) {
phoneNumber = hintResult
}
}
val context = LocalContext.current
LaunchedEffect(Unit) {
val hintRequest: HintRequest = HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build()
val phoneNumberHintIntent = Credentials.getClient(context)
.getHintPickerIntent(hintRequest)
phoneNumberHintLauncher.launch(
IntentSenderRequest.Builder(phoneNumberHintIntent)
.build()
)
}