Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 4 - Android Intenty a aktivity - Odpověď od zavřené aktivity

V předchozím kvízu, Kvíz - Nastavení vzhledu aktivity a intenty v Androidu, jsme si ověřili nabyté zkušenosti z předchozích lekcí.

V dnešním Android tutoriálu si ukážeme, jak otevřít aktivitu tak, aby nám, po svém ukončení, předala odpověď s požadovanými daty.

Často v aplikaci otevíráme jinou aktivitu, od které, po jejím zavření, očekáváme odpověď. V našem konkrétním případě budeme z aktivity SumActivity otevírat aktivitu SumResultActivity, která předá zpět do aktivity SumActivity výsledek součtu dvou čísel.

To, zda zavřená aktivita bude nebo nebude předávat data zpět, záleží na způsobu, jakým je otevřena. Postupně se dostaneme ke dvěma možným způsobům otevření aktivity:

  • bez požadavku odpovědi po jejím zavření,
  • s očekáváním odpovědi po jejím zavření.

Nejdříve si v aktivitě SumActivity, na které stále pracujeme, napíšeme kód pro příjem součtu dvou čísel, který zde budeme očekávat po zavření aktivity SumResultActivity.

K otevření aktivity, vracející zpět data, existují dva postupy. První, dosud používaný, je nyní v dokumentaci označen jako zastaralý. Druhý novější způsob nahrazuje ten první. Jako důvod této změny oficiální dokumentace uvádí efektivnější práci s pamětí. Obě možnosti si vysvětlíme.

Starší způsob získání odpovědi

Aktivita, která očekává odpověď od jiné aktivity, přepisuje metodu onActivityResult() ze třídy Activity.

Metoda onActivityResult()

Metoda onActivityResult() patří třídě Activity. My si ji přidáme do naší třídy 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 {
        labelResult.setText(R.string.info_no_result);
    }
}

Po zavření aktivity SumResultActivity obdrží aktivita SumActivity ze zavřené aktivity SumResultActivity odpověď zavoláním její metody onActivityResult().

Metoda onActivityResult() přijímá tři parametry:

  • requestCode - Hodnota parametru requestCode z volání metody startActivityForResult().
  • resultCode - Hodnota typu int říkající jakým způsobem byla zavřená aktivita ukončena. Číselná hodnota je vyjádřena konstantou:
    • RESULT_OK v případě, že v zavřené aktivitě bylo, před jejím ukončením, zavoláno setResult(RESULT_OK, resultIntent).
    • RESULT_CANCELED obdržíme, pokud byla aktivita ukončena voláním setResult(RESULT_CANCELED) nebo tlačítkem Zpět. Toto bude brzy blíže vysvětleno při popisu aktivity SumResultActivity.
  • data - Objekt třídy Intent vložený do parametru volání setResult(RESULT_OK, resultIntent) v zavírané aktivitě. Tím se dostáváme k použití intentu jako kontejneru primitivních dat. V intentu bez akce nalezneme data odeslaná aktivitou SumResultActivity. Popis, jak tato data vytvořit, opět uvidíme ve výkladu o aktivitě SumResultActivity.

V metodě onActivityResult() podmínkou zjišťujeme, jak byla aktivita zavřena. Pokud parametr resultCode obsahuje hodnotu RESULT_OK, další postup určujeme podle int requestCode. My zde máme pouze jedinou možnost.

Dále v podmínce testujeme, zda příchozí intent obsahuje nějaká návratová data. Očekáváme, že nám bude vrácen součet dvou čísel, odeslaných do SumResultActivity. Pokud je podmínka splněna, zjišťujeme voláním data.hasExtra(), zda data obsahují uvedené klíče, vyjádřeným textovým řetězcem. Pod tímto klíčem jsou data do návratového intentu vložena v SumResultActivity. Pokud data tyto klíče obsahují, rovnou nastavujeme TextView, který je určen pro zobrazení výsledku součtu v SumActivity.

Nový způsob získání odpovědi

V novém postupu aktivita, která očekává odpověď od jiné aktivity, nepřepisuje metodu onActivityResult() ze třídy Activity.

Místo toho použijeme třídu ActivityResultLauncher, jejíž instanci získáme zavoláním metody registerForActivityResult(). Tato metoda ve svých parametrech přijímá rozhraní ActivityResultCallback, v jehož přepsané metodě onActivityResult() získáváme odpověď ze zavřené aktivity.

Pozor na shodný název dvou rozdílných metod! Ve starém způsobu přepisuje třída, otevírající jiné aktivity, metodu onActivityResult(), patřící třídě Activity. I v novém způsobu přepisujeme metodu onActivityResult(), ale úplně jinde - v tomto případě tato metoda patří rozhraní ActivityResultCallback. Jde o shodný název dvou různých metod.

Třída SumActivity

Ve třídě SumActivity, pod deklaraci proměnných, přidá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 uvedeném kódu vytváříme instanci třídy ActivityResultLauncher voláním metody registerForActivityResult().

Metoda registerForActivityResult() patří rozhraní ActivityResultCaller, které je součástí API nového způsobu otevírání aktivit vracejících odpověď.

Ve druhém parametru metody deklarujeme rozhraní ActivityResultCallback, v jehož přepsané metodě onActivityResult() získáváme odpověď od zavřené aktivity. Na instanci result typu ActivityResult voláme metodu getData(), která nám vrací objekt typu Intent. S objektem Intent dále pracujeme úplně stejně jako ve výše popsaném starém způsobu.

V příští lekci, Android Intenty a aktivity - SumResultActivity, vytvoříme vzhled grafického uživatelského rozhraní aktivity, do které budeme odesílat uživatelem zadaná čísla, určená k součtu.


 

Předchozí článek
Kvíz - Nastavení vzhledu aktivity a intenty v Androidu
Všechny články v sekci
Android Intenty a aktivity
Přeskočit článek
(nedoporučujeme)
Android Intenty a aktivity - SumResultActivity
Článek pro vás napsal Pavel
Avatar
Uživatelské hodnocení:
2 hlasů
Autor se věnuje programování v Javě, hlavně pro Android. Mezi jeho další zájmy patří Arduino, Minecraft.
Aktivity