Wie ersetzt man startActivityForResult durch Aktivitätsergebnis-APIs?

Lesezeit: 6 Minuten

Neohs Benutzeravatar
Neoh

Ich habe eine Hauptaktivität, die als Einstiegspunkt dient, um je nach Zustand verschiedene Aktivitäten aufzurufen. Unter anderem verwende ich Firebase Auth, um die Benutzeranmeldung zu verwalten:

startActivityForResult(
            AuthUI.getInstance().createSignInIntentBuilder()
                    .setAvailableProviders(providers)
                    .build(),
            RC_SIGN_IN)

Ich überschreibe onActivityResult() um die zurückgegebenen Absichten/Daten zu unterscheiden, zum Beispiel:

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {

        REQUEST_CODE_1 -> {
          // update UI and stuff
        }

        RC_SIGN_IN -> {
          // check Firebase log in
        }
        // ...
    }
}

Mit den Aktivitätsergebnis-APIs, die von der dringend empfohlen werden Dokumentationich verstehe, dass ich machen sollte prepareCall() Vor ActivityResultLauncher und um sicherzustellen, dass sich die Aktivität beim Start im erstellten Zustand befindet, aber ich verstehe immer noch nicht, wie mehrere Aktivitätsergebnisse (zumindest an einem Ort) wie in onActivityResult().

Anschauen Dieser Artikeles scheint, dass ich implementieren muss mehrere Kind innere Klassen von ActivityResultContract Typ (also mehrere prepareCall()‘s?), weil sie angeblich anders sind Verträge, hab ich recht? Kann mir bitte jemand ein Skelettbeispiel zeigen, das das oben Gesagte widerspiegelt onActivityResult() Logik?

Benutzeravatar von Misha Akopov
Mischa Akopow

Sie können so viele Aktivitäten als Ergebnis aufrufen, wie Sie möchten, und für jede einen separaten Rückruf haben:

    val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult())
    { result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK) {
            //  you will get result here in result.data
            }

        }
    }

    startForResult.launch(Intent(activity, CameraCaptureActivity::class.java))

Sie müssen nur die Aktivitätsklasse angeben – CameraCaptureActivity::class.java

Aktualisieren:

The prepareCall() method has been renamed to registerForActivityResult() in Activity 1.2.0-alpha04 and Fragment 1.3.0-alpha04. And it should be startForResult.launch(...) in the last line

Vielen Dank Raffael Tavares für Aktualisierung

  • Das prepareCall() Methode wurde umbenannt in registerForActivityResult() in Aktivität 1.2.0-alpha04 und Fragment 1.3.0-alpha04. Und es sollte sein startForResult.launch(...) in der letzten Zeile

    – Raffael Tavares

    10. September 2020 um 11:23 Uhr


  • Was ist mit dem Passieren 'android.content.Intent intent, int requestCode' als Parameter?

    – AtomX

    10. April 2021 um 12:58 Uhr


  • Aber um das Ergebnis von Activity2 zurückzusenden, ist es das gleiche wie immer?: setResult(Bundle)???

    – mantc_sdr

    10. Juni 2021 um 9:19 Uhr

  • es gibt result.data als null zurück

    – Karunesh Palekar

    4. August 2021 um 12:39 Uhr

Benutzeravatar von Hardik Hirpara
Hardik Hirpara

In, startActivityForResult() ist veraltet, verwenden Sie stattdessen die neue Methode.

Beispiel

public void openActivityForResult() {
    
 //Instead of startActivityForResult use this one
        Intent intent = new Intent(this,OtherActivity.class);
        someActivityResultLauncher.launch(intent);
    }


//Instead of onActivityResult() method use this one

    ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    if (result.getResultCode() == Activity.RESULT_OK) {
                        // Here, no request code
                        Intent data = result.getData();
                        doSomeOperations();
                    }
                }
            });

  • Probieren Sie diesen Code mit Google-Anmeldung bei ActivityForResult ohne Erfolg aus, irgendwelche Vorschläge?

    – Kerl

    16. Mai 2021 um 1:35 Uhr

  • dieser Code hat bei mir funktioniert; musste allerdings nach kotlin übersetzen. Danke

    – federico verchez

    28. Mai 2021 um 1:04 Uhr

  • Vielen Dank, dass Sie “var” und Lambdas nicht verwenden 🙂

    – paulsm4

    13. August 2021 um 3:32 Uhr

  • Vereinfachter und sauberer beschrieben ✓

    – Basaveshwar-Lamture

    28. Dezember 2021 um 18:58 Uhr

  • Kann bestätigen, dass es einwandfrei funktioniert hat

    – Ezequiel Adrian

    29. Januar um 17:48 Uhr

Vergessen Sie zunächst nicht, dies zu Ihrer Gradle-Abhängigkeit hinzuzufügen

implementation 'androidx.activity:activity-ktx:1.2.0-alpha05'
implementation 'androidx.fragment:fragment-ktx:1.3.0-alpha05'

Erstellen Sie zweitens Ihren Ergebnisvertrag, indem Sie eine abstrakte Klasse namens erweitern ActivityResultContract<I, O>. Ich meine die Art der Eingabe und O bedeutet die Art der Ausgabe. Und dann müssen Sie nur 2 Methoden überschreiben

class PostActivityContract : ActivityResultContract<Int, String?>() {

    override fun createIntent(context: Context, input: Int): Intent {
        return Intent(context, PostActivity::class.java).apply {
            putExtra(PostActivity.ID, postId)
        }
    }

    override fun parseResult(resultCode: Int, intent: Intent?): String? {
        val data = intent?.getStringExtra(PostActivity.TITLE)
        return if (resultCode == Activity.RESULT_OK && data != null) data
        else null
    }
}

Und schließlich ist der letzte Schritt die Registrierung des Vertrages bei Activity. Sie müssen Ihren benutzerdefinierten Vertrag und den Rückruf weitergeben registerForActivityResult.

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
      
        start_activity_contract.setOnClickListener {
            openPostActivityCustom.launch(1)
        }
    }
  
    // Custom activity result contract
    private val openPostActivityCustom =
        registerForActivityResult(PostActivityContract()) { result ->
            // parseResult will return this as string?                                              
            if (result != null) toast("Result : $result")
            else toast("No Result")
        }
}

Weitere Informationen finden Sie hier Post

  • War auf der Suche nach den Abhängigkeiten, danke für das Hinzufügen. Bekomme eine positive Bewertung 🙂

    – Neo Wakeup

    21. Juni 2021 um 15:29 Uhr

  • Schön zu hören, dass es dir geholfen hat 🙂

    – Krishna Sony

    22. Juni 2021 um 17:19 Uhr

  • Ein guter Ansatz, um das Anfordernde zu spezifizieren Intent! Vielen Dank!

    – YUSMLE

    28. November 2021 um 13:09 Uhr


In diesem Fall war das, was von AuthUI zurückgegeben wurde, bereits ein Intent, also verwenden wir es wie im folgenden Beispiel.

private val startForResult =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            when(result.resultCode){
                RESULT_OK -> {
                    val intent = result.data
                    // Handle the Intent...
                    mUser = FirebaseAuth.getInstance().currentUser
                }
                RESULT_CANCELED -> {

                } else -> {
            } }
        }

Starten Sie die Aktivität von überall (z. B. durch Klicken auf eine Schaltfläche) mit:

 AuthUI.getInstance().createSignInIntentBuilder().setAvailableProviders(providers)
            .build().apply {
                startForResult.launch(this)
            }

List<AuthUI.IdpConfig> providers = Arrays.asList(
                    new AuthUI.IdpConfig.EmailBuilder().build(),
                    new AuthUI.IdpConfig.GoogleBuilder().build());

            ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Log.v("LOGIN OK", "OK Result for Login");
                }
            });
            
            launcher.launch(AuthUI.getInstance()
                    .createSignInIntentBuilder()
                    .setIsSmartLockEnabled(false)
                    .setAvailableProviders(providers)
                    .build());

Siehe dies für weitere Details:
https://githubmemory.com/repo/firebase/FirebaseUI-Android/issues?cursor=Y3Vyc29yOnYyOpK5MjAyMS0wMy0wNVQyMjoxNzozMyswODowMM4xEAQZ&pagination=next&page=2

Benutzeravatar von Arvind Sharma
Arvin Sharma

Verwenden Sie dies für Firebase AuthUI;

final ActivityResultLauncher<Intent> launcher = registerForActivityResult(
            new FirebaseAuthUIActivityResultContract(), this::onSignInResult);

    binding.loginSignup.setOnClickListener(view -> {
        List<AuthUI.IdpConfig> provider = Arrays.asList(new AuthUI.IdpConfig.EmailBuilder().build(),
                new AuthUI.IdpConfig.GoogleBuilder().build(),
                new AuthUI.IdpConfig.PhoneBuilder().build());
        Intent intent = AuthUI.getInstance()
                .createSignInIntentBuilder()
                .setIsSmartLockEnabled(false)
                .setAlwaysShowSignInMethodScreen(true)
                .setAvailableProviders(provider)
                .build();
        launcher.launch(intent);
    });


private void onSignInResult(FirebaseAuthUIAuthenticationResult result) {

    if (result.getResultCode() == RESULT_OK) {
        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
        if (user != null) {
            if (user.getMetadata() != null) {
                if (user.getMetadata().getCreationTimestamp() != user.getMetadata().getLastSignInTimestamp()) {
                    Toast.makeText(this, "Welcome Back", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "Welcome", Toast.LENGTH_SHORT).show();
                }
                startMainActivity();
            }
        }
    } else {
        IdpResponse response = result.getIdpResponse();
        if (response == null)
            Toast.makeText(this, "Canceled By You", Toast.LENGTH_SHORT).show();
        else Log.d(TAG, "onCreate: ActivityResult" + response.getError());
    }
}

private void startMainActivity() {
    Intent intent = new Intent(LoginActivity.this, MainActivity.class);
    startActivity(intent);
    finish();
}

So was.

Benutzeravatar von CoolMind
CoolMind

Wenn Sie eine Aktivität von einem Fragment aus starten und das Ergebnis an das Fragment zurückgeben, tun Sie dies.

Im Fragment:

private lateinit var activityResult: ActivityResultLauncher<Intent>

activityResult = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == RESULT_OK) {
        val data = result.data
        doSomeOperations(data)
    }
}

SomeActivity.showScreen(activityResult, requireContext())

In Aktivität:

// activity?.setResult(Activity.RESULT_OK) doesn't change.

companion object {

    fun showScreen(activityResult: ActivityResultLauncher<Intent>, context: Context) {
        val intent = Intent(context, SomeActivity::class.java)
        activityResult.launch(intent)
    }
}

  • was ist SomeActivity.showScreen (activityResult, requireContext()) ich meine, was ist showScreen ??? kannst du näher beschreiben?

    – Yogi Arif Widodo

    1. Februar um 22:24 Uhr

  • @YogiArifWidodo, fun showScreen(activityResult: ActivityResultLauncher<Intent>, context: Context) im 2. Teil der Antwort. Sie können eine Aktivität öffnen SomeActivity aus einem Fragment, führen Sie einige Aktionen aus und geben Sie ein Ergebnis dieser Aktivität an das Fragment zurück.

    – CoolMind

    2. Februar um 7:15

1394630cookie-checkWie ersetzt man startActivityForResult durch Aktivitätsergebnis-APIs?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy