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óduonActivityResult() 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 parametrarequestCodez volania metódystartActivityForResult().resultCode- Hodnota typuinthovoriaci akým spôsobom bola zatvorená aktivita ukončená. Číselná hodnota je vyjadrená konštantou:RESULT_OKv prípade, že v zatvorenej aktivite bolo, pred jej ukončením,setResult(RESULT_OK, resultIntent).RESULT_CANCELEDdostaneme, ak bola aktivita ukončená volanímsetResult(RESULT_CANCELED)alebo tlačidlom Späť. Toto bude čoskoro bližšie vysvetlené pri popise aktivitySumResultActivity.RESULT_OKv prípade, že v zatvorenej aktivite bolo, pred jej ukončením,setResult(RESULT_OK, resultIntent).RESULT_CANCELEDdostaneme, ak bola aktivita ukončená volanímsetResult(RESULT_CANCELED)alebo tlačidlom Späť. Toto bude čoskoro bližšie vysvetlené pri popise aktivitySumResultActivity.data- Objekt triedyIntentvložený do parametra volaniasetResult(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é aktivitouSumResultActivity. Popis, ako tieto dáta vytvoriť, opäť uvidíme vo výklade o aktiviteSumResultActivity.
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óduonActivityResult() 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.

