Sem vložte zadání Vaší práce.
České vysoké učení technické v Praze Fakulta informačních technologií Katedra softwarového inženýrství
Bakalářská práce
Moje lékárna: klient pro Android Aliaksandr Maksimau
Vedoucí práce: Ing. Zdeněk Troníček, Ph.D.
17. května 2013
Poděkování Rád bych poděkoval panu Ing. Zdeňku Troníčkovi, Ph.D. za jeho cenné rady, připomínky a odborné vedení při zpracování této bakalářské práce.
Prohlášení Prohlašuji, že jsem předloženou práci vypracoval samostatně a že jsem uvedl veškeré použité informační zdroje v souladu s Metodickým pokynem o etické přípravě vysokoškolských závěrečných prací. Beru na vědomí, že se na moji práci vztahují práva a povinnosti vyplývající ze zákona č. 121/2000 Sb., autorského zákona, ve znění pozdějších předpisů, zejména skutečnost, že České vysoké učení technické v Praze má právo na uzavření licenční smlouvy o užití této práce jako školního díla podle § 60 odst. 1 autorského zákona.
V Praze dne 17. května 2013
.....................
České vysoké učení technické v Praze Fakulta informačních technologií c 2013 Aliaksandr Maksimau. Všechna práva vyhrazena.
Tato práce vznikla jako školní dílo na Českém vysokém učení technickém v Praze, Fakultě informačních technologií. Práce je chráněna právními předpisy a mezinárodními úmluvami o právu autorském a právech souvisejících s právem autorským. K jejímu užití, s výjimkou bezúplatných zákonných licencí, je nezbytný souhlas autora.
Odkaz na tuto práci Maksimau, Aliaksandr. Moje lékárna: klient pro Android. Bakalářská práce. Praha: České vysoké učení technické v Praze, Fakulta informačních technologií, 2013.
Abstract The thesis deals with the development of mobile client for OS Android for „Moje Lékárna“ system, which should fulfill all the functions of the web interface and extend the use of the system among people. The main objective of the application is to search the lowest price for the cart of medicines in the nearest pharmacies. Applications should be beneficial for everyone, because price lists and information about pharmacies would be on hand. Keywords pharmacy, prescription, medicine, Android, Google, mobile devices
Abstrakt Práce se zabývá vývojem mobilního klienta pro OS Android pro systém „Moje Lékárna“, který by měl plnit všechny funkce webového rozhraní a rozšířit použití tohoto systému. Hlavním cílem aplikace je vyhledávaní nejnižší ceny košíku léků v nejbližších lékárnách. Aplikace by měla být přínosná pro všechny, protože přehled cen a informací o lékárnách bude vždy po ruce. ix
Klíčová slova lékárna, recept, lék, Android, Google, mobilní zařízení
x
Obsah Úvod Uvedení do problematiky . . . . . . . . . . . . . . . . . . Stanovení cílů a požadavků na implementovaný produkt Popis struktury bakalářské práce . . . . . . . . . . . . . Rešeršní zpracování podobných implementací . . . . . .
. . . .
1 1 4 5 5
1 Analýza 1.1 Analýza požadavků . . . . . . . . . . . . . . . . . . . . . . . 1.2 Analýza případů užití . . . . . . . . . . . . . . . . . . . . . .
9 9 12
. . . .
. . . .
. . . .
. . . .
2 Návrh 15 2.1 Základy aplikací pro Android . . . . . . . . . . . . . . . . . 15 2.2 Návrh uživatelského rozhraní . . . . . . . . . . . . . . . . . . 17 2.3 Návrh architektury . . . . . . . . . . . . . . . . . . . . . . . 19 3 Realizace 3.1 Skenovaní čárových kódů . . . . 3.2 Propojení s API . . . . . . . . . 3.3 Práce na pozadí . . . . . . . . . 3.4 Použití Content Providers . . . 3.5 Vkládání velkého množství dat . 3.6 Použití Native Development Kit 3.7 Zpětná kompatibilita . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
21 21 23 24 26 26 27 28
4 Testování 29 4.1 Unit testy . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.2 Integrační testy . . . . . . . . . . . . . . . . . . . . . . . . . 30 xi
4.3
Systémové testy . . . . . . . . . . . . . . . . . . . . . . . . .
30
Závěr
31
Literatura
33
A Seznam použitých zkratek
35
B Instalační příručka 37 B.1 Instalace z CD . . . . . . . . . . . . . . . . . . . . . . . . . 37 B.2 Instalace z Google Play . . . . . . . . . . . . . . . . . . . . . 37 C Obsah přiloženého CD
39
xii
Seznam obrázků 0.1 0.2 0.3
Vzhled aplikace „České lékárny“ [12] . . . . . . . . . . . . . . . Vzhled aplikace „Lékař doma“ [13] . . . . . . . . . . . . . . . . Vzhled aplikace „tabletka.by“ [11] . . . . . . . . . . . . . . . .
6 7 8
1.1
Diagram případů užití . . . . . . . . . . . . . . . . . . . . . . .
13
2.1
Návrh uživatelského rozhraní . . . . . . . . . . . . . . . . . . .
18
xiii
Seznam tabulek 1.1
Verze OS Android
. . . . . . . . . . . . . . . . . . . . . . . . .
12
3.1
Testování rychlostí vkládaní dat . . . . . . . . . . . . . . . . . .
27
xv
Úvod Používání informačních technologií je v dnešním životě již naprostou nezbytností – výjimkou není ani oblast zdravotnictví. Informační technologie mají za úkol pomáhat lidem a usnadnit jejich život. Tímto problémem se budu ve své bakalářské práci na téma „Moje lékárna: klient pro Android“ zabývat i já. Jedná se o aplikaci, která umožní pomocí mobilního telefonu najít v okolí lékárnu s nejnižší cenou vybraných léků či nejnižším doplatkem za vybrané léky. Toto téma jsem si zvolil, protože zatím neexistuje obdobný program. Takový program by pomáhal mnoha lidem a byl by tak velice užitečný pro společnost. Je to taky práce se zajímavými novými technologiemi, a vypracování bude přínosné i pro mě. Výsledkem bakalářské práce by měl být úspěšný vývoj a zprovoznění programu. Aplikace by byla velice přínosná pro každého: lidé by měli větší přehled o cenách a službách lékáren, ušetřili by čas při hledání léků a peníze při nákupu; lékárnám by se zvýšila návštěvnost a byl by to pro ně další marketingový kanál a způsob jak se zviditelnit.
Uvedení do problematiky Lékárny prodávají různé léky, ale ne všechny se prodávají stejně. Každý lék má striktně uvedené podmínky, jak se má prodávat. Většina léků je volně dostupná a takové léky si může koupit kdokoliv bez jakýchkoliv omezení. Jsou to léky, „které mají nízkou toxicitu i nízké riziko závažných nežádoucích účinků, které mohou být používány u onemocnění, která si pacient dokáže určit sám (tzv. samodiagnóza) a riziko ohrožení zdraví při nesprávném užívání přípravku je nízké, jejichž užívání by nemělo 1
Úvod zakrýt příznaky závažnějšího onemocnění, které pacient nerozpozná, a nevyhledá tak včas lékaře“[17]. Tyto léky jsou volně dostupné i přes internet a není tudíž nutné jít do lékárny. Pak existuje skupina léků, které se prodávají s omezením. Takové léky „mohou přímo nebo nepřímo představovat nebezpečí pro zdraví lidí, neboť jsou často a v širokém rozsahu používány nesprávně nebo jejich správné použití předpokládá nezbytně odbornou poradu s farmaceutem. Jako omezení pro výdej může být stanovena např. věková hranice, množství balení, které je možné poskytnout v rámci jednoho výdeje, zákaz zásilkového (internetového) výdeje apod. Lék zařazený do této skupiny je možné vydat pouze osobě, které je určen. Lékárník povinně vede dokumentaci o jeho výdeji v požadovaném rozsahu. Výdej těchto léků je možný pouze v lékárnách“[17]. Poslední skupina léků, je tvořená z léků, které se prodávají pouze po předložení lékařského předpisu. Do této skupiny většinou patří přípravky, „které mohou i při správném používání představovat přímé nebo nepřímé nebezpečí, pokud jsou použity bez lékařského dohledu, které jsou často a ve velmi širokém rozsahu používány nesprávně a v důsledku toho mohou představovat přímé nebo nepřímé nebezpečí pro zdraví lidí, obsahují látky nebo přípravky z látek, jejichž účinnost nebo nežádoucí účinky vyžadují další sledování, nebo jsou určeny k parenterálnímu podání, jejichž použití může vyvolat velmi závažné nežádoucí účinky vyžadující, aby lékařský předpis byl vystaven podle požadavků odborného lékaře a aby byl zajištěn zvláštní dohled během léčby. Výdej těchto léků je možný pouze v lékárnách“[17]. Jakmile člověk onemocní závažnou nemocí, s největší pravděpodobností se obrátí na svého lékaře. Podle zdravotního stavu nemocného lékař stanoví diagnózu a může předepsat léky. podle zákona je možné na jeden předpis předepsat jeden druh léčivého přípravku, který obsahuje omamné látky nebo psychotropní látky, nebo dva druhy ostatních léčivých přípravků. Každý lékařský předpis musí obsahovat povinné údaje, mezi které patří jméno, příjmení, adresa pacienta, označení zdravotní pojišťovny (pokud je léčivý přípravek hrazen z veřejného zdravotního pojištění) a předepsaný léčivý přípravek (přípravky). Na receptu jsou označení, která nejsou povinná, ale jsou důležitá. Do takových označení patří: „Nezaměňovat“ jestliže předepisující lékař trvá na vydání předepsaného léčivého přípravku, „Hradí nemocný“ jestliže léčivý přípravek není hrazen z veřejného zdravotního pojištění nebo lékař nemá smlouvu se zdravotní pojišťovnou pacienta, „Zvýšená úhrada“ jde-li o předpis léčivého přípravku, který má podle jiného právního předpisu 2 výše úhrady a předepisující lékař požaduje využití úhrady vyšší.[7] Po návštěvě nebo bez návštěvy lékaře se nemocný rozhoduje, kde zakoupí potřebné léky. V případě potřeby volně prodejného léku je možné 2
Uvedení do problematiky navštívit webové stránky lékáren, kde se kupující zároveň informuje o výši ceny. Kdyby šlo o lék vydávaný bez lékařského předpisu s omezením, člověk také dovede dohledat cenu přes vyhledávací servisy nebo na stránkách lékáren, najde nejlevnější lékárnu, ale pak se bude muset dostavit pro léky osobně. Ovšem, pokud by daný člověk měl recept na nějaké léky, buď volně dostupný (v tomto případě by člověk měl výhodu, že by neplatil za lék částku v plné výši, ale pouze doplatek), nebo prodávaný pouze na recept, nedovede již jednoduše zjistit cenu toho léku v konkrétní lékárně. Pomocí informace na stránkách SÚKL nebo na jiných informačních serverech, je možné zjistit pouze orientační cenu léku, která může zajímat pacienta pouze v případě, že bude hradit celou částku. Ze stejných zdrojů lze zjistit i maximální možný doplatek za lék, což zajímá většinu lidí. Následně je problém, že pacienta zajímá cena u všech léků, vyjma těch, jenž jsou plně hrazeny pojišťovnou. Naproti tomu však lékárny většinou nemají uvedené ceny u veškerých léků prodávaných pouze na recept. Pouze když lék je plně hrazen pojišťovnou, cena pacienta nezajímá. Tudíž je třeba zmínit důležitý pojem generický lék, co znamená alternativní lék, který „obsahuje stejné léčivo ve stejném množství jako příslušný originální přípravek, má i stejnou lékovou formu, např. tablety a tobolky, a stejnou biologickou účinnost. Typ a poměr použitých pomocných látek (plniv, pojiv, barviv apod.) může být od originálu odlišný“[15]. Z toho plyne generická substituce, což je možnost „aby lékárník při výdeji informoval pacienta o možných alternativách k předepsanému léku a případně jej s jeho souhlasem zaměnil. Taková záměna je možná pouze v případě, že alternativní lék je s předepsaným shodný z hlediska jeho účinnosti a bezpečnosti“[16] a „obsahuje stejnou léčivou látku se stejnou cestou podání a stejnou lékovou formou. Pokud alternativní lék (substitut) obsahuje rozdílné množství léčivé látky (rozdílná síla), lékárník upraví dávkování tak, aby odpovídalo dávkování předepsanému lékařem. V případě záměny je tato skutečnost uvedena na receptu“[16]. Občas by člověk rád koupil levnější analog léku (když není uvedené v předpisu, že se lék nesmí zaměňovat). Ne každá lékárna má možnost zjistit ceny generik, a tím že člověk musí porovnat více léků (přičemž generické léky nemusí mít stejné balení, nebo sílu účinné látky) se úloha porovnávání stává ještě obtížnější. Problém vypadá tak, že v polovině případů kupující nemá možnost zjistit přesnou cenu nebo doplatek za lék. A ještě složitější je porovnat nabídky lékáren při nákupu různých položek nebo při hledání substitutů léků. V případě hledání léků na předpis je úloha skoro nevyřešitelná. 3
Úvod Dalším problémem pro člověka stává počítání již uhrazené částky na doplatcích za léky na recept s částečnou úhradou a úhrady regulačních poplatků. V závislosti na věku každý klient zdravotní pojišťovny má ochranný limit. Ochranný limit je částka, po jejímž překročení již budou všechny poplatky klientovi vrácené pojišťovanou. Limit se liší podle věku pojištěnce, a to tak, že pro pojištěnce do 18 let a od 65 činí 2500 Kč za kalendářní rok (včetně roku kdy dovršily 18 a 65 let) a 5000 Kč u ostatních pojištěnců.[9, §16b] Do ochranného limitu se započítává několik typů regulačních poplatků: 30 Kč za návštěvu u lékaře (i v případě, když lékař navštíví pacienta doma), 30 Kč za recept a doplatky zaplacené za léky koupené na recept. Ale ne vždy se započte celý doplatek. Doplatek se započítává v plné výši v případě, že je na receptu uvedené „Nezaměňovat“, v ostatních případech se postupuje podle následujícího pravidla: vyhledávají se doplatky za všechny léky, které mají stejnou účinnou látku se stejnou cestou podání a stejnou lékovou formou jako lék na receptu, a započítává se ten nejmenší doplatek. „V případě, že by byl některý z uvedených léků plně hrazen ze zdravotního pojištění, poté se započitatelný doplatek rovná 0 Kč. Doplatek u podpůrných nebo doplňkových léků, které jsou uvedeny ve vyhlášce o stanovení seznamu léčivých látek určených k podpůrné a doplňkové léčbě, se započítává pouze u osob starších 65 let (včetně dne, kdy dovršily tento věk).“[14][9, §16] Z toho je zřejmé, že počítání doplatků do výše ochranného limitu není jednoduchá záležitost a pacienti by jistě uvítali, kdyby jim výpočet provedl podpůrný program.
Stanovení cílů a požadavků na implementovaný produkt Existující problém je možné efektivně a elegantně vyřešit za použití informačních technologií, což by měl udělat systém „Moje lékárna“. Systém má zatím pouze webové uživatelské rozhraní. Cílem mé bakalářské práce je implementace klienta k existujícímu systému pro OS Android, aby zpopularizoval a rozšířil použití systému. Aplikace by měla být nasazena do provozu a měla by plnit všechny funkce webové verze. Klient by měl být podporován ve většině Android zařízeních a fungovat na mobilních telefonech a tabletech. Aplikace by měla mít spolehlivou architekturu a umožňovat přidávání nových funkcí v budoucnu. Pro uživatele by se měla aplikace stát pohodlným a užitečným prostředkem pro zjištění cen léků a informací o lékárnách. 4
Popis struktury bakalářské práce
Popis struktury bakalářské práce Tato implementační bakalářská práce má 5 částí: • Úvod – seznámení s problematikou, stanovení cílů a přehled podobných implementací. • Analýza – analýza požadavků a případů užití • Návrh – návrh architektury a uživatelského rozhraní aplikace • Realizace – implementace aplikace a výsledná realizace. • Testování – testování výsledné aplikace.
Rešeršní zpracování podobných implementací Jelikož Google Play1 je oficiální online distribuční služba aplikací pro chytré telefony a tablety s Androidem, proto jsem právě tam hledal aplikace, které by měly obdobnou funkcionalitu. Podařilo se mi najít 3 aplikace, které mají společné prvky s mojí aplikací aplikací. Jsou to české aplikace „České lékárny“ a „Lékař doma“, a zahraniční aplikace „tabletka.by“.
České lékárny Po dlouhou dobu toto byla jediná česká aplikace spojená se zdravotnictvím na Google Play. Je to jednoduchá a na užívání pohodlná aplikace, která má pouze jednu funkci – vyhledávání lékáren, tuto funkci plní docela dobře. České lékárny má pouze 2 obrazovky, první je mapa s lékárnami (viz. obr 0.1a) a druhá je informace o zvolené lékárně (viz. obr 0.1b). Je tam možnost vyhledávat lékárnu podle názvu, města nebo ulice bez diakritiky a možnost oslovit vývojáře i za účelem přidání nové lékárny. Mezi další užitečné vlastnosti patří možnost zavolat do lékárny a být navigován do zvolené lékárny přes externí aplikaci. Z toho, že je možnost hlásit nové lékárny, vyplývá, že se aplikace neaktualizuje automaticky a nové lékárny se přidávají pouze s vydáním nové verze programu, což je nevýhoda. Mezi nedostatky také patří nepřítomnost údajů o otevírací době lékáren. I přes to, že aplikace má nedostatky, je docela dobře udělaná a je možné inspirovat se určitými částmi. 1
https://play.google.com/store
5
Úvod
(a) Hlavní obrazovka
(b) Informace o lékárně
Obrázek 0.1: Vzhled aplikace „České lékárny“ [12]
Lékař doma Je srovnatelná nová mobilní aplikace, která se objevila v době, když už jsem se blížil ke konci implementace programu. Jedná se o aplikace od českých vývojářů, která je především určená k stanovení diagnózy (viz. obr 0.2a) podle odpovědí uživatele na otázky ohledně jeho zdravotního stavu a doporučování léků v případě, že je to možné i bez lékaře. Aplikace „Lékař doma je komplexní“ a dobře propracovaná. Obsahuje informaci o každém léku a o hodně nemocích. Na rozdíl od aplikace „České lékárny“ má nejenom seznam lékáren, ale i nemocnic a lékařů. Jako „České lékárny“ má stejnou možnost zavolat a nechat se navigovat do zdravotnického zařízení a stejně neobsahuje údaje o otevírací době. Za užitečné funkce považuji možnost vytvořit nákupní seznam léků, možnost přidávat připomínky ohledně užívání léků a upomínky o návštěvách lékaře a diagnózách. Aplikace stahuje aktualizace při každém startu, proto není nutné stahovat novější verzi za účelem obnovy informací. Aplikace má i nedostatky. Jako jeden z menších je neexistence možnosti vyhledat zdravotnické zařízení podle ulice. Jako největší nedostatek, je technická nedokonalost: při použití aplikace uživatel zjišťuje, že aplikace často nereaguje na uživatelské akce nebo občas „zamrzne“. Je to důsledek toho, 6
Rešeršní zpracování podobných implementací
(a) Diagnóza
(b) Informace o léku
(c) Mapa s zdravotnickými zařízení
Obrázek 0.2: Vzhled aplikace „Lékař doma“ [13]
že náročné operace (čtení a zápis do databáze, síťová komunikace) neprobíhají ve vlastním vláknu na pozadí, ale provádí se v hlavním UI-vláknu. Což je zřejmě chyba vývojářů. Celkově je aplikace udělaná dobře a určitě je přínosná pro veřejnost. Program poskytuje užitečné funkce, z nichž většinu neposkytuje žádná jiná aplikace.
tabletka.by „tabletka.by“ je představitel běloruské aplikace určené k vyhledávání cen léků v lékárnách a lékáren v okolí. Dříve program existoval pouze v podobě webové aplikace a od letošního roku se objevila mobilní verze pro OS Android. Je to velice jednoduchá ale dobře propracovaná aplikace. Vyhledává léky s možností hledání léků se stejnou účinnou látkou v okolí zadaného města. Stačí zadat název léků a město na první obrazovce (viz. obr 0.3a), zvolit potřebný lék na druhé obrazovce (viz. obr 0.3b), a na třetí obrazovce uživatel uvidí ceny v jednotlivých lékárnách. Existuje možnost podívat se do mapy (viz. obr 0.3c), kde se lékárna přesně nachází, zjistit otevírací dobu, zavolat nebo navigovat do zvolené lékárny. Aktualizace se vždy provede při spouštění, tudíž jsou data stále aktuální. Rozhodně „tabletka.by“ je kvalitní aplikace, která splňuje veškeré požadavky, které jsou na ni kladené. 7
Úvod
(a) Hlavní obrazovka
(b) Upřesnění léků
(c) Mapa s lékárnami
Obrázek 0.3: Vzhled aplikace „tabletka.by“ [11]
8
Kapitola
Analýza 1.1
Analýza požadavků
Na začátku práce nad projektem byla provedená důkladná analýza problematiky. V úvahu se braly existující řešení a požadavky na aplikaci. Aplikace by měla splňovat řadu požadavků, jak funkčních tak i nefunkčních. K funkčním požadavkům patří: • Aplikace umožní uživateli vyhledat lékárny s nejnižší cenou léků či nejnižším doplatkem za léky • Aplikace umožní počítání uhrazených doplatků a regulačních poplatků • Aplikace umožní uživateli vyhledat nejbližší lékárny v okolí • Nalezené lékárny aplikace umožní zobrazit v mapě K nefunkčním požadavkům patří: • Aplikace musí komunikovat s jádrem aplikace „Moje lékárna“ • Aplikace musí být podporována 90 % mobilních zařízení s OS Android • Rozhraní musí být uživatelsky přívětivé Jelikož se server vyvíjel paralelně s klientem, počáteční požadavky byly rozšířené a doplněné. Dále podrobně rozeberu všechny požadavky. 9
1
1. Analýza
1.1.1
Vyhledávání lékárny s nejnižší cenou léku či nejnižším doplatkem za léky
Hlavní funkce aplikace je možnost nalézt lékárny s nejnižší cenou sady léků nebo nejnižším doplatkem za léky. Uživatel by měl možnost zadat léky, které by chtěl koupit a aplikace by měla poslat požadavek na server a zobrazit výsledky vyhledávaní. Pro pohodlnější použití bylo vyřešeno, že sada léků pro vyhledávání bude představená košíkem s léky a recepty (položka obsahující do dvou léků pro vyhledávání ceny doplatků). následně se objevily další funkční požadavky jako ukládání a synchronizace košíků a receptů.
1.1.2
Ukládání a synchronizace košíků a receptů
Pro pohodlnější použití by si aplikace měla pamatovat léky vyhledané uživatelem ve formě košíků a receptů. Položky by měly být aktuální jak na klientovi, tak i na serveru a měly by se synchronizovat. Uživatel by mohl zvolit jeden z uložených košíků a vyhledat jej znovu. Tím vznikne možnost použití uložených receptů i v nových košících.
1.1.3
Počítání uhrazených doplatků a regulačních poplatků
Jelikož počítání doplatků není jednoduché, aplikace by měla uživateli vypočíst již zaplacené regulační poplatky a doplatky za léky a zobrazit kolik zbývá do dosažení ochranného limitu. Veškeré výpočty by se měly provádět na základě údajů uvedených uživatelem. Tyto údaje by se měly ukládat a synchronizovat se serverem.
1.1.4
Vyhledávání nejbližší lékárny v okolí
Uživateli se zobrazí seznam lékáren, který bude seřazen dle vzdáleností od uživatele. Poloha uživatele by měla být zjištěná pomocí služeb mobilního zařízení jako například GPS nebo informace z mobilních stanic.
1.1.5
Nalezené lékárny aplikace umožní zobrazit v mapě
Pro pohodlnou orientaci by všechny výsledky vyhledávání měly být zobrazeny na mapě. V OS Android lze pro zobrazení použít Google Mapy, které 10
1.1. Analýza požadavků poskytují sadu užitečných nástrojů pro zobrazení, jsou přesné a kvalitně zpracované.
1.1.6
Komunikace s jádrem aplikace „Moje lékárna“
I když jsou moderní telefony s operačním systémem Android výkonné skoro jako počítače, velké výpočty a analýzu dat je mnohem lepší provádět na straně serveru. Důvodu je mnoho, patří mezi ně: velký počet aplikací běžících paralelně v mobilním zařízení, a tím menší počet systémových prostředků pro každou z nich; velký počet grafických prvků a náročné animace ke zpracování, což zabírá většinu výkonu zařízení, protože mobilní telefony nemají grafické adaptéry, a všechno se zpracovává procesorem; omezení paměťové kapacity; nedokonalé a poměrné drahé internetové připojení. Oproti tomu servery jsou velice výkonné, nejsou zatížené neúčelovými aplikacemi a zpracováním náročné grafiky, mají velké paměťové zásoby a jsou vysoce škálovatelné. Tyto důvody vedou k tomu, aby se mobilní verze aplikací chovala jako klient bez provádění náročných výpočtů, a nechávala co nejvíc práce serveru, jádru aplikace, s kterým by se synchronizovala a komunikovala prostřednictvím webových služeb. Hlavním důvodem, proč by nestačil samostatný klient, je to, že klient nemá přehled o cenách v lékárnách, což lze velice těžko zajistit z mnoha hledisek (nestačila by paměť pro uložení všech cen, nepodařilo by se provádět aktualizace v reálném čase z důvodu rychlosti internetového připojení a velkých objemů dat, bylo by složitější zajistit poskytování dat ze strany lékáren).
1.1.7
Podpora 90 % mobilních zařízení s OS Android
Android je moderní dynamická mobilní platforma, která je založena na jádru Linux. Stovky milionů mobilních zařízení po celém světě obsahují tento operační systém. Android patří společnosti Google a vyvíjí se konsorciem Open Handset Alliance a společnosti Google. První verze Androidu byla oficiálně zveřejněná 23. září 2008. Od té doby popularita Android den ode dne roste. Je to podmíněné tím, že Android se neustále zlepšuje a mění. Každý rok se vydává několik nových verzí s novými funkcemi. Verze Android jsou rozřazené podle API a podle verzí. Několik verzí může mít stejné API, tudíž stejné funkce. Se zvýšením API se přidávají nové funkce operačního systému (nové animace, podpora nového zařízení jako např. NFC, nové třídy a knihovny). Bohužel ne všechny změny jsou zpětně kompatibilní a často novější API klade větší nároky na hardwarovou 11
1. Analýza součást zařízení. V tabulce 1.1 jsou uvedené klíčové verze Android API a procentuální počet zařízení s odpovídajícími verzemi.[8] Version 1.6 2.1 2.2 2.3 - 2.3.2 2.3.3 - 2.3.7 3.2 4.0.3 - 4.0.4 4.1.x 4.2.x
Codename Donut Eclair Froyo Gingerbread Honeycomb Ice Cream Sandwich Jelly Bean
API 4 7 8 9 10 13 15 16 17
Distribution 0,1 % 1,7 % 3,7 % 0,1 % 38,4 % 0,1 % 27,5 % 26,1 % 2,3 %
Tabulka 1.1: Verze OS Android Je vidět, že zatím většina zařízení má Android s API 10, z čeho plyne, že aplikace musí být funkční minimálně na zařízeních s těmito verzemi Androidu. Neznamená to, že v aplikaci není možné použit funkce z vyšších verzí API, ale všechny použité funkce musí být zpětně kompatibilní.
1.1.8
Uživatelsky přívětivé rozhraní
Při vývoji Androidu se velký důraz klade na uživatelské rozhraní a styl aplikace, možná je to jeden z klíčů k úspěchu platformy. Na webových stránkách určených pro vývojáře je velká sekce, která popisuje konstrukční zásady aplikace. Jsou tam i pokyny a doporučení ke stylům, barvám, rozměrům, použití návrhových vzorů a předefinovaných prvků uživatelského rozhraní. Ve své práci se budu snažit držet se pokynů a doporučení ohledně uživatelského rozhraní. Toto není jednoduchý úkol v neustále se měnících pokynech v návaznosti se zaváděním nových verzí API. Tudíž není možné, aby byl každý nový element zpětně kompatibilní.
1.2
Analýza případů užití
Případy užití aplikace jsou představené na obrázku 1.1. Uživatel se pohybuje v aplikaci pomocí přepínání záložek nebo výběrem položky v menu. Takovým způsobem uživatel dovede: • Zobrazit košíky – zobrazí se seznam košíků 12
1.2. Analýza případů užití
Obrázek 1.1: Diagram případů užití
• Zobrazit recepty – zobrazí se seznam receptů • Zobrazit platby – zobrazí se seznam plateb • Zobrazit nejbližší lékárny – zobrazí se seznam lékáren, seřazený podle vzdáleností • Zobrazit uživatele – zobrazí se seznam uživatelů Po rozkliknutí jednotlivých položek uživatel bude mít možnost odstranit položku (košík, recept, platbu nebo uživatele). Vedle odstranění uživatele je možné přidat nového nebo editovat libovolného uživatele ze seznamu. Na záložce „Platby“ má uživatel možnost přidat novou platbu pomocí položky v menu. 13
1. Analýza Po kliknutí na ikonu „Přepnout uživatele“ v navigační liště se zobrazí dialog se seznamem uživatelů. Po výběru jiného než aktuálního uživatele se přepne aktuální uživatel a aktualizují se veškeré záložky, aby odpovídaly aktuálnímu uživateli. Po výběru košíku může uživatel vyhledat cenu jeho obsahu pomocí ikony v navigační liště. Uživateli se zobrazí dialog s volbou hledání města nebo možnosti hledat podle aktuální polohy, v případě že bude k dispozici. Po zadání údajů a potvrzení aplikace se zobrazí seznam cen košíku v jednotlivých lékárnách nebo se zobrazí hlášení o chybě v případě že dojde k chybě.
14
Kapitola
Návrh V této kapitole se věnuji návrhu aplikace (návrhu architektury a uživatelského rozhraní), ale ze začátku popíšu obecnou strukturu aplikací pro platformu Android a jejich specifika.
2.1
Základy aplikací pro Android
Aplikace pro Android jsou napsané v jazyku Java, ale jelikož Android je velký framework, v aplikacích se používá velký počet objektů a knihoven platformy. Aplikace je rozdělená na sources (česky zdrojové kódy), resources (česky prostředky) a Manifest soubor. V zdrojových kódech se definují aplikační komponenty a objekty, píše se programová logika, apod. Používají se stejně jako při běžném programování. Prostředky jsou podpůrné elementy, které používá aplikace (obrázky, audio soubory, všechno co se tyká vizuálního představení aplikace jako např. animace, menu, styly, barvy, popisky, prvky uživatelského rozhraní v podobě XML). Používaní prostředků přidává velkou pružnost aplikace. Je možné jednoduše změnit celý výhled uživatelského rozhraní nebo přeložit aplikaci na jiný jazyk bez změn v kódu. Manifest soubor je hlavní soubor, v kterém jsou nadefinované důležité údaje aplikace. Tam jsou nadefinované všechny použité komponenty, uvádějí se oprávnění, které aplikace vyžaduje, deklaruje se minimální podporované API, uvádějí se knihovny které aplikace potřebuje pro správné fungování jako např. Google Maps library. Aplikační komponenty jsou základními stavebními kameny Android aplikace. Komponenty jsou navzájem provázané a každý plní svou vlastní funkci. Jsou 4 druhy aplikačních komponent, jsou to Activities (česky aktivity), 15
2
2. Návrh Services (česky služby), Content providers (česky poskytovatelé obsahu) a Broadcast receivers (česky přijímače vysílání). Ale myslím si, že se dá přidat jako další základní typ komponent Fragments (fragmenty). Provázání a komunikace mezi většinou uvedených komponent probíhá přes Intent (česky záměr). Čerpáno z [2, 4].
2.1.1
Intent
Intent je asynchronní zpráva která je určená pro spouštění komponent a provázaní komponent mezi sebou. Pro Activity a Service Intent definuje akci, která musí být provedená, tudíž může obsahovat nějaké argumenty, URI i data. Například je moné poslat Activity asynchronní zprávu s požadavkem na zobrazení obrazovky nebo otevření webové stránky. Intent může vracet výsledek (např. můžeme požádat uživatele vybrat nějaký kontakt a on se vrátí v podobě Intent s URI ukazujícím na zvolený kontakt).
2.1.2
Activities
Activity představuje jednu obrazovku s uživatelským rozhraním. Je to základní kamen, bez kterého žádná aplikace nemůže existovat. Kromě toho, že Activity má v sobě vzhled, vždy má i nějakou logiku pro změnu vzhledu nebo interakci s uživatelem. Každá Activity má svůj životní cyklus, který se dělí na stav když Activity je aktivní a viditelná, stav když je aktivní ale neviditelná, a stav když není aktivní, ale ještě je živá a uložená na zásobníku. Pak už následuje ukončení aktivity. Activity se mění mezi stavy na základě uživatelských akcí a přepínání mezi Activity. Při nedostatku paměti každá Activity, která není viditelná může být ukončená a pak v případě potřeby vytvořená znovu.
2.1.3
Services
Service je komponenta běžící na pozadí a určená k provádění dlouhých operací. Service nemá uživatelské rozhraní. Např. Service se hodí pro přehrávání hudby nebo stahovaní dat na pozadí, bez toho aby zastavovalo nebo zpomalovalo vlákno, které obsluhuje uživatelské rozhraní. Service může být spuštěna jinou komponentou, např. Activity, pomocí Intent. 16
2.2. Návrh uživatelského rozhraní
2.1.4
Content providers
Content providers je mezivrstva nebo rozhraní pro správu a poskytování dat aplikaci. Jednou z největších výhod je možnost sdílení dat jiným aplikacím. Jsou velice užitečné i uvnitř aplikace, protože mohou poskytovat data interním objektům pro načítání na pozadí.
2.1.5
Broadcast receivers
Broadcast receiver je komponenta, která reaguje na vysílání oznámení přes celý systém. V systému se pořád vysílají různé zprávy, např. změna stavu sítě, zpráva že baterka je vybita a další. Je možné vysílat i vlastní zprávy do celého systému. Pro přijetí zprávy je nutné zaregistrovat přijímač, a aby on nedostával všechny existující zprávy, je nutné přidat filtr. Zprávy se posílají v podobě Intent objektů a mohou obsahovat nějaká data.
2.1.6
Fragments
Novinkou platformy Android od verze 3, která přináší nové možnosti vývoje a mění styl programování je Fragments. Fragment je znovupoužitelná komponenta, která vlastní uživatelské rozhraní a životní cyklus. Mezi vlastnosti Fragments patří to, že se může zobrazovat několik Fragments vedle sebe, nebo dokonce jeden v druhém, což není možné v případě Activity. Proto pomocí Fragments se dá jednoduše přizpůsobit aplikaci jak pro telefon, tak i pro tablet (stačí přidat další Fragment vedle a hned se zvýší funkčnost a pohodlnost aplikace na velké obrazovce). Životní cyklus Fragment je skoro stejný jako Activity až na to, že Fragment je závislý na Activity a musí se na začátku přepojit k Activity a na konci se odpojit. I když Fragments se objevili nedávno, byla vytvořená knihovna, která poskytuje zpětnou kompatibilitu a je možné používat Fragments i na starší verzi operačního systému.
2.2
Návrh uživatelského rozhraní
Jedním z požadavků na aplikaci je aby měla uživatelsky přívětivě rozhraní a aby byla pohodlná v použití. Při návrhu jsem se snažil zohlednit pokyny a požadavky platformy Android na aplikaci. Najednou jsem se snažil navrhnout aplikaci, aby byla použitelná na zařízeních s různě velkou obrazovkou (jak na telefonech, tak i na tabletech). 17
2. Návrh
(a) První varianta
(b) Druhá varianta
Obrázek 2.1: Návrh uživatelského rozhraní
Na začátku jsem měl na výběr 2 základní vzhledy aplikace (viz. obr 2.1)2 . První (viz. obr 2.1a) je když hlavní obrazovka vypadá jako dlaždice s ikonami různých součástí aplikace a po stisknutí na ikonu uživatel by přecházel k odpovídajícím obrazovkám. Druhy vzhled (viz. obr 2.1b) vypadal tak, že uživatel hned po spouštění aplikace vidí před sebou nějakou funkcionální obrazovku, na které už hned může provádět akci a nemusí přecházet na další pomocí stisku na ikonu. Přístup k dalším funkcím byl by zajištěn pomocí odkazu v menu a pomocí záložek i ikon v horní navigační liště (Action Bar). Každá z variant je něčím dobrá a každá má klady a zápory. První varianta je dobrá tím že je velice intuitivní a pochopitelná. Je to časem ověřený návrh a hodně aplikací existuje s takovým vzhledem. Ale přechod mezi obrazovkami je trošku těžší, protože se člověk vždy musí vracet na hlavní obrazovku pro volbu další akci. Také tato varianta není vhodná pro tablety, protože na obrazovce zůstává hodně volného místa. Tento návrh se spíš používá pro telefony, pro tablety se dělá jiná verze aplikace zvlášť. Druhá varianta je modernější a prosazuje ji Google jako nový standard Android aplikací. Tato varianta je dobrá tím, že uživatel hned po spouštění má před sebou funkcionální obrazovku a může hned provádět akce. Přechod mezi akce a obrazovky také je rychlejší. Ale největší výhoda je že tento návrh 2
18
Návrh byl vytvořen pomocí aplikace fluid, dostupné na https://www.fluidui.com
2.3. Návrh architektury se aplikuje jak na telefony, tak i na tablety a na obojích perfektně funguje. Nevýhoda je že možná ne pro všechny je tento návrh intuitivní a ne pro veškeré aplikace se tento vzhled hodí. Po zvážení každého návrhu a zhodnocení kladů a záporů každého z nich jsem rozhodl pro druhou variantu. Důležitým faktorem při výběru byla možnost použití vzhledu na telefonu i na tabletu, a myslím si, že druhá varianta pro tuto aplikaci je ještě pohodlnější v používání.
2.3
Návrh architektury
Při vývoje jakékoli aplikace je důležité udělat dobrý návrh architektury. Architektura aplikace musí nejenom odpovídat na požadavky systému, ale musí být schopna reagovat na budoucí změny a přizpůsobovat se jím s co nejmenším zásahem a změnami. Při návrhu jsem se snažil uspokojit veškeré požadavky na aplikaci a vytvořit efektivní a udržovatelnou architekturu. Jelikož aplikace musí mít databázi pro uložení informace, musí provádět synchronizaci a aktivně komunikovat s uživatelem, jsem si rozhodl rozložit architekturu do několika vrstev. Z mého pohledu třívrstvá architektura je velice efektivní a velice dobře udržovatelná. Prezentační vrstva odpovídá za zobrazení informace uživateli a kontroluje jeho vstupy, aplikační nebo business vrstva obsahuje v sobě celou logiku a zpracovává data, datová vrstva představuje databázi nebo souborový systém pro uložení informace. Každá nižší vrstva poskytuje služby vyšší vrstvě. V případě aplikací pro Android je těžko zachovat čistou třívrstvou architekturu, protože Activity jsou postavené tak, že mají v sobě nějakou aplikační logiku a provádí nějaké zpracování dat. Proto prezentační vrstva v Androidu je s elementy aplikační logiky, ale ostatní vrstvy mohou být samostatné a fungovat podle návrhu. V mém návrhu nejnižší datová vrstva je tvořená XML soubory, které jsou přístupné v aplikaci přes SharedPreferences objekty, a databází, která je přístupna přes Content Providers. Jsem si rozhodl nejen pro použití databáze ale i XML souboru a SharedPreferences objektů protože jejích implementace je mnohem jednodušší a ideálně se hodí pro ukládání malého množství dat. Business vrstva se skládá z DAO tříd pro přístup k databázi a Content Providers, SharedPreferences objektů pro přístup k datům uloženým v XML souborech a tříd pro komunikace se serverem a synchronizaci. Pro pohodlný přístup k této vrstvě z vyšší jsem použil návrhový vzor Facade. Tento návrhový vzor je založen na tom, že poskytuje vyšší vrstvě zjednodušené a pohodlnější rozhraní pro přístup k nižším vrstvám. Do této vrstvy je možné 19
2. Návrh odnést i Services, které nemají uživatelské rozhraní a provádí synchronizací a zjišťovaní polohy na pozadí. Přistupuje se k nim pomocí Intent objektů, a komunikace je zajištěná pomocí Broadcast Receivers. Prezentační vrstva je v aplikaci představená všemi Activities a Fragments, které se zobrazují uživateli a mají v sobě minimální logiku. Snažil jsem se maximálně rozdělit vrstvy, aby každá odpovídala pouze za své věci a nezasahovala do dalších vrstev, ale ne vždy je to možné kvůli specifikám platformy.
20
Kapitola
Realizace V kapitole Realizace bych se chtěl věnovat implementaci samotné aplikace. Při implementaci jsem se držel návrhu a poznatků z analýzy. Bylo by zbytečné popisovat implementaci každé třídy, proto se v této kapitole zaměřím na nestandardní řešení a nejproblematičtější části implementace.
3.1
Skenovaní čárových kódů
Při přidávání léků do košíku nebo při vytváření receptu uživatel musí zadat název léku, lékovou formu a obsah balení. I když po zadání názvu léků aplikace nabídne pouze ty lékové formy a balení, které může daný lék mít, tato operace by pro některé uživatele mohla být problematická. Poměrně často lidé kupují léky, který už brali. Aby se usnadnil způsob zadávání léků, v případě že člověk má k dispozici balení, bylo rozhodnuto přidat možnost vkládání léku pomocí skenovaní čárového kódu na obalu. Na výběr jsem měl 3 možností implementace této funkce: vlastní implementace celého algoritmu skenování, použití existující knihovny nebo použití služeb externí aplikace. První možnost je nejnáročnější a domnívám se, že předělávat to, co již existuje a dobře funguje, není smysluplné. Studium, přepracování algoritmu skenovaní a implementace by bylo příliš pracné a mohlo by být tématem pro samostatný projekt. Jelikož mé cíle jsou jiné a z důvodů neefektivity řešení pomocí vlastní implementace algoritmu skenování jsem tuto variantu zamítl. Použití existující knihovny je dobrým řešením z několika pohledů. První je že ušetřím čas a použiji to, co existuje a dobře funguje, a druhy je že, uživatel nemusí mít nainstalovanou aplikaci pro skenování čárových kódů, tudíž tato funkce bude nezávislá a bude vždy fungovat. Jako příklad knihovny 21
3
3. Realizace pro skenování čárových kódů je vhodná open-source knihovna ZXing3 implementovaná v jazyce Java. Na této knihovně je postavená řada programů pro skenování čárových kódů pro OS Android a jiné platformy. Nevýhodou by byla skutečnost, že knihovna by zvětšila rozměr aplikace, a v případě, že uživatel by tuto funkci nevyužíval, zabírala by zbytečné místo. Pokud by uživatel měl nainstalovanou aplikaci pro skenování čárových kódu, tak by bylo zbytečně mít další knihovnu zabudovanou v aplikaci navíc. Třetí varianta je nejlepší z pohledu platformy Android. Aplikace neobsahuje zbytečné komponenty a v případě, že potřebuje doplňující informace, požádá o ně pomocí Intent objektu. Systém sám vyhledá nainstalovanou aplikaci pro skenování čárových kódů, uživatel naskenuje daný kód, a systém pošle výsledek skenovaní pomocí Intent objektu. Jediný problém je chybějící aplikace na skenovaní, která se ale dá předem ošetřit pomocí systémových prostředku. V případe, kdy uživatel žádnou takovou aplikaci nemá nainstalovanou, program může nabídnout její stažení. Vývojáři knihovny ZXing naimplementovali IntentIntegrator pro Android. Je to jen adaptér pro použití externí aplikace na skenovaní postavené na ZXing knihovně. Adaptér se chová uživatelsky přívětivé a zjistí, zda je aplikace nainstalována, případně nabídne její instalaci a vrátí výsledek po skenovaní kódu. Do kódu stačí přidat pár řádek pro vyvolání: 1 2
I n t e n t I n t e g r a t o r i n t e g r a t o r = new I n t e n t I n t e g r a t o r ( a c t i v i t y ) ; integrator . initiateScan () ;
Po návratu zpět do aplikace je nutné zpracovat výsledek pomocí standardní metody: 1 2 3 4 5 6 7 8
public void o n A c t i v i t y R e s u l t ( int requestCode , int r e s u l t C o d e , Intent intent ) { IntentResult scanResult = IntentIntegrator . p a r s e A c t i v i t y R e s u l t ( requestCode , r e s u l t C o d e , i n t e n t ) ; i f ( s c a n R e s u l t != null ) { // h a n d l e s c a n r e s u l t } // e l s e c o n t i n u e with any o t h e r code you need i n t h e method ... }
Jelikož většina majitelů mobilních telefonů s OS Android má nainstalovanou aplikaci pro skenovaní čárových kódů, použil jsem možnost skenovaní pomocí externí aplikace a přímo IntentIntegrator od ZXing. 3
22
http://code.google.com/p/zxing/
3.2. Propojení s API
3.2
Propojení s API
Aplikace by nemohla existovat bez serveru, a proto je důležitá část implementace propojení aplikace s API serveru. Na straně serveru byly připravené webové služby, které pomocí rozhraní REST přijímaly a odpovídaly na požadavky. Server podporuje komunikaci ve formátu XML a JSON. Platforma Android nemá zabudované syntaktické analyzátory jako např. JAXB a zpracovaní XML je docela nepohodlné. Je nutné buď napsat vlastní DOM nebo SAX, nebo XML pull parser4 pro každou třídu nebo použít externí knihovnu. Bohužel se mi ale nepodařilo nalézt knihovnu vhodnou pro tento účel. Pro zpracování JSON Android také nemá standardní prostředky, ale existuje knihovna Gson5 , která odpovídá všem požadavkům. JSON formát je také úspornější než XML, proto jsem implementoval posílání a zpracovaní dat ve formátu JSON s použitím knihovny Gson. Při implementaci jsem narazil na několik komplikací. První bylo vyloučení nějaké proměny z serializace. Gson má anotaci která umožňuje přidat do serializace proměnnou, v případě že je nastaveno pravidlo pro výběr pouze anotovaných proměnných. Přímo na stránkách s uživatelkou příručkou pro knihovnu Gson je uvedeno několik postupů, které umožňují takovýto problém vyřešit. Jako nejvhodnější způsob jsem shledal vytvoření vlastní anotace a použití pravidla pro vylučování položek s danou anotaci. Přidal jsem následující anotaci a pravidlo pro vylučování: @Retention ( R e t e n t i o n P o l i c y .RUNTIME) @Target ( { ElementType . FIELD} ) public s t a t i c @ i n t e r f a c e S k i p S e r i a l i z a t i o n { // F i e l d t a g o n l y a n n o t a t i o n 5 } 1 2 3 4 6 7 8 9 10 11 12 13 14 15 16
public s t a t i c c l a s s S k i p S e r i a l i z a t i o n E x c l u s i o n S t r a t e g y implements E x c l u s i o n S t r a t e g y { @Override public boolean s h o u l d S k i p F i e l d ( F i e l d A t t r i b u t e s f ) { return f . g e t A n n o t a t i o n ( S k i p S e r i a l i z a t i o n . c l a s s ) != null ; } @Override public boolean s h o u l d S k i p C l a s s ( C l a s s > c l a z z ) { return c l a z z . g e t A n n o t a t i o n ( S k i p S e r i a l i z a t i o n . c l a s s ) != null ; } } 4 5
XML pull parser obdoba SAX parser, je postaven na principu zpracovaní událostí http://code.google.com/p/google-gson/
23
3. Realizace Dále bylo nutné zaregistrovat pravidlo při vytváření Gson objektu: Gson gson = new GsonBuilder ( ) . s e t E x c l u s i o n S t r a t e g i e s (new SkipSerializationExclusionStrategy () ) 3 // R e g i s t e r o t h e r r u l e s 4 . create () ;
1 2
Druhým problémem byla nutnost serializovat objekt jiným způsobem než standardním. Například při vyhledávání cen není nutné posílat celý objekt který popisuje lék, stačí pouze jeho identifikátor. Knihovna Gson poskytuje možnost používat vlastní serializator/deserializator. V kódu vypadá následujícím způsobem: 1 2 3 4 5 6
public s t a t i c c l a s s M e d i c i n e S e r i a l i z e r implements J s o n S e r i a l i z e r <Medicine> { @Override public JsonElement s e r i a l i z e ( Medicine s r c , Type typeOfSrc , JsonSerializationContext context ) { return new J s o n P r i m i t i v e ( s r c . getCode ( ) ) ; } }
Poté je třeba zaregistrovat serializator na objektu Gson: Gson gson = new GsonBuilder ( ) . r e g i s t e r T y p e A d a p t e r ( Medicine . c l a s s , new M e d i c i n e S e r i a l i z e r ( ) ) 3 // R e g i s t e r o t h e r r u l e s 4 . create () ;
1 2
3.3
Práce na pozadí
Pro práci na pozadí v Androidu jsou nadefinované třídy AsyncTask a Loader. Čerpáno z [3, 5].
3.3.1
AsyncTask
AsynkTask je velice efektivní nastroj pro práci na pozadí, který byl představen spolu s Android API 3. Životní cyklus je rozřazen do následujících metod: • onPreExecute() – metoda pro přípravu před spouštěním • doInBackground(T...) – metoda pro zpracování dat na pozadí 24
3.3. Práce na pozadí • onProgressUpdate(T...) – metoda pro notifikace uživatele o stavu procesu • onPostExecute(T) – metoda pro vracení výsledku • onCancelled() – metoda pro notifikace v případě zrušení úlohy Po přidání kontextu Activity jako argumentu AsyncTask dovede informovat uživatelé o stavu úlohy pomocí metody onProgressUpdate(T...) nebo o výsledku pomocí onPostExecute(T). Zde nastává největší problém. V případě že uživatel otočí zařízení, Activity a vnitřní Fragments se vytvoří znovu, aby přizpůsobil vzhled k poloze zařízení, a s tím se změní i kontext, který nebude předáván AsyncTask. Tím pádem AsyncTask bude pracovat dál a používat odkaz na již nevalidní kontext. Pokud bude chtít notifikovat uživatele, použije tento nevalidní kontext, čímž způsobí výjimku a následné spadnutí aplikace. Proto jsem musel využít Loaders, a nechat AsyncTasks pouze tam kde není nutné nic vracet uživateli nebo je zakázané otáčení obrazovky.
3.3.2
Loader
Loader je nastroj pro asynchronní načítání dat, který byl představen v Android API 11, ale má zpětnou kompatibilitu. Loader má následující charakteristiky: • Je dostupný pro každý Fragment nebo Activity • Provádí se asynchronně • Sleduje změny dat a při změně se aktualizuje • Nepotřebuje znovu načítat data po otočení při změně konfigurace Objekt Loader je napojen na životní cyklus Fragment nebo Activity, a při jakýchkoliv změnách má vždy aktuální kontext, proto netrpí stejnými problémy jako AsyncTask. Další zajímavá možnost Loaders je že mohou získávat data od Content Providers ve formě Cursor (rozhraní, které poskytuje náhodný přístup pro čtení a zápis k výsledkům databázového dotazu). Objekty Cursor se používají většinou u komponent uživatelského rozhraní na stejné úrovni jako pole dat. Kvůli výhodám objektů Loader jsem je upřednostnil před objekty AsyncTasks, což to mě donutilo používat Content Providers ve své implementaci. 25
3. Realizace
3.4
Použití Content Providers
Standardním přístupem k datům z databáze v platformě Android je použití metod insert(), update(), delete() a query() nad objektem SQLiteDatabase. Je možné používat metodu rawQuery(), v případě, že je třeba používat pokročilejší funkce, např. sloučení tabulek. Také existuje metoda execSql(), kterou nedoporučuji používat pro příkazy SELECT, INSERT, UPDATE nebo DELETE, jelikož nemá návratovou hodnotu. Hodí se však příkazy řízení databází, např. ALTER TABLE, CREATE, DROP, REINDEX a další. Content Provider obaluje databázovou vrstvu a přidává užitečnou možnost mít přístup k databázi z různých částí aplikace nebo zvenku. Vnitřní implementace Content Provider je založená na standardním dotazování objektu SQLiteDatabase. Podle dokumentací OS Android Content Provider nejsou doporučené pro používaní v případě že aplikace nebude předávat data navenek nebo nepotřebuje funkce Content Provider. Mobilní klient nebude moci sdělit data dalším aplikacím, ale potřebuje Content Providers pro objekty Loaders, kvůli čemuž jsem je používal při implementaci.
3.5
Vkládání velkého množství dat
V databázi aplikace bude uložen poměrně velký počet dat, např. léků bude řadově deset tisíc. Během vkládání testovacích dat léků do databází, jsem byl nepříjemně překvapen, operace vkládání 7 965 záznamů trvala kolem 5 minut. Předpokládal jsem, že výsledkem pomalého vkládání byla buď nedokonalost standardních funkcí nebo velká časová režie, která vznikla při vkládání po jedné položce v jedné transakci. Android poskytuje nástroje pro ruční řízení transakci, které jsou ošetřeny pomocí následujících metod, které se volají nad objektem SQLiteDatabase: • beginTransaction() – oznámení o začátku transakce • setTransactionSuccessful() – potvrzení úspěšného dokončení transakce • endTransaction() – dokončení transakce, uložení dat nebo zrušení transakce Kromě standardních prostředků pro vkládání Android má objekt InsertHelper, který není detailně zdokumentován, a podle Android API 17 je 26
3.6. Použití Native Development Kit tento objekt označen za zastaralý. Další možností vkládání objektů je příkaz execSql(), který ale není doporučen, protože nemá žádnou návratovou hodnotu.[6] Před konečným rozhodnutím. které komponenty mám použit, jsem se rozhodl otestovat každou možnost s použitím transakce a možnost vkládání prostřednictvím standardní metody insert() bez použití transakce. Testování probíhalo na dvou zařízeních, mobilním telefonu HTC Desire V s OS Android verzí 4.0.3 a procesorem 1 GHz Cortex-A5 a mobilním telefonu Samsung Galaxy Mini S5570 OS Android verzí 2.3.6 a procesorem 600 MHz ARMv6. Vkládalo se 7 965 záznamů. Průměrné výsledky testování jsou představené v tabulce 3.1.
insert() s transakcí InsertHelper s transakcí execSql() s transakcí insert() bez transakce
HTC Desire V 5,373 s 3,778 s 3,837 s 305,270 s
Samsung Galaxy Mini S5570 10,469 s 6,552 s 7,596 s 206,773 s
Tabulka 3.1: Testování rychlostí vkládaní dat Podle výsledků testování všech možností jsem rozhodl pro použití objektů InsertHelper. Přestože od poslední verzí API je označen jako zastaralý, poskytuje nejvyšší rychlost při vkládání dat a po vkládání vrací hodnotu, ukazující úspěšnost provedení operací, což nedělá metoda execSql() při téměř stejné rychlosti.
3.6
Použití Native Development Kit
NDK je sada nástrojů která umožňuje používat v aplikaci nativní kód, jako např. C nebo C++, přes JNI. Většina aplikací nepotřebuje použití NDK a ne vždy je to přínosné.[1] K použití NDK mě donutily omezení SQLite databáze a Android knihovny pro práci s databází. Jelikož počet lékáren v databázi bude řadově v tisících a aplikace bude muset obsahovat funkce pro zobrazení lékáren v okolí, seřazených podle vzdálenosti, bylo by velice neefektivní vybírat všechny lékárny a následně je seřazovat podle vzdálenosti. Je vhodnější nechat tuto funkci na databázi. Bohužel SQLite nemá přímou podporu trigonometrických funkci, které jsou nutné k výpočtu vzdáleností mezi dvěma body, ale má možnost nadefinovat a používat vlastní funkce. Další překážkou je omezení knihovny Android pro práci s databází, která neposkytuje možnost 27
3. Realizace definování a použití vlastních funkcí. Takovouto možnost však má nativní knihovna napsaná v jazyce C. Proto jsem zvolil použité NDK jako nejvhodnější variantu, kde bych mohl importovat nativní knihovnu pro práci s SQLite, nadefinovat vlastní funkci pro výpočet vzdáleností a vybírat lékárny podle vzdáleností. Jako návod na použití NDK jsem čerpal z video kurzu [10].
3.7
Zpětná kompatibilita
Android vydává ročně jednu nebo dvě nové verzi platformy, a s každou novou verzí přibývají nové funkce a elementy uživatelského rozhraní. Vývojáři se snaží zachovat zpětnou kompatibilitu a podporu nových věcí na starších verzích platformy, ale neplatí to úplně pro všechno. Pro tyto účely Android má knihovnu android-support-v4, kterou jsem používal. Při implementaci jsem se snažil vytvořit pohodlné a moderní uživatelské rozhraní, při čemž se nedalo obejít bez moderních. V aplikaci jsou použity různé moderní prvky, např. Fragments (pro optimalizací rozhraní pro tablety a telefony), Action Bar (pro pohodlné ovládání), Loaders (pro načítání dat na pozadí) a řada View elementů (elementy uživatelského rozhraní). Fragments, Loaders a většina elementů View mají zajištěnou zpětnou kompatibilitu. Ale nejpopulárnější Action Bar a některé View nejsou oficiálně podporované ve starších verzích. Pro podporu těchto elementů existuje knihovna třetí strany ActionBarSherlock6 . Knihovna představuje samostatný projekt, který obaluje standardní objekt Fragment, objektem SherlockFragment, jenž umožňuje zobrazovat prvky na starších verzích OS. Použitím této knihovny jsem zajistil podporu 99 % elementů. Zbylé elementy, které nejsou kompatibilní, jsou předefinované proměnné nových verzí, které stačilo pouze předefinovat.
6
28
http://actionbarsherlock.com/
Kapitola
Testování Testování je nezbytná fáze vývoje jakékoliv aplikace. Aplikaci jsem testoval průběžně během vývoje a na konci vývoje jsem provedl systémové testy celé aplikace. V této kapitole popíšu všechny etapy testování (Unit testy, integrační testy a systémové testy).
4.1
Unit testy
Po dokončení nějaké obrazovky nebo elementu aplikace jsem testoval jejich funkčnost. Většinou při testování elementu jsem ověřoval zda prvek funguje správně, korektně reaguje na uživatelské vstupy, případně zda oznámí uživateli chybu, pokud k ní dojde. Část kódu byla otestovaná pomocí framework JUnit. Testovaly se public (česky veřejné) metody tříd zda výstup odpovídá očekávanému výstupu při určitých vstupních hodnotách. Takovým způsobem jsem většinou testoval vlastní Gson serializer/deserializer pro třídy, které se posílají přes webové služby. Při testování jsem také používal standardní Android prostředky pro logování. V Androidu je pro tyto účely třída Log, pomocí které je možné logovat stav proměnných, chyby a další informace. Docela často při vývoji nastávala chyba spojená s databází. Pro zjištění příčiny chyby mi velice pomáhal plugin Questoid SQLite Manager7 , který umožňuje stáhnout databázi ze zařízení a zobrazit ji v čitelné podobě. Takovým způsobem jsem mohl zjistit, jestli došlo k chybě při vkládaní dat, nebo se data vložila ale je problém při jejích čtení. 7
http://www.questoid.com/Tools/QuestoidSQLiteManager.aspx
29
4
4. Testování Během testování jsem prováděl i nefunkční testy. Například v sekci 3.5 je popsán způsob testování rychlosti vkládání velkého množství dat, podle kterého jsem se rozhodoval, jaké metody pro vkládaní mám použít. Všechny provedené Unit testy pomohly zajistit funkčnost většiny tříd a odstranit chyby během vývoje.
4.2
Integrační testy
Jelikož důležitou částí aplikace je komunikace se serverem, velký důraz byl kladen na implementaci a testování provázaní klienta se serverem. Za účelem testování jsem vytvořil vlastní Activity, kde jsem přímo volal metody pro komunikaci s webovými službami. Toto mi dalo možnost otestovat přímo funkčnost všech metod pro komunikaci, a výsledky by neměly být ovlivněné případnými chybami vyšší prezentační vrstvy. Výsledkem integračních testů bylo ověření a korekce funkčnosti metod pro komunikaci se serverem, což mi umožnilo bezpečně je používat při implementaci.
4.3
Systémové testy
Poslední fází testování byly systémové testy, kde jsem vyzkoušel aplikaci jako hotový produkt a ujistil se v její funkčnosti. Otestoval jsem všechny scénáře použití aplikace, které jsou popsané v sekci 1.2. Snažil jsem se otestovat i neočekávané akce ze strany uživatele, abych ošetřil další případné chyby. Při testování hotové aplikace jsem také používal vývojářský Android nástroj StrictMode. Tento nástroj umožňuje sledovat běh aplikace a oznamuje vývojáře v případě špatného chování aplikace. StrictMode sleduje hlavní vlákno, a aby se v něm neprováděly dlouhé operace čtení, zápisu na disk nebo síťová komunikace. Další funkce StrictMode je možnost sledovat možné úniky aplikace a notifikace v případě nezavírání spojení s databází, nezavírání kurzorů nebo když nejsou odregistrované všechny zaregistrované objekty (např. BroadcastReceiver). Výsledkem systémových testů bylo doladění aplikace a ověření její plné funkčnosti.
30
Závěr Cílem práce bylo vytvořit klienta pro OS Android pro systém „Moje Lékárna“, který by měl stejné funkce jako webové rozhraní a měl by rozšířit použití systému. A to se mi i přes všechny problémy během vývoje podařilo splnit. Jelikož mi chybělo zařízení pro testování, nestihl jsem dopracovat podporu pro tablety. Tuto záležitost plánuji vyřešit v co nejbližší době. Aplikace se bude vyvíjet paralelně se serverem, ale i teď jsou věci, které se dají zlepšit. V poslední fázi implementace už přibyla nová funkce na serveru, která bude následně přidána i na klientu. Je to možnost zjištění lékových interakcí. Předpokládám, že budou i další nové funkce, tudíž vývoj tímto rozhodně neskončí. A i bez dalších funkcí je několik věcí, které bych chtěl v budoucnu zlepšit. První je uživatelské rozhraní. Chtěl bych pak ozdobit aplikaci animací, čím by se stala ještě příjemnější pro uživatele. Dál bych chtěl aplikaci zlepšovat a přidávat nové elementy, které se budou objevovat spolu s vývojem platformy Android a použitých knihoven. Vývoj této aplikace byl pro mě dobrou zkušeností a velkým přínosem. Budu rád dál pokračovat nad zlepšením a vývojem aplikace.
31
Literatura [1] Android NDK | Android Developers [online]. [cit. 2013-0506]. Dostupné z: http://developer.android.com/tools/sdk/ndk/ index.html [2] Application Fundamentals | Android Developers [online]. [cit. 2013-05-06]. Dostupné z: https://developer.android.com/guide/ components/fundamentals.html [3] AsyncTask | Android Developers [online]. [cit. 2013-05-06]. Dostupné z: https://developer.android.com/reference/android/os/ AsyncTask.html [4] Fragments | Android Developers [online]. [cit. 2013-05-06]. Dostupné z: https://developer.android.com/guide/components/ fragments.html [5] Loaders | Android Developers [online]. [cit. 2013-05-06]. Dostupné z: http://developer.android.com/guide/components/loaders.html [6] SQLiteDatabase | Android Developers [online]. [cit. 2013-05-06]. Dostupné z: http://developer.android.com/reference/android/ database/sqlite/SQLiteDatabase.html [7] Vyhláška č. 54 ze dne 6. února 2008 o způsobu předepisování léčivých přípravků, údajích uváděných na lékařském předpisu a o pravidlech používání lékařských předpisů. In Sbírka zákonů, 2008, částka 16/2008. Dostupné z: http://portal.gov.cz/zakon/54/2008 33
Literatura [8] Dashboards | Android Developers [online]. Květen 2013, [cit. 2013-05-06]. Dostupné z: http://developer.android.com/about/ dashboards/index.html [9] Zákon č. 16 ze dne 7. března 1997 o veřejném zdravotním pojištění a o změně a doplnění některých souvisejících zákonů. In Sbírka zákonů, 2013, částka 16/1997. Dostupné z: http://portal.gov.cz/zakon/48/ 1997 [10] Gargent, A.: Introduction To Android NDK - Marakana [online]. Duben 2012, [cit. 2013-05-06]. Dostupné z: http://marakana.com/s/ post/1153/introduction_to_ndk [11] Laptsionak, A.: tabletka.by [online]. Únor 2013, [cit. 2013-05-06]. Dostupné z: https://play.google.com/store/apps/details?id= com.tabletka.by [12] MobileSoft.cz: České lékárny [online]. Duben 2013, [cit. 2013-05-06]. Dostupné z: https://play.google.com/store/apps/details?id= cz.novosvetsky.lekarny [13] MobileSoft.cz: Lékař doma [online]. Květen 2013, [cit. 2013-05-06]. Dostupné z: https://play.google.com/store/apps/details?id= cz.mobilesolutions.domaciLekar [14] Státní ústav pro kontrolu léčiv: Co je to započitatelný doplatek?, O lécích.cz [online]. [cit. 2013-05-06]. Dostupné z: http://www.olecich.cz/ encyklopedie/co-je-to-zapocitatelny-doplatek [15] Státní ústav pro kontrolu léčiv: Co to jsou generické léky?, O lécích.cz [online]. [cit. 2013-05-06]. Dostupné z: http://www.olecich.cz/ encyklopedie/co-to-jsou-genericke-leky [16] Státní ústav pro kontrolu léčiv: Generická substituce, O lécích.cz [online]. [cit. 2013-05-06]. Dostupné z: http://www.olecich.cz/slovnik/ genericka-substituce?highlightWords=substituce [17] Státní ústav pro kontrolu léčiv: Proč jsou některé léky volně prodejné a jiné na recept?, O lécích.cz [online]. [cit. 2013-0506]. Dostupné z: http://www.olecich.cz/encyklopedie/proc-jsounektere-pripravky-volne-prodejne-a-jine-na-recept
34
Příloha
Seznam použitých zkratek SÚKL Státní ústav pro kontrolu léčiv OS Operating system UI User interface GPS Global Positioning System API Application Programming Interface NFC Near Field Communication XML Extensible markup language URI Uniform Resource Identifier DAO Data access object ZXing Zebra Crossing REST Representational State Transfer JSON JavaScript Object Notation JAXB Java Architecture for XML Binding DOM Document Object Model SAX Simple API for XML JNI Java Native Interface NDK Native Development Kit
35
A
Příloha
B
Instalační příručka Aplikace je možné nainstalovat z přiloženého CD nebo přímo z Google Play (doporučují tento způsob, jelikož tam bude vždy aktuální verze).
B.1
Instalace z CD
Pro instalace apk souboru z CD je nutné zkopírovat apk soubor do pamětí zařízení nebo na paměťovou kartu, povolit instalaci z neznámých zdrojů v Nastavení (v sekci Zabezpečení8 ), nainstalovat apk soubor pomocí výchozího nebo externího prohlížeče souborů.
B.2
Instalace z Google Play
Aplikace je dostupná z https://play.google.com/store/apps/details?id= by.maximov.najdilekarnu
8
Pojmenování se může lišit podle verze OS a výrobce zařízení
37
Příloha
Obsah přiloženého CD
readme.txt ................................ stručný popis obsahu CD apk.....................adresář se spustitelnou formou implementace Najdi-lekarnu.apk..........................spustitelná aplikace src thesis....................zdrojová forma práce ve formátu LATEX text.....................................................text práce BP_Maksimau_Aliaksandr_2013.pdf...text práce ve formátu PDF 39
C