3. diel - Android Intent a aktivity - SumActivity - Java kód
V minulej lekcii, Android Intent a aktivity - SumActivity - Súčet čísel , sme si pripravili GUI aktivity pre súčet 2 čísel.
Než začneme písať Java kód SumActivity
, vytvoríme
rozhranie pre deklarácia všetkých konštánt ukážkové aplikácie
Activities
.
V aplikácii máme totiž niekoľko aktivít a nechceme každej definovať konštanty zvlášť. Niektoré budú určite potrebovať tie isté. Preto je definujeme centrálne v jednom rozhraní.
Rozhranie pre konštanty
V štruktúre projektu klikneme pravým tlačidlom na priečinok (viď. Obrázok) a v menu cez New na Java Class:
V otvorenom okne New Java Class do riadku Name napíšeme
AppConstants
, v ďalšom riadku Kind vyberieme možnosť
Interface a potvrdíme tlačidlom OK:
Bude vytvorený súbor AppConstants.java
:
public interface AppConstants { }
Do tohto súboru budeme postupne pridávať konštanty, použité v projekte.
Konštanta LOG_TAG
Hneď pridáme konštantu pre tag správ Logcatu:
public interface AppConstants { String LOG_TAG = "Activities_log_tag"; }
Takto môžeme potom ľahko spoznať naše logami.
Prístup ku konštantám
Prístup ku konštantám je možný dvoma spôsobmi. Prvý spôsob je priamo, napríklad volaním:
String tag = AppConstants.LOG_TAG;
Alebo môže trieda, v ktorej konštantu potrebujeme, implementovať
rozhranie AppConstants
, čím získa prístup ku všetkým jeho
konštantám:
public class MyClass implements AppConstants { String tag = LOG_TAG; }
SumActivity.java
Vráťme sa späť k aktivite SumActivity
. Teraz upravíme jej
Java kód na nasledujúce:
public class SumActivity extends AppCompatActivity { EditText etNumber1, etNumber2; // Políčko pro zadání čísel k součtu Button btnSend; // Tlačítko pro odeslní čísel do SumResultActivity TextView labelResult; // Label pro zobrazení vráceného součtu zadaných čísel int number1, number2; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sum_activity); setTitle(R.string.sum_activity_title); etNumber1 = findViewById(R.id.etNumber1); etNumber2 = findViewById(R.id.etNumber2); labelResult = findViewById(R.id.labelResult); btnSend = findViewById(R.id.btnSend); btnSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { number1 = Integer.parseInt(etNumber1.getText().toString()); number2 = Integer.parseInt(etNumber2.getText().toString()); sendData(); } catch (NumberFormatException e) { Log.d(AppConstants.LOG_TAG, "NumberFormatException"); Log.d(AppConstants.LOG_TAG, e.getMessage()); showErrorToast(); } catch (NullPointerException e) { Log.d(AppConstants.LOG_TAG, "NullPointerException"); Log.d(AppConstants.LOG_TAG, e.getMessage()); showErrorToast(); } } }); } private void showErrorToast() { Toast.makeText(this, R.string.info_incorrect_entry, Toast.LENGTH_LONG).show(); } }
Poďme si ho vysvetliť:
Kliknutie na tlačidlo
V ActivityMain.java
sme udalosti kliknutia nastavili
príslušnými parametrami tlačidiel v XML a deklaráciou obslužné metódy v
Java kóde. Tu to robíme pre zmenu len Java kódom, presnejšie priradením
OnClickListener
komponentom, na ktorých budeme kliknutie
očakávať. Nastavenie Listener tu vykonávame inline anonymný triedou. Na
tomto prístupe nie je nič zlé, ale má nevýhodu vo väčšom množstve Java
kódu a v nemožnosti kód znova použiť.
Kliknutím na tlačidlo Odoslať na výpočet zadané čísla
odosielame do aktivity SumResultActivity
, ktorej úlohou je čísla
sčítať a výsledok odoslať späť do aktivity SumActivity
.
Zadanie užívateľa v políčkach EditText
prevádzame z typu
String
na typ int
volaním metódy
parseInt()
triedy Integer
.
Počas konverzie môže, v prípade, že zadaný text obsahuje znak, ktorý
nie je číslicou, dôjsť k výnimke NumberFormatException
. To je
prvý z dvoch dôvodov, prečo je táto časť kódu "zabalená" do bloku
try
- catch
. Druhým dôvodom je fakt, že riadok
etNumberOne.getText().toString()
môže vyvolať výnimku
NullPointerException
. Spomínané prípadné výnimky teda
odchytávajú a môžeme na ne reagovať, bez toho aby došlo k pádu
aplikácie.
Otvorenie aktivity pre súčet zadaných čísel
Po úspešnej konverzii vstupe voláme metódu sendData()
.
Pridajme si ju do triedy:
private void sendData() { }
Metódu zatiaľ necháme prázdnu. Po vytvorení aktivity
SumResultActivity
(pre samotný súčet čísel) kód metódy
sendData()
doplníme.
startActivityForResult()
Metódu pre odpoveď s výsledkom aktivity si teraz pridajme:
@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 z tejto
aktivity SumActivity
odpoveď volaním jej metódy
onActivityResult()
. S touto metódou získame tri parametre:
requestCode
- Tu bude vrátená hodnota parametrarequestCode
z volanie metódystartActivityForResult()
.resultCode
- Hodnota typuint
, ktorá hovorí, 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, zavolásetResult(RESULT_OK, resultIntent)
.RESULT_CANCELED
obdržíme, ak bola aktivita ukončená volanímsetResult(RESULT_CANCELED)
alebo tlačidlom Späť. Toto bude čoskoro bližšie vysvetlené pri opise aktivitySumResultActivity
.RESULT_OK
v prípade, že v zatvorenej aktivite bolo, pred jej ukončením, zavolásetResult(RESULT_OK, resultIntent)
.RESULT_CANCELED
obdržíme, ak bola aktivita ukončená volanímsetResult(RESULT_CANCELED)
alebo tlačidlom Späť. Toto bude čoskoro bližšie vysvetlené pri opise aktivitySumResultActivity
.data
- Tu nájdeme objekt triedyIntent
, vložený do parametra volaniesetResult(RESULT_OK, resultIntent)
v zatvárané aktivite. Tým sa dostávame k použitiu intent ako kontajnera primitívnych dát. V Intent bez akcie nájdeme dáta odoslané aktivitouSumResultActivity
. Opis, ako tieto dáta vytvoriť, opäť uvidíme vo výklade o aktiviteSumResultActivity
.
V metóde onActivityResult()
ako prvý podmienkou zisťujeme,
ako bola aktivita zatvorená. Ak 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úce intent obsahuje nejaká
návratová dáta. Očakávame, že nám bude vrátený súčet dvoch čísel,
odoslaných do SumResultActivity
. Ak 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 Intent vložená v SumResultActivity
. Ak dáta tieto
kľúče obsahujú, rovno nastavujeme TextView
, ktorý je určený
pre zobrazenie výsledku súčtu v SumActivity
.
Úprava Java kódu hlavné aktivity
Teraz, keď máme hotovú aktivitu SumActivity
, doplníme v
MainActivity
kus kódu do prvej vetvy konštrukcie
switch
v metóde click()
. Týmto bude prvé tlačidlo
s textom Súčet čísel ukážkové aplikácie funkčné. Metóda
click()
bude teraz vyzerať takto:
public void click(View view) { switch (view.getId()) { case R.id.btnSumActivity: Intent intentSumActivity = new Intent(MainActivity.this, SumActivity.class); startActivity(intentSumActivity); break; case R.id.btnMapActivity: break; case R.id.btnPhoneActivity: break; case R.id.btnPhotoActivity: break; case R.id.btnShareActivity: break; case R.id.btnITnetwork: Intent webIntent = new Intent(Intent.ACTION_VIEW); webIntent.setData(Uri.parse("https://www.itnetwork.cz/")); if (webIntent.resolveActivity(getPackageManager()) != null) { startActivity(webIntent); } break; } }
V doplnené prvej vetve prepínače switch
, v prvom riadku,
vytvárame explicitné intent pre otvorenie aktivity SumActivity
. V
druhom riadku túto aktivitu, volaním metódy startActivity()
,
otvárame.
Len pripomeniem, že metóda click()
je nami deklarovaná
metóda a v XML návrhu hlavné aktivity je všetkým tlačidlám nastavená ako
obsluha udalosti kliknutí takto: android:onClick="click"
.
V budúcej lekcii, Android Intent a aktivity - SumResultActivity , vytvoríme vzhľad grafického užívateľského rozhrania aktivity, do ktorej budeme odosielať užívateľom zadané čísla, určená k súčtu.