IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

17. diel - Android Intenty a aktivity - Odpoveď od zatvorenej aktivity

V minulej lekcii, Android Intent a aktivity - Java kód aktivity ShareActivity , sme si ukázali zdieľanie zadaného textu do iných aplikácií a otváranie aplikácií schopných zobraziť webovú adresu.

V dnešnom Android tutoriále si ukážeme, ako otvoriť aktivitu tak, aby nám, po svojom ukončení, odovzdala odpoveď s požadovanými dátami.

Často v aplikácii otvárame inú aktivitu, od ktorej, po jej zatvorení, očakávame odpoveď. V našom konkrétnom prípade budeme z aktivity SumActivity otvárať aktivitu SumResultActivity, ktorá odovzdá späť do aktivity SumActivity výsledok súčtu dvoch čísel.

To, či zatvorená aktivita bude alebo nebude odovzdávať dáta späť, záleží na spôsobe, akým je otvorená. Postupne sa dostaneme k dvom možným spôsobom otvorenia aktivity:

  • bez požiadavky odpovede po jej zatvorení,
  • s očakávaním odpovede po jej zatvorení.

Najskôr si v aktivite SumActivity, na ktorej stále pracujeme, napíšeme kód pre príjem súčtu dvoch čísel, ktorý tu budeme očakávať po zatvorení aktivity SumResultActivity.

Na otvorenie aktivity, vracajúcej späť dáta, existujú dva postupy. Prvý, doteraz používaný, je teraz v dokumentácii označený ako zastaraný. Druhý novší spôsob nahrádza ten prvý. Ako dôvod tejto zmeny oficiálna dokumentácia uvádza efektívnejšiu prácu s pamäťou. Obe možnosti si vysvetlíme.

Starší spôsob získania odpovede

Aktivita, ktorá očakáva odpoveď od inej aktivity, prepisuje metódu onActivityResult() z triedy Activity.

Metóda onActivityResult()

Metóda onActivityResult() patrí triede Activity. My si ju pridáme do našej triedy SumActivity:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
     if (resultCode == RESULT_OK) {
        if (requestCode == 1) {
            if (data != null) {
                if (data.hasExtra("result_from_activity_sum")) {
                    labelResult.setText("" + data.getIntExtra("result_from_activity_sum", -1));
                } else {
                    labelResult.setText(R.string.info_error_loading_result);
                }
            }
        }
    } else if (resultCode == RESULT_CANCELED) {
        labelResult.setText(R.string.info_no_result);
    }
}

Po zatvorení aktivity SumResultActivity dostane aktivita SumActivity zo zatvorenej aktivity SumResultActivity odpoveď zavolaním jej metódy onActivityResult().

Metóda onActivityResult() prijíma tri parametre:

  • requestCode - Hodnota parametra requestCode z volania metódy startActivityForResult().
  • resultCode - Hodnota typu int hovoriaci akým spôsobom bola zatvorená aktivita ukončená. Číselná hodnota je vyjadrená konštantou: RESULT_OK v prípade, že v zatvorenej aktivite bolo, pred jej ukončením, setResult(RESULT_OK, resultIntent).

    RESULT_CANCELED dostaneme, ak bola aktivita ukončená volaním setResult(RESULT_CANCELED) alebo tlačidlom Späť. Toto bude čoskoro bližšie vysvetlené pri popise aktivity SumResultActivity.

  • RESULT_OK v prípade, že v zatvorenej aktivite bolo, pred jej ukončením, setResult(RESULT_OK, resultIntent).
  • RESULT_CANCELED dostaneme, ak bola aktivita ukončená volaním setResult(RESULT_CANCELED) alebo tlačidlom Späť. Toto bude čoskoro bližšie vysvetlené pri popise aktivity SumResultActivity.
  • data - Objekt triedy Intent vložený do parametra volania setResult(RESULT_OK, resultIntent) v zatváranej aktivite. Tým sa dostávame na použitie intentu ako kontajnera primitívnych dát. V intente bez akcie nájdeme dáta odoslané aktivitou SumResultActivity. Popis, ako tieto dáta vytvoriť, opäť uvidíme vo výklade o aktivite SumResultActivity.

V metóde onActivityResult() podmienkou zisťujeme, ako bola aktivita zatvorená. Pokiaľ parameter resultCode obsahuje hodnotu RESULT_OK, ďalší postup určujeme podľa int requestCode. My tu máme iba jedinú možnosť.

Ďalej v podmienke testujeme, či prichádzajúci intent obsahuje nejaké návratové dáta. Očakávame, že nám bude vrátený súčet dvoch čísel, odoslaných do SumResultActivity. Pokiaľ je podmienka splnená, zisťujeme volaním data.hasExtra(), či dáta obsahujú uvedené kľúče, vyjadreným textovým reťazcom. Pod týmto kľúčom sú dáta do návratového intentu vložené v SumResultActivity. Pokiaľ dáta tieto kľúče obsahujú, rovno nastavujeme TextView, ktorý je určený pre zobrazenie výsledku súčtu v SumActivity.

Nový spôsob získania odpovede

V novom postupe aktivita, ktorá očakáva odpoveď od inej aktivity, neprepisuje metódu onActivityResult() z triedy Activity.

Namiesto toho použijeme triedu ActivityResultLauncher, ktorej inštanciu získame zavolaním metódy registerForActivityResult(). Táto metóda vo svojich parametroch prijíma rozhranie ActivityResultCallback, v ktorého prepísanej metóde onActivityResult() získavame odpoveď zo zatvorenej aktivity.

Pozor na zhodný názov dvoch rozdielnych metód! V starom spôsobe prepisuje trieda, otvárajúca iné aktivity, metódu onActivityResult(), patriacu triede Activity. Aj v novom spôsobe prepisujeme metódu onActivityResult(), ale úplne inde - v tomto prípade táto metóda patrí rozhraniu ActivityResultCallback. Ide o zhodný názov dvoch rôznych metód.

Trieda SumActivity

V triede SumActivity, pod deklaráciu premenných, pridáme tento kód:
ActivityResultLauncher<Intent> sumActivityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Intent data = result.getData();

                    if (data != null) {
                        if (data.hasExtra("result_from_activity_sum")) {
                            labelResult.setText("" + data.getIntExtra("result_from_activity_sum", -1));
                        } else {
                            labelResult.setText(R.string.info_error_loading_result);
                        }
                    }
                }
            }
        });

V uvedenom kóde vytvárame inštanciu triedy ActivityResultLauncher volaním metódy registerForActivityResult().

Metóda registerForActivityResult() patrí rozhranie ActivityResultCaller, ktoré je súčasťou API nového spôsobu otvárania aktivít vracajúcich odpoveď.

V druhom parametri metódy deklarujeme rozhranie ActivityResultCallback, v ktorého prepísanej metóde onActivityResult() získavame odpoveď od zatvorenej aktivity. Na inštancii result typu ActivityResult voláme metódu getData(), ktorá nám vracia objekt typu Intent. S objektom Intent ďalej pracujeme úplne rovnako ako vo vyššie popísanom starom spôsobe.


 

Predchádzajúci článok
Android Intent a aktivity - Java kód aktivity ShareActivity
Všetky články v sekcii
Android intent a aktivity
Článok pre vás napísal Pavel
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje programování v Javě, hlavně pro Android. Mezi jeho další zájmy patří Arduino, Minecraft.
Aktivity