GOOGLE ADS

Samstag, 30. April 2022

Wie gehe ich mit Activity.onActivityResult() mit Jetpack Compose um?

Ich versuche, Anmeldehinweise in meiner Android-App mit Jetpack Compose zu implementieren, aber diese API erfordert eine Activity, um zu funktionieren.

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
}
}

Ich schätze also, dass ich das Aktivitätsobjekt ganz nach unten an das Composable weitergeben muss, wo es benötigt wird, was nicht sehr sauber erscheint, aber es sollte funktionieren.

Aber jetzt wird das Ergebnis des Hinweises in den Aktivitäten empfangen, onActivityResult()und ich bin mir nicht sicher, wie ich es richtig an das Composable zurückbekomme, wo es benötigt wird.

Gibt es einen sauberen/standardmäßigen/alternativen Weg, dies zu tun? Am liebsten würde ich all diese Logik einfach im Composable enthalten lassen.


Lösung des Problems

Activity.onActivityResult()ist veraltet und Sie sollten es auch ohne compose nicht verwenden. Sie sollten die Aktivitätsergebnis-APIs verwenden, die in AndroidX Activity and Fragment eingeführt wurden.

Die Aktivitätsergebnis-APIs stellen eine registerForActivityResult()API zum Registrieren des Ergebnisrückrufs bereit. registerForActivityResult()nimmt ein ActivityResultContractund ein ActivityResultCallbackund gibt ein zurück ActivityResultLauncher, mit dem Sie die andere Aktivität starten.

Beispiel ohne compose:

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/*")
}
}

Verwenden Sie in compose rememberLauncherForActivityResult()anstelle von 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())
}

Das Problem mit der API, die Sie verwenden möchten, ist, dass sie die Verwendung von onActivityResult erfordert. Sie haben also keine andere Wahl, als es zu verwenden. Versuchen Sie, ein Problem auf GitHub zu öffnen, in dem Sie aufgefordert werden, die API zu aktualisieren.

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...