Programování pro Android v příkladech

Lukáš Marek 10. 3. 2011

Tutoriálů a různých příkladů věnujících se programování pro Android je na webu velké množství. Proč tedy vlastně psát další? Android prochází rychlým rozvojem a co platilo včera, již nemusí platit dnes. Článek vybírá několik častých programátorských oříšků a jejich řešení v Androidu 2.0 a vyšším.

Disclaimer

Uvedené příklady fungují na Android 2.0 a vyšších a jsou založeny na zkušenostech získaných při vytváření reálných aplikací pro Android. Ukázky jsou zaměřeny primárně na Contacts API, nicméně principy by měly být univerzální.

A ještě jedna věc. Pokud se v Androidu moc nevyznáte, přečtěte si nejdřív články Pavla Petřeka.

Získání kontaktu

Začneme malou rozcvičkou. Řekněme, že chceme nechat uživatele vybrat kontakt z telefonního seznamu a s tímto kontaktem dále pracovat.

Filosofie Androidu tento úkol značně zjednodušuje, protože samotný výběr není nutné vyvíjet – lze ho nechat na ostatních aplikacích. Než si ale ukážeme jak, bude dobré si pár slovy zmíněnou filozofii přiblížit.

Activity a Intenty

Typická aplikace pro Android (stejně jako aplikace pro jiné OS) se skládá z několika obrazovek. V terminologii Androidu se obrazovkám říká Activity. Nic nového pod sluncem.

Teď ovšem přijde to zajímavé – ve správné aplikaci jsou jednotlivé Activity navrhované tak, aby fungovaly zcela samostatně. Například tím, že mají jasně definované vstupy a výstupy. Takže ve své aplikaci můžete zavolat Activity z jiné aplikace a uživatel to v podstatě nepozná.

Analogicky je možné zaregistrovat libovolnou Activity, kterou pak mohou používat ostatní aplikace v telefonu. Mimochodem, zajímavý seznam volně dostupných aktivit je na OpenIntents.

Řekli jsme, že správně navržená Activity musí mít definované vstupy a výstupy. K tomu jsou v Androidu tzv. Intents. Intent je zkratka slova intetion, tedy úmysl. Použitím Intent u tedy systému sděluji, co mám v úmyslu, a nechávám na něm, jak můj úmysl splní.

Android postupuje tak, že vyhledá všechny Activity, které mohou daný Intent splnit, a pokud je jich více, dá uživateli vybrat. Příslušná Activity je poté nastartována a je jí předán konkrétní Intent jako vstup.

Rada nad zlato: než se vrhnete do programování, zjistěte, jestli si nemůžete ušetřit práci použitím existující aktivity. Kromě volného času tím získáte i spokojenějšího uživatele, který nebude zmaten novým vzhledem známé funkce.

Získání kontaktu II

Jsme zpět u rozcvičky. Takže jak se vyhledává kontakt v telefonu plném aktivit a intentů? Jednoduše:

  private static final int ACTIVITY_PICK_CONTACT = 42;

    private void pickContact() {
      Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
      startActivityForResult(intent, ACTIVITY_PICK_CONTACT);
    }

V prvním řádku metody pickContact() říkáme, že máme v úmyslu vybrat ( ACTION_PICK) konkrétní kontakt ( Contacts.CONTENT_URI) z telefonního seznamu. Druhým žádáme operační systém, aby našel a spustil příslušnou aktivitu. ACTIVITY_PICK_CONTACT je víceméně libovolná konstanta, kterou budeme potřebovat, až se bude vracet řízení zpět.

Nyní tedy Android nastartuje standardní telefonní seznam a nechá uživatele vybrat jeden kontakt. Po kliknutí na kontakt zavolá systém opět naší aktivitu, konkrétně callback metodu onActivityResult(). Pro tu si musíme připravit implementaci. Tady je:

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
       switch (requestCode) {
          case (ACTIVITY_PICK_CONTACT) :
              if (resultCode == Activity.RESULT_OK) {
                  //hotovo, máme kontakt
                  Uri pickedContact = data.getData();
                  return;
              }
          break;
      }
  }

Jak je vidět, zde je použita konstanta ACTIVITY_PICK_CONTACT. Vybraný kontakt se předává opět jako Intent, konkrétně jako jeho property data. V případě, že je potřeba předat něco jiného než Uri, použijeme metodu getExtras(), která dovolí předat libovolný objekt.

Uri

Než se pustíme do dalšího příkladu, možná by stálo za to, vysvětlit si pojem Uri. Nemám na mysli ani tak samotný pojem URI, ten asi čtenáři Roota znají dobře, ale jeho použití v Androidu. Nechci zde duplikovat vývojářskou příručku, takže jen krátce.

Obsah (tedy kontakty, SMSky, fotky, …) Android telefonu je v zásadě dostupný všem aplikacím bez rozdílu. O přístup k jednotlivým položkám se starají tzv. Content Providers. Content Providers zapouzdřují práci s obsahem – vyhledávání, editaci, mazání apod. Uri vyjadřuje za prvé typ obsahu a za druhé může, ale nemusí ukazovat i na konkrétní záznam.

Takže například jeden určitý kontakt bude mít takovéto  Uri:

content://com.android.contacts/contacts/666

Vytvoření dialogu

Dost bylo odboček, pojďme se podívat, jaký kontakt si uživatel vybral. Pro začátek zkusíme zobrazit Uri kontaktu v dialogu. Nějak takhle:

Zobrazení alertu nemůže přece být nic složitého? A opravdu není:

  new AlertDialog.Builder(this).
    setTitle("URI kontaktu").
    setMessage(pickedContact.toString()).
    setCancelable(true).
    setPositiveButton("OK", null).
    create().
    show();

Jediná „drobnost“ – takto vytvořený alert při otočení telefonu a změně orientace displeje spadne a vezme s sebou celou aplikaci (zkuste si to).

Tak na to správně po androidsku? Je nutné předefinovat metody onCreateDialog()onPrepareDialog():

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_SHOW_CONTACT: {
                return new AlertDialog.Builder(this).
                        setTitle("URI kontaktu").
                        setCancelable(true).
                        setPositiveButton("OK", null).
                        create();
            }
        }
        return null;
    }

    @Override
    protected void onPrepareDialog(int id, Dialog dialog) {
        switch (id) {
            case DIALOG_SHOW_CONTACT: {
                ((AlertDialog)dialog).setMessage(pickedContact.toString());
            }
        }

První z metod volá systém při vytváření dialogu, což znamená, že se zavolá pouze jedenkrát. Dále už je „recyklován“ vytvořený dialog opakovaným voláním druhé metody, čehož využijeme k nastavení správného textu k zobrazení. Všimněte si, že jsme museli definovat další konstantu, podle které rozlišujeme, jaký dialog se bude vytvářet. Samotné zobrazení pak zajistíme voláním:

   showDialog(DIALOG_SHOW_CONTACT);

Jistě vám neušlo, že v metodě showDialog() není možné předat konkrétní data k zobrazení. To se většinou řeší nastavením proměnné třídy, kterou si poté metoda onPrepareDialog() přečte. A poslední zrada – tato proměnná musí být statická, aby přežila znovuvytvoření aktivity a dialogu při změně orientace displeje.

Naštěstí se blýská na lepší časy. Od verze 2.2 je možné přidat do volání showDialog() objekt typu Bundle, takže vytváření dialogů bude o něco jednodušší.

widgety

Co bude příště?

V příštím článku si zkusíme vytáhnout základní údaje kontaktu – telefonní číslo, e-mail, fotku. A pak se je naučíme změnit.

Celý zdrojový kód příkladu je k dispozici na Githubu.

Našli jste v článku chybu?
Lupa.cz: Další Češi si nechali vložit do těla čip

Další Češi si nechali vložit do těla čip

DigiZone.cz: Konference Radiokomunikace se blíží

Konference Radiokomunikace se blíží

Lupa.cz: Jak levné procesory změnily svět?

Jak levné procesory změnily svět?

DigiZone.cz: Parlamentní listy: kde končí PR...

Parlamentní listy: kde končí PR...

Vitalia.cz: dTest odhalil ten nejlepší kečup

dTest odhalil ten nejlepší kečup

Podnikatel.cz: Takhle se prodávají mražené potraviny

Takhle se prodávají mražené potraviny

DigiZone.cz: DVB-T2 ověřeno: seznam TV zveřejněn

DVB-T2 ověřeno: seznam TV zveřejněn

DigiZone.cz: Rapl: seriál, který vás smíří s ČT

Rapl: seriál, který vás smíří s ČT

Lupa.cz: Blíží se konec Wi-Fi sítí bez hesla?

Blíží se konec Wi-Fi sítí bez hesla?

Podnikatel.cz: Znáte už 5 novinek k #EET

Znáte už 5 novinek k #EET

DigiZone.cz: Digi Slovakia zařazuje stanice SPI

Digi Slovakia zařazuje stanice SPI

Vitalia.cz: Jak Ondra o astma přišel

Jak Ondra o astma přišel

DigiZone.cz: Samsung EVO-S: novinka pro Skylink

Samsung EVO-S: novinka pro Skylink

Vitalia.cz: Fyzioterapeutka: Chůze naboso? Rozhodně ano!

Fyzioterapeutka: Chůze naboso? Rozhodně ano!

Vitalia.cz: 5 chyb, které děláme při skladování potravin

5 chyb, které děláme při skladování potravin

Podnikatel.cz: Instalatér, malíř a elektrikář. "Vymřou"?

Instalatér, malíř a elektrikář. "Vymřou"?

DigiZone.cz: Na jaká videa se vlastně díváme

Na jaká videa se vlastně díváme

DigiZone.cz: Wimbledon na Nova Sport až do 2019

Wimbledon na Nova Sport až do 2019

DigiZone.cz: Česká televize otevírá další studio

Česká televize otevírá další studio

Vitalia.cz: Muž, který miluje příliš. Ženám neimponuje

Muž, který miluje příliš. Ženám neimponuje