MojAndroid

V minulej časti programovania pre začiatočníkov sme sa zoznámili s vývojovým prostredím Eclipse a vytvorili sme si jednoduchú aplikáciu, ktorá odpočítavala čas. V novej časti sa pozrieme bližšie na štruktúru Android aplikácie a vytvoríme si menu a naučíme sa otvoriť novú Activity, kde si používateľ vyberie aký čas sa bude odpočítavať. Seriál je z veľkej časti prepísaný z portálu linux.com a pomôže vám v začiatkoch programovania pre platformu Android. Taktiež boli použité aj niektoré materiály zo stránky developer.android.com, kde nájdete množstvo informácií na túto tému. Predpokladá sa základná znalosť jazykov Java a XML. Druhá časť nadväzuje na predchádzajúci program, ktorý sme vytvorili v prvej časti.

1. časť: Programovanie Android aplikácií pre začiatočníkov (1. časť)

programovanie-android-aplikacii

Moje prvé menu 

Menu alebo ponuka sú veľmi často používané pri návrhu používateľského prostredia v mnohých typoch aplikácií. Zariadenia so systémom vyšším než Android 3.0 (API level 11), už nie sú povinné poskytovať vyhradené tlačidlo pre vyvolanie Menu. S touto zmenou migrovali aplikácie od tradičných šesť položkových ponúk a namiesto toho poskytujú  tzv. Action Bar.

V Androide máme tri typy ponuky menu. Tzv. Options Menu, ktoré sa zobrazí ak používateľ stlačí menu tlačidlo (na spomínaných starších zariadeniach) alebo je zobrazené v Action bare (novšie Androidy). Dostupné sú ja contextual a popup menu, o ktorých sa dozviete viac na stránkach spoločnosti Google. Dnes použijeme prvé spomínané Options menu, ktoré nám umožní nastaviť čas odpočítavania.

Vývojárske prostredie Eclipse vytvorí automaticky pri novom projekte aj metódu pre spomínaný Options menu:

public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.activity_main, menu);
  return true;
}

getMenuInflater() vám umožní riadiť sa osvedčenými postupmi a vytvoriť menu v XML, než pomocou kódu. Je potrebné upraviť XML súbor, ktorý nájdete v res/menu/activity_main.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item    
    android:id="@+id/nastavenie_casu" 
    android:title="@string/nastav_cas">
</item>
</menu>

Eclipse vám v tomto bode vyhodí chybu, pretože sme nenastavili referenciu nastav_cas, ktorá bude zobrazovať text položky v menu. Urobte tak v res/values/strings.xml. (v minulej časti sme si ukázali ako pridať referenciu na string).

Ak používateľ klikne položku v menu, vyvolá sa metóda onMenuItemSelected(). Tú je potrebné pridať do nášho kódu nasledovne:

public boolean onMenuItemSelected(int id, MenuItem item) {
  switch(item.getItemId()) {
    case R.id.nastavenie_casu:
      nastavCas();
      return true;
    default:
  }
  return super.onMenuItemSelected(id, item);
}

Vo vyššie uvedenom kóde v podstate iba získame Id (ientifikátor) položky menu a pomocou podmienky switch vytvoríme akciu, ktorá sa má vykonať, po stlačení. Opäť nám Eclipse vypíše chybu, pretože sme použili metódu setTime(), ktorá zatiaľ neexistuje. Nastavíme si ju, aby zobrazila novú Activity (“nový pohľad”).

Aktivity

Activity, ďalej aktivita, je komponent aplikácie ponúkajúci obrazovku (pohľad) s ktorou môže používateľ komunikovať. Slúži napríklad na vyvolanie klávesnice pre telefonovanie, vytvorenie fotografie, poslanie e-mailu a podobne. Každá aplikácia sa obvykle skladá z niekoľkých aktivít, ktoré sú na seba naviazané. Vo väčšine prípadov  je jedna aktivita nastavená ako hlavná, ktorá je prezentovaná používateľovi pri spustení aplikácie. Táto aktivita potom otvára ďalšie aktivity. Vždy, keď otvoríme novú aktivitu, predchádzajúca je pozastavená no systém ju ukladá do zásobníka (tzv. “back stack”). Keď sa vytvorí nová aktivita, vloží sa do zásobníka a získava pozornosť používateľa, ktorý môže s ňou pracovať. Zásobník pracuje podľa mechanizmu “last in, first out” (LIFO), čo znamená, že keď používateľ skončil prácu s aktuálnou aktivitou a stlačí napríklad tlačidlo naspäť, odoberie sa zo zásobníka (zničí sa) a pokračuje predchádzajúca aktivita.

Aktivita sa v priebehu svojho života môže nachádzať v troch rôznych stavoch: resumed (aktivita je v popredí a používateľ má vstup), paused(ďalšia aktivita je v popredí a má vstup, a pôvodná môže byť čiastočne viditeľná. Systém ju môže zničiť.) a stopped(je na pozadí a nieje viditeľná, systém ju taktiež môže zničiť ak bude potrebovať pamäť). Prechody aktivít medzi jednotlivými stavmi sú volané pomocou spätnými volaniami tzv. callback. Tieto definujú životný cyklus aplikácie, ktorý je zásadný pre vývoj. Viac o životnom cykle sa dočítate tu.

Operačný systém ponúka celkom štyri rôzne komponenty a to:

  1. Activity: ponúka obrazovku a používateľské prostredie pre nejakú akciu. Každá aplikácia má bežne jednu hlavnú aktivitu a ďalšie asociované aktivity.
  2. Services: vykonávajú akcie na pozadí aplikácie bez používateľského prostredia (kontrolujú nový e-mail, prehrávajú hudbu a pod).
  3. Broadcast Receiver: dostáva oznámenie vysielané systémom a následne niečo urobí.
  4. Content Provider: sprístupňuje dáta pre iné aplikácie.

Ďalším pojmom, s ktorým sa stretneme je Intent (zámer). Intent je správa, ktorá sa používa na skok do komponentu alebo k prenosu informácií medzi komponentami (napríklad dve aktivity). Tri komponenty aplikácie (activity, service a broadcast receiver) sú týmito správami aktivované. Viac informácií si prečítate tu. Teraz si nastavíme novú aktivitu, ktorá sa vyvolá metódou nastavCas() a bude slúžiť pre zadávanie času odpočítavania pomocou komponentu scroller. Naučíme sa zároveň, ako prenášať informácie medzi jednotlivými aktivitami. Metódu nastavCas() nastavíme nasledovne:

private void nastavCas() {
  Intent i = new Intent(getBaseContext(), NastavenieOdpocitavania.class);
  startActivityForResult(i, 1);    
}

Tento Intent jednoducho spustí  novú aktivitu nazvanú NastavenieOdpocitavania a povie súčasnej aktivite, aby očakávala nejaký výsledok (v našom prípade to bude čas). Stlačte tlačidlo New v ľavom hodnom rohu Eclipse, vyberte priečinok Android a následne Android Activity. Zvolíme BlankActivity a zadajte názov NastavenieOdpocitavania. V súbore NastavenieOdpocitavania.java, pridajte nasledovný kód:

int secondsSet;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nastavenie_odpocitavania);
  Spinner spinner = (Spinner) findViewById(R.id.spinner);
  ArrayList<Integer> spinnerList = new ArrayList<Integer>();
  for (int i = 1; i <= 99; i++) {
   spinnerList.add(i);
  }
  ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this,
          android.R.layout.simple_spinner_item, spinnerList);
  adapter.setDropDownViewResource(
          android.R.layout.simple_spinner_dropdown_item);
  spinner.setAdapter(adapter);
  spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> parent,
      View view, int pos, long id) {
      secondsSet = (Integer)parent.getItemAtPosition(pos);
    }
    public void onNothingSelected(AdapterView<?> parent) {
      // Nerob nic.
    }
  });
}

Upravíme ešte používateľské prostredie v XML súbore res/layout/set_time.xml týmto kódom:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  >
  <Spinner
    android:id="@+id/spinner"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="50px"
    android:text="@string/spinner_text"
  />
  <Button
    android:id="@+id/ok_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/spinner"
    android:layout_marginLeft="10dip"
    android:onClick="tlacidloOk"
        android:text="@string/ok_text" />
  <Button
    android:id="@+id/cancel_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/spinner"
    android:layout_toRightOf="@id/ok_button"
    android:layout_marginLeft="10dip"
        android:text="@string/cancel_text" />
</RelativeLayout>

XML súbor definuje Spinner (pre výber hodnôt odpočítavania), dve tlačidlá (Ok, Zrušiť) a ich rozloženie. Spinner zobrazuje dáta, ktoré sme naplnili v podmienke číslami 1 až 99 (rozsah si môžete nastaviť ľubovoľný). Pole (Array) tieto dáta udržuje a ArrayAdapter medzi oboma prekladá. android.R.layout.simple_spinner_item a andandroid.R.layout.simple_spinner_dropdown_item sú preddefinované rozloženia v Androide a definujú vzhľad Spinnera a jeho rozbaľovacej ponuky. Samozrejme môžete si vytvoriť aj vlastné no tým sa v tejto časti zaoberať nebudeme.

onItemSelectedListener() nastavuje Listener (poslucháča), ktorý reaguje ak používateľ vyberie položku z ponuky a nastaví premennú sekundy vybranou hodnotou. Tlačidlá Ok a Zrušiť sme vytvorili pre to, aby sme mohli predať dáta naspäť do hlavnej aktivity. Vytvoríme si metódu, ktorá zareaguje keď používateľ stlačí tlačidlo Ok. Všimnite si v XML súbore, že sme pridali android:onClick="tlacidloOk". Takto sa bude volať naša nová metóda:

public void tlacidloOk (View view) {
  Intent i = new Intent();
  Bundle bundle = new Bundle();
  bundle.putInt("sekundy", secondsSet);
  i.putExtras(bundle);
  setResult(RESULT_OK, i);
  finish();
}

Bundle sa používa na uloženie informácie v Intente, aby mohla byť predaná do inej aktivity. Každá hodnota (v tomto prípade máme len jednu) je uložená pod nejakým menom (v našom prípade “sekundy”). Pre tlačidlo Zrušiť nie je potrebný Bundle, pretože nebudeme posielať  žiadne dáta. Stačí vytvoriť Intent a výsledok nastaviť na RESULT_CANCELED a zavolať funkciu finish(), ktorá ukončí aktuálnu aktivitu.

public void tlacidloZrusit (View view) {
  Intent i = new Intent();
  setResult(RESULT_CANCELED, i);
  finish();
}

Teraz musíme oblúžiť Intent na strane hlavnej aktivity, na čo slúži metóda onActivityResult(). Najskôr si definujeme premennú sekundyOdpocitavania a potom vložíme kód pod označením [ …. ]

private int sekundyOdpocitavania;  // prednastavena hodnota odpocitavania
[ .... ]
protected void onActivityResult(int requestCode, int resultCode, Intent i) {
  super.onActivityResult(requestCode, resultCode, i);
  if (resultCode == RESULT_CANCELED) {
    return;
  }
  assert resultCode == RESULT_OK;
  switch(requestCode) {
    case 1: //musime dat 1 tak ako sme to urobili na zaciatku v startActivityForResult
      Bundle extras = i.getExtras();
      sekundyOdpocitavania = extras.getInt("sekundy");
      countdownDisplay.setText(Long.toString(sekundyOdpocitavania));
      break;
    default:
      // neurob nic, neocakavame ziadne ine vysledky
    }
  }

Najskôr sme obslúžili RESULT_CANCELLED, pretože vo väčšine prípadov ho budete ignorovať a nastavovať return. Potom sme oblúžili RESULT_OK a v tomto prípade sme prijali dáta “sekundy” a nastavili se ich do textového poľa countdownDisplay. Posledná vec, ktorú musíme urobiť je upraviť tlačidlo Štart:

showTimer(sekundyOdpocitavania * MILLIS_PER_SECOND);

Spustenie aplikácie na smartfóne

Pre niektoré prípady je vhodné vyskúšať vašu aplikáciu na reálnom Android zariadení než v simulátore. Ide najme o využitie hardvéru ako napríklad akcelerometra a podobne. Stačí ak pripojíte vaše zariadenie k počítaču pomocou USb kábla a v nastaveniach povolíte “Ladenie zariadenia USB” vo vývojárskych možnostiach. Keď stlačíte tlačidlo pre spustenie v Eclipse, objaví sa vám možnosť pre spustenie aplikácie na vašom smartfóne alebo tablete.

Android programovanie Android programovanie Android programovanie

 ->Hotový Android projekt si stiahnete tu<-

13.4.2013

Pravidlá diskusie

Portál MojAndroid.sk si vyhradzuje právo zmazať neslušné, rasistické a vulgárne príspevky, ako aj osobné útoky na redakciu, či diskutérov v komentároch pod článkom bez ďalšieho upozornenia. V prípade uverejňovania odkazov na externé stránky, je komentár automaticky preposlaný do redakcie na schválenie.

+