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()
a 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šší.
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.