You are on page 1of 90

ANDROID SKOLA

PROGRAMIRANJA
By android@Vidi

Kopija teksta Android@Vidi skole programiranja za


android sisteme
Robert

SADRZAJ:
Android kola programiranja Pisanje i pokretanje prvog programa.........3
Trei nastavak serijala o Google Android programiranju Interakcija sa
korisnikom................................................................................................. 8
Android programiranje #4: Uvod u pisanje programskoga koda..............12
Android programiranje #5: Koritenje rasporeda kontrola u sloenim
aplikacijama............................................................................................ 18
Android programiranje #6: Koritenje osnovnih Android kontrola............24
Android programiranje #7.......................................................................31
Android programiranje #8: Android kontrole u akciji IV...........................35
Android programiranje #9: Koritenje datotenog sustava......................40
Android programiranje #10: Nekoliko standardnih dijelova aplikacije......48
Android programiranje #11: Standardni dijelovi aplikacije......................59
Android programiranje #12: Alternativni pristup razvoju aplikacija.........65
Android programiranje #13: Alternativni pristup razvoju aplikacija II......69
Android programiranje #14: Alternativni pristup razvoju aplikacija III.....73
Android programiranje #15: Izrada sloenijih aplikacija..........................78
Android programiranje #16: Koritenje kartografskih servisa..................82
Android programiranje #17: to je novo u 3.x izdanjima.........................86

Android kola programiranja Pisanje i pokretanje prvog programa

Proli put smo u malo poduem poetnom tekstu objasnili zato


pokreemo novu kolu programiranja i koji su nam sve alati potrebni za
nju, odnosno kako ih treba instalirati na raunalo da bi sve proradilo na
odgovarajui nain. Budui da je za razvoj Google Android aplikacija
potrebno instalirati nekoliko alata razliitih proizvoaa, takva instalacija
nikad ne prolazi tako glatko kao kad je rije o instalaciji pojedinanoga
razvojnog alata samo jednog proizvoaa.
Ok, ako ste napravili sve to smo napisali u prolom nastavku, sad biste
trebali imati raunalo spremno za pisanje prvog Google Android
programa, to emo doista i napraviti u nastavku teksta. Usput emo
malo zagrepsti po glavnim dijelovima razvojne okoline potrebnim za
razvoj takve vrste aplikacija, kao i samom emulatoru odgovarajueg
hardverskog ureaja, jer na kraju krajeva, tek u njemu moemo vidjeti
rezultate rada naeg programa na smisleni nain. Nakon toga se u
sljedeim brojevima moemo pozabaviti samim programiranjem i
naprednijim programskim tehnikama.
Stvaranje projekta HelloWorld: Ovako izgleda poetni
dijaloki okvir kod stvaranja projekta

Kako rezervirani prostor za ovaj serijal u nekoliko


brojeva asopisa jednostavno nije dovoljan za detaljnije
bavljenje razvojnom okolinom, tog segmenta razvoja aplikacije dotaknut
emo se samo kad neto postane zaista neophodno. Ipak, ako ste do sad
ve koristili neku od modenijih razvojnih okolina za razvoj aplikacija (a
napomenuli smo da praenje serijala zahtijeva odreeno predznanje),
onda ne biste trebali imati previe problema ni sa snalaenjem u razvojnoj
okolini Eclipse.
Kao to to dobra programerska tradicija nalae, priu o programiranju u
Google Androidu zapoet emo od trivijalnog HelloWorld primjera.
Njegova namjena jest pokazati kako se u novom razvojnom okruenju
prikazuje jednostavna poruka korisniku programa. Za mlae (ili starije)
itatelje koji moda upravo sada prvi put zapoinju avanturu
programiranja u nekom programskom jeziku, treba napisati samo kratko
objanjenje zato se u gotovo svakoj koli programiranja zapoinje s tako
trivijalnim primjerom budui da on sam za sebe zapravo ne radi nita
korisno. Ideja u pripremi tako jednostavnog primjera jest u tome da se
programer to bre upozna s novim programskim jezikom, ali i njegovim
razvojnim okruenjem, kako bi se nakon toga to bre moglo prijei na
sloenije probleme.
Za pisanje novog programa potrebno je u razvojnoj okolini Eclipse
izabrati naredbu File > New > Project te u dijalokom okviru prikazanom u

nastavku odabrati odgovarajuu vrstu projekta. U ovom sluaju to je


Android Project. Kao rezultat izvoenja prethodne operacije, pojavljuje se
dijaloki okvir New Android Project gdje se od programera oekuje
upisivanje nekoliko polaznih podataka o vlastitom projektu.
Project Name predstavlja naziv projekta na kojem trenutno radimo. U
ovom sluaju, to e biti HelloWorld. Osim naziva projekta, potrebno je
izabrati mjesto na disku za spremanje njegovih sastavnih dijelova. To
moe biti podrazumijevana radna povrina definirana prilikom prvog
pokretanja radne okoline, neko tono odreeno mjesto na disku, ili se u
razvoj projekta moe krenuti od ve postojeeg projekta recimo nekog
od prateih primjera Google Android projekata. Za sada na ovom mjestu
moemo ostaviti podrazumijevane vrijednosti, dakle ukljuene opcije
Create New Project in Workspace te Use default location.
Projekt HelloWorld nakon stvaranja: Automatski je
generiran itav niz datoteka koje se mogu pregledati u
razvojnoj okolini Eclipse.

Projekt HelloWorld nakon stvaranja: Automatski je


generiran itav niz datoteka koje se mogu pregledati u
razvojnoj okolini Eclipse.
U sluaju da je na raunalo instalirano vie inaica razvojnih paketa
Google Android SDK, potrebno je izabrati jedan od njih, nakog ega e se
odgovarajua oznaka inaice pojaviti u okviru Min SDK Version na dnu
dijalokog okvira. Da bi se moglo nastaviti s radom na projektu, potrebno
je navesti jo nekoliko podataka. U okvir Application Name treba upisati
naziv aplikacije, to moe biti bilo kakav niz znakova, dakle i onaj jednak
nazivu projekta. U Package Name treba upisati naziv Java paketa. Ovaj
naziv treba biti sastavljen od najmanje dva dijela meusobno odvojena
tokom na primjer helloWorld.java (prema uobiajenim konvencijama
prvo slovo treba biti malo). U okvir Create Activity treba upisati naziv prve
aktivnosti u Google Android projektu na primjer helloWorld.
Sada je mogue kliknuti na gumb Next te tako prijei na sljedei dijaloki
okvir namijenjen za stvaranje odgovarajuega pomonog projekta za
testiranje. Projekti za testiranje namijenjeni su za pojednostavljeno
ponavljanje testiranja vrlo sloenih Google Android projekta (kakav
HelloWorld zasigurno nije), ali emo na ipak kreirati takav projekt kako
bismo se upoznali i s tom mogunou razvojnog alata. Na ovom mjestu
mogu se ostaviti sve predloene vrijednosti to za posljedicu ima
stvaranje projekta HelloWorldTest. Nakon izvoenja svih prethodno
nabrojenih operacija, u radnoj povrini na disku stvara se itava hrpa
datoteka, a sadraj svake od njih moe se vidjeti u odgovarajuem
prozoru radne okoline. Za jednostavnije snalaenje najbolje je koristi

hijerarhijski prikaz dijelova projekta u posebnom prozoru na lijevom dijelu


razvojne okoline (Navigator).
Upravljanje virtualnim ureajima: Omoguuje testiranje
projekta na razliitim emulacijama hardverskih
karakteristika.

Budui da je razvojna okolina automatski pripremila


itav niz datoteka, prva ideja koja nam svakako mora pasti na pamet
isprobavanje je nastale situacije. Najjednostavniji nain za to jest odabir
naredbe Run As > Android Application iz padajueg izbornika povezanog s
projektom HelloWorld. Podrazumijeva se da se ista naredba moe izvesti
na bar jo nekoliko naina kao u svim modernim razvojnim okolinama na
primjer odabirom istoimene naredbe iz glavnog izbornika ili odgovarajue
ikone na alatnoj traci prozora. Na taj detalj vie se neemo vraati ni u
ovom ni u buduim tekstovima, nego istraivanje alternativnih
mogunosti ostavljamo samim itateljima.
Budui da je cijeli Android sustav namijenjen razvoju aplikacija za
prijenosne mobilne ureaje, razumljivo je da se aplikacija ne moe izvesti
u zraku, nego nam je za to potreban nekakav ureaj za njezino
izvoenje ako nita drugo, onda bar u obliku softverske emulacije. Takav
softverski stroj naziva se Android Virtual Device ili skraeno AWD. Ako
nekakva konfiguracija emulatora ve ne postoji od prije, treba je
pripremiti prema konkretnim potrebama za testiranje vlastite aplikacije.
Za upravljanje virtualnim ureajima koristi se dijaloki okvir Android SDK
and AVD Manager, to ukljuuje operacije poput stvaranja ureaja,
njegovog brisanja, ispravljanja te moda najvanije, pokretanja ureaja.
Kljuni hardverski parametri koji se mogu definirati kod stvaranja novoga
virtualnog stroja jesu koliina raspoloive radne memorije te rezolucija
zaslona.
Nakon stvaranja novoga virtualnog ureaja, u njega je mogue uitati, a
nakon toga i isprobati vlastitu aplikaciju. Budui da za sada naa
aplikacija predstavlja samo goli kostur aplikacije te kao takva zapravo ne
radi nita pametno, ni u virtualnom ureaju nema se mnogo toga za
vidjeti osim osnovne poruke korisniku programa. U sluaju da se tekst iz
aplikacije ne prikae automatski u virtualnom ureaju, kliknite na gumb
Menu prikazan na prozoru virtualnog ureaja.
Trenutno stanje programskoga koda ima oblik prikazan u nastavku, ali ne
treba smetnuti s uma da to nije jedini dio aplikacije. Tako, na primjer, za
pregled i izmjenu prikazane poruke treba otvoriti datoteku strings.xml,
hijerarhijski smjetenu u mapi res/values.
package helloWorld.java;import android.app.Activity;
import android.os.Bundle;public class helloWorld extends Activity {

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Na slian nain, otvaranjem datoteke main.xls smjetene u mapi
res/layout, moe se oblikovati grafiko suelje aplikacije na nain vrlo
slian izvoenju odgovarajuih postupaka u drugim modernim razvojnim
okolinama na primjer Microsoft Visual Studio. Kao osnovnu vjebu u
koritenju razvojne okoline, probajte u vlastitu aplikaciju dodati jedan
gumb te mu eventualno podesiti neka od svojstava za odreivanje izgleda
u prozoru Properties.
Virtualni ureaj u akciji: Stvarni izgled ovisi o
parametrima definiranim prilikom njegovog stvaranja.

Vizualna priprema suelja aplikacije: Izvodi se u


posebnom prozoru radne okoline.

Spomenimo na ovom mjestu kako se itava operacija


prevoenja izvornoga koda, pokretanja virtualnog ureaja te uitavanja
prevedenog programa u ureaj moe opisati svakako, ali sigurno ne
pojmom brza operacija, bez obzira na snagu raunala. Ako ste ve
ranije probali sline kombinacije razvojnih alata i emulatora drugih
proizvoaa, onda sigurno niste iznenaeni prethodnom tvrdnjom, jer ste
na to ve jednostavno navikli. Dobra vijest je da je vrijeme uitavanja
nove inaice aplikacije u ve pokrenuti virtualni ureaj bitno krae, to
znai da je isprobavanje vlastite aplikacije nakon manjih promjena
izvornoga koda ipak prilino bezbolan proces.
Spomenimo na kraju dananjeg predstavljanja poetnih koraka u razvoju
Android aplikacija, jer se dovrena i testirana Android aplikacija moe
pripremiti za distribuciju u obliku datoteke s nastavkom .apk. Rije je o
komprimiranoj datoteci sastavljenoj od veeg broja datoteka koje sadre
sve potrebne informacije za izvoenje aplikacije na ureaju s ugraenom
podrkom za Google Android. Kad zavrite ovu kolu i napiete prve

kvalitetne aplikacije, prrua vam se mogunost da poneto i zaradite


putem online trgovine Google Android aplikacija, koja svakodnevno
dobiva sve vei broj naslova od programera irom svijeta.

Trei nastavak serijala o Google Android programiranju Interakcija sa korisnikom

Drugi nastavak nove kole programiranja u razvojnom alatu Google


Android bio je namijenjen izradi klasine aplikacije u svim kolama
programiranja opepoznatog primjera HelloWorld. Cilj projekta bio je
brzo upoznavanje dijelova razvojne okoline potrebnih za izradu vlastitih
aplikacija, dok o samom programiranju nije bilo reeno ba mnogo. U biti,
u prolom tekstu samo smo isprobali ono to je automatski pripremila
razvojna okolina. Ovaj put idemo korak dalje pa poinjemo u poetnu

aplikaciju dodavati prve objekte, a nakon toga i programski kod za njihovu


reakciju na dogaaje u okolini, to jest na operacije korisnika programa.
Usput emo se malo pozabaviti i posebnom terminologijom koja se koristi
tijekom rada na Google Android projektima.
Prije nego ponemo zaozbiljno, dopustite da se osvrnemo na bitan
tehniki detalj. Moderna razvojna okolina kao to je Eclipse ima itav niz
prozora za definiranje razliitih dijelova projekta, pa se poetniku nije ba
uvijek lako snai sa svim tim dijelovima, posebno ako je neki od bitnih
prozora zatvoren ili premjeten s podrazumijevanog mjesta sluajno ili
namjerno. Kako bi olakao praenje teksta, autor se trudi da priloene
slike uz tekst uvijek pokazuju bitne dijelove. Problem nastaje kad se zbog
ovog ili onog razloga (najee nedostatka prostora u asopisu), neka od
slika mora izostaviti, ili se smanji tako da je teko razaznati neke dijelove.
Zato emo (bar u poetku) stalno navoditi ne samo to treba napraviti da
bi se dovrila neka operacija nego i kako se zapravo stie do tog mjesta.
Navedimo prvo to elimo postii u dananjem i sljedeem nastavku. U
osnovni projekt, HelloWorld, iz prolog nastavka elimo dodati tri nova
objekta jedan okvir za prikaz i unos teksta od strane korisnika te dva
dodatna gumba za upravljanje tim okvirom. Odmah pri pokretanju
programa okvir za tekst se programski puni poetnom vrijednou, a
pritisak miem na bilo koji od dodatna dva gumba izaziva zamjenu
poetnog sadraja drugaijim tekstom. Dakle, nita spektakularno u
smislu izvoenja programa, ali i tako jednostavan primjer demonstrira
razliite naine koritenja Google Android sustava u razvoju aplikacija za
mobilne ureaje.
Rad na proirenju poetnog HelloWorld projekta
zapoinjemo otvaranjem datoteke main.xml u prozoru
radne okoline, pod nazivom Android Layout Editor, jer je
on namijenjen grafikom ureivanju izgleda vlastite
aplikacije. Naravno, budui da je u osnovi rije o
obinoj .xml datoteci, moemo je otvoriti i u nekom od
tekstualno orijentiranih prozora, ali se to ba ne
preporuuje poetniku. Na ovom mjestu postoji velik stupanj analogije sa
stvaranjem HTML dokumenata (to je vjerojatno poznato bar dijelu
itatelja). HTML dokument moemo stvoriti izravnim upisivanjem
sastavnih dijelova u tekstualnom obliku (tei nain), ili njihovim
crtanjem u odgovarajuem grafiki orijentiranom alatu (laki nain). Za
sada emo i u razvojnoj okolini Eclipse izabrati laki nain izrade
korisnikog suelja, a kad postanete iskusniji, moete koristiti oba naina.
Spomenimo na ovom mjestu namjenu prozora Outline, koji zapravo
predstavlja neto izmeu. U njemu je vidljiv samo popis osnovnih
dijelova od kojih se sastoji korisniko suelje aplikacije, kao i njihov
meusobni odnos, ali ne i drugi detalji za odreivanje izgleda. Korisniko

suelje aplikacije iz prolog nastavka bilo je sastavljeno od svega dva


dijela: LinearLayout i TextView. Prvi dio pripada grupi objekata
namijenjenih odreivanju meusobnog rasporeda osnovnih objekata koji
ine korisniko suelje (u terminologiji Google Androida to su layouts
objekti). U dananjem nastavku neemo se detaljnije baviti ovim dijelom
oblikovanja korisnikog suelja, nego to ostavljano za budue nastavke
serijala. Za sada spomenimo samo da je tijekom inicijalne pripreme
projekta uporabljen prilino jednostavan raspored objekta pod prije
spomenutim nazivom LinearLayout, a mi emo ga zasad koristiti bez
ikakvih izmjena. U projekt HelloWorld automatski je dodan jo jedan
objekt namijenjen osnovnoj interakciji s korisnikom programa, to se
zapravo svodilo na obian prikaz pozdravne poruke. U terminologiji
Google Androida, takvi objekti s vlastitim vizualnim izgledom, namijenjeni
izgradnji razliitih dijelova korisnikog suelja za interakciju s korisnikom
aplikacije nazivaju se widgets.

Ve smo spomenuli da emo u korisniko suelje


dodati jo tri dijela pa sad prelazimo na izvoenje
odgovarajuih operacija. Iz prozora Views treba redom
povui tri objekta na dio koji prikazuje grafiku
reprezentaciju aplikacije (objekt LinearLayout).
Jednom to treba napraviti s objektom tipa EditText, a
dva puta s objektom tipa Button. O samom mjestu
isputanja objekta ne treba voditi previe rauna,
jer se pozicioniranje nacrtanih objekata ionako izvodi automatski zbog
koritenja vrlo jednostavnog naina rasporeivanja objekata. Primijetimo
na ovom mjestu da je razvojna okolina nacrtanim objektima automatski
dodijelila nazive (EditText01, Button01 i Button02), ba kao i dio drugih
vrijednosti svojstava. Ako ste ve ranije koristili neku inaicu Microsoftove
razvojne okoline, bit e vam potpuno jasno to se je dogodilo u
prethodnom koraku.
Isto tako, prepoznat ete nain za pregled i izmjenu podrazumijevanih
vrijednosti svojstava aktivnog objekta. Za to se koristi prozor Properties, a
u njemu treba jednostavno pronai svojstvo iji sadraj namjeravamo
izmijeniti te upisati (ili izabrati to ovisi o vrsti svojstva) novu vrijednost.
Na primjer, ako elimo boju cjelokupne pozadine izmijeniti s crne na
bijelu, kao aktivan objekt treba oznaiti LinearLayout, a kao vrijednost
svojstva Background upisati vrijednost #FFFFFF. Na slian nain moemo
gumbima Button01 i Button02 izmijeniti poetni tekst na vrijednost
Prihvati odnosno Odbaci, tako da za svaki gumb izvedemo korekciju
vrijednosti svojstva Text. Objektu EditText01 takoer izmijenimo vrijednost
svojstva Layout width na unaprijed definiranu vrijednost fill_parent, kako
bi se objekt proirio na punu irinu. Za vjebu, moete promijeniti poetnu
vrijednost prikazanog teksta na objektu EditText01, iako emo to kasnije

napraviti programski, kako bismo demonstrirali izmjenu vrijednosti


svojstava u programskom jeziku.
Nestrpljivi itatelji mogu probati sami otkrivati emu
slue druga dostupna svojstva tako da im izmijene
poetnu vrijednosti, a mi emo u sljedeim nastavcima
serijala objanjavati neka od njih kad nam zatrebaju.
Objasnimo na ovom mjestu neto zaobilazniji nain za
izmjenu vrijednosti svojstava. Vrijednost #FFFFFF na
prvi, drugi pa ak i trei pogled poetniku ne odaje da je
rije o bijeloj boji, a priznat ete da ni iskusnijima nije ba lako pamtiti
sline vrijednosti, ako ih ne koriste svakodnevno. Postoji li nain da se
takve vrijednosti koriste na humaniji nain? Sreom, da, a odgovarajui
postupak opisujemo u nastavku teksta.
U hijerarhijskom pregledu dijelova projekta (prozor Navigator) treba
pronai i otvoriti datoteku res \ values \ strings.xml. U ovoj datoteci nalaze
se definicije resursa uporabljenih na razliitim mjestima u programu. Na
ovo mjesto treba jednostavno dodati novi resurs pod nazivom BijelaBoja.
Za to se koristi klik na gumb Add.., nakon ega se otvara dijaloki okvir za
odabir kategorije resursa. U njemu sasvim logino treba izabrati
kategoriju Color, iako se potpuno slian postupak primjenjuje za druge
vrste resursa. Preostaje jo samo da se kao naziv resursa (Name) upie
vrijednost BijelaBoja, a kao njegova vrijednost (Value) #FFFFFF. Naravno,
nemojte zaboraviti ni na spremanje nove vrijednosti resursa pomou
ikone diskete na alatnoj traci razvojne okoline.
Ako sada zatvorimo datoteku strings.xml, vraamo se ponovno na
grafiku reprezentaciju korisnikog suelja. Ponovno kao aktivni objekt
izaberimo LinearLayout te pronaimo svojstvo Background. Nakon klika
na gumb s tri toke na samom desnom kraju reda, otvara se dijaloki
okvir Reference Chooser. U njemu moemo pronai vrijednost BijelaBoja u
okviru kategorije Color te je izabrati kao novu vrijednost svojstva,
potvrdom na gumb OK. Kao nova vrijednost svojstva sada e biti
prikazana vrijednost @color/BijelaBoja, to i dalje predstavlja bijelu boju,
ali sada napisanu na mnogo itljiviji nain od upisa heksadecimalnoga
koda iste boje. Na slian nain moemo definirati druge vrijednosti koje
namjeravamo uporabiti u razliitim dijelovima programa.
Za kraj ovoga poglavlja, otvorimo ponovno datoteku main.xml, ali sada u
obinome tekstualnom editoru. Dobit emo neto poput:
<?xml version=1.0 encoding=utf-8?>
<LinearLayout
xmlns:android=http://schemas.android.com/apk/res/android
android:orientation=vertical
android:layout_width=fill_parent

android:layout_height=fill_parent
android:background=@color/BijelaBoja>
<TextView
android:layout_width=fill_parent
android:layout_height=wrap_content
android:text=@string/hello
/>
<EditText android:text=@+id/EditText01 android:id=@+id/EditText01
android:layout_height=wrap_content
android:layout_width=fill_parent></EditText>
<Button android:id=@+id/Button01
android:layout_height=wrap_content
android:onClick=myClickHandler android:layout_width=wrap_content
android:text=Prihvati></Button>
<Button android:id=@+id/Button02
android:layout_width=wrap_content
android:layout_height=wrap_content
android:onClick=myClickHandler android:text=Odbaci></Button>
</LinearLayout>
Sve ono to smo ranije dobili grafikim oblikovanjem
suelja u nekoliko prozora razvojne okoline, ovdje je
prikazano u obinom XML formatu zapisa. Iskusniji
programeri mogu na ovom mjestu izravno izvoditi
promjene, pa ak i dodavanje novih objekata na suelje.
Na primjer, probajte jednostavno umnoiti dio teksta
namijenjen definiranju gumba Button02 pa ete dobiti
jo jedan identian gumb na korisnikom suelju.
Primijetimo na kraju dananjeg nastavka da u XML opisu oba gumba
postoji veza prema programskom kodu za obradu dogaaja onClick, jer je
autor teksta to ve pripremio u primjeru, ali zbog zadane veliine svakog
pojedinog nastavka serijala, o tome e neto vie rijei biti u sljedeem
broju.

Android programiranje #4: Uvod u pisanje programskoga koda.

U prolom, treem poglavlju Google Android programiranja, u poetnu


inaicu aplikacije HelloWorld dodali smo nekoliko osnovnih grafikih
objekata, te usput objasnili vie bitnih dijelova razvojne okoline Eclipse,
povezanih s postavljanjem i pregledom grafikih objekata koritenih u
aplikaciji, odnosno pripremom i izmjenom njihovih svojstava. Meutim,
tako dugo dok nacrtanim objektima ne dodamo nekakav programski kod,
oni u aplikaciji slue manje-vie samo kao ukras, pa kao takvi ne rade
nita pametno. Tek kada se objektima pridrue odgovarajue funkcije za
reakciju objekta na podraaj iz okoline (recimo pritisak na objekt od
strane korisnika aplikacije na zaslonu ureaja), poinje se doista neto
dogaati.
Vratimo se na trenutak ponovno na tekstualni prikaz dijela
datoteke main.xml, zaduene za definiranje izgleda objekata u aplikaciji,
ali istovremeno i za povezivanje nacrtanih objekata s dijelovima
programskoga koda. Usredotoimo se u nastavku na sljedee dijelove
datoteke:
<?xml version=1.0 encoding=utf-8?>

<Button android:id=@+id/Button01
android:layout_height=wrap_contentandroid:onClick=myClickHand
ler android:layout_width=wrap_content
android:text=Prihvati></Button>
<Button android:id=@+id/Button02
android:layout_width=wrap_content
android:layout_height=wrap_content android:onClick=myClickHan
dler android:text=Odbaci></Button>

Povezivanje objekata s programskim kodom: Izvedivo je


izravnim ureivanjem tekstualnog sadraja datoteke
Main.xml.
Dijelovi oznaeni istaknutim pismom zadueni su za
povezivanje oba nacrtana gumba u suelju s
odgovarajuom funkcijom u programskom kodu u ovom sluaju ona je
zaduena za obradu dogaaja izazvanog pritiskom korisnika na kontrolu.
Da odmah razjasnimo jednu vrlo bitnu stvar (kako se itatelji ne bi nali u
svojevrsnoj konfuziji pri praenju teksta), iako smo je ve spomenuli na
kraju prethodnog nastavka. Ako se pozorno pratili tekst iz prolog broja te
pokuali ponoviti sve opisane operacije, onda u vaem projektu
trenutno nema navedenih dijelova. U projektu autora teksta ti dijelovi
postoje, jer je primjer prvo napravljen do kraja, a tek onda je zapoeto
pisanje teksta. Odatle dolazi do istaknute razlike izmeu projekata, ali
emo odmah poduzeti sve potrebne operacije da ih uklonimo.

Na koji nain u vlastite projekte moete dodati dio koji nedostaje? Jedan
od naina izravni je upis prije oznaenoga teksta u prozoru zaduenom za
tekstualni prikaz sadraja datoteke main.xml. Drugi nain koritenje je
prozora Properties, nakon to eljeni objekt postane aktivan objekt (vidi
priloenu sliku uz tekst). U naem primjeru oba objekta povezana su s
istim dijelom programskog koda, jer se u njemu na jedinstven nain prvo
provjerava objekt na koji je korisnik programa napravio pritisak. Mogue
je napraviti i drugaije rjeenje. Svaki gumb moe biti povezan s
posebnom funkcijom za obradu dogaaja. Na autoru programa je odluiti
to je najbolje izabrati u odreenoj situaciji.
Pripadajui programski kod primjera u ovom trenutku ima sljedei oblik
(datoteka HelloWorld.java):
package helloWorld.java;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.os.Bundle;
public class helloWorld extends Activity {
private EditText text;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (EditText) findViewById(R.id.EditText01);
text.setText(No button pressed);
}
// Will be connected with the buttons via XML
public void myClickHandler(View view) {
switch (view.getId()) {
case R.id.Button01:
text.setText(Button 1 was clicked);
break;
case R.id.Button02:
text.setText(Button 2 was clicked);
break;
}
}
}

U prethodnom primjeru mogu se uoiti tri glavna dijela. Prvo je naveden


itav niz import naredaba kako bi se u vlastiti program ukljuili svi
potrebni dijelovi za izvoenje aplikacije. Pomou dijela:
public void onCreate(Bundle savedInstanceState) {
zapoinje drugi dio, odnosno izvoenje glavnog dijela programa. U njemu
se, osim inicijalizacije same aplikacije, postavlja poetna vrijednost
tekstualnog sadraja za trenutno jedini objekt u aplikaciji zaduen za
prikaz odnosno unos teksta (EditText01). Za to su zaduene naredbe za
njegovo pronalaenje meu postojeim objektima, a nakon toga za
postavljanje poetne vrijednosti.
setContentView(R.layout.main);
text = (EditText) findViewById(R.id.EditText01);
text.setText(No button pressed);
Kao to smo to ve spomenuli, u ovom primjeru oba gumba u aplikaciji
povezana su na zajedniki dio programskoga koda za obradu dogaaja.
Alternativni nain povezivanja: Koritenje prozora
Properties u razvojnoj okolini Eclipse.
Pomou naredbe switch provjerava se o kojem je
gumbu doista rije, a onda se izvodi jedan od dva
mogua nastavka. Svaki od njih izaziva prikaz drugaije
poruke u prije spomenutomu tekstualnom okviru. Ako je sve napravljeno
precizno, prema uputama iz ovog i prethodnog nastavka serijala, tijekom
izvoenja programa trebali biste dobiti identino ponaanje programa kao
na slikama uz tekst.
Pokupajmo sada u svrhu svojevrsne vjebe opisati sve potrebne izmjene
kako bi u programskom kodu primjera svaki gumb imao vlastitu proceduru
za obradu dogaaja. U praksi je to zapravo ee rjeenje zbog velike
razlike izmeu namjene pojedinih gumba u aplikaciji. Postojei programski
kod primjera helloWorld.java u tom sluaju treba izmijeniti u sljedei oblik.

package helloWorld.java;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.os.Bundle;
public class helloWorld extends Activity {
private EditText text;
/** Called when the activity is first created. */

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (EditText) findViewById(R.id.EditText01);
text.setText(No button pressed);
}
// first Button
public void myClickButton1(View view) {
text.setText(Button 1 was clicked);
}
// second Button
public void myClickButton2(View view) {
text.setText(Button 2 was clicked);
}
}
Poetni izgled prozora: Nakon pokretanja programa
pojavljuje se poetna poruka.
Budui da zajednika funkcija za obradu dogaaja
nakon pritiska na gumb vie ne postoji, nego je
zamijenjena s dvije pojedinane funkcije, treba korigirati
veze izmeu oba gumba i pripadajuega programskoga koda. To se
ponovno moe napraviti izmjenom svojstva On click u
prozoruProperties te upisivanjem
vrijednosti myClickButton1, odnosnomyClickButton2. Klikom na gumb
na krajnjoj desnoj strani toga reda moe se prikazati i dijaloki okvir za
odabir postojeih dijelova programskoga koda. Alternativni nain za
izvoenje iste operacije (neto bri, ali zahtijeva veu preciznost u
pisanju) izravna je izmjena tekstualnog sadraja datotekemain.xml. U
konanici, bez obzira na uporabljeni nain izmjene vrijednosti, u toj
datoteci treba biti sljedei sadraj.
<?xml version=1.0 encoding=utf-8?>

<Button android:id=@+id/Button01
android:layout_height=wrap_content
android:layout_width=wrap_content
android:text=Prihvati android:onClick=myClickButton1android:scr
ollHorizontally=false></Button>

<Button android:id=@+id/Button02
android:layout_width=wrap_content
android:layout_height=wrap_content
android:text=Odbaci android:onClick=myClickButton2></Button
>

Ovime je dovren poetni niz tekstova o razvoju aplikacija pomou


Google Android platforme. Ako ste pozorno pratili sve to je do sada
napisano o ovoj temi, sada biste na vlastitom raunalu trebali imati
pravilno instaliran razvojni sustav, a ujedno biste ga trebali poznavati do
razine koritenja koja omoguuje praenje i upis primjera iz sljedeih
nastavaka serijala. Kao i obino u kolama programiranja, praenje
tekstova olakat emo izdavanjem prateih primjera na digitalnomu
mediju uz asopis.
to emo raditi u buduim nastavcima? Zbog relativne ogranienosti
prostora za ovaj serijal u asopisu, kola programiranja u razvojnom alatu
Google
Izgled prozora nakon klika na prvi gumb: Poetna poruka
zamjenjuje se novom porukom.

Android dalje e izgledati neto drugaije nego to je to


bio sluaj s prethodnim slinim materijalima istog
autora. To znai da neemo obraivati segment po segment
programskoga jezika ni prateih biblioteka funkcija, a onda izmiljati
odgovarajui primjer za njihovu demonstraciju, nego emo raditi upravo
obrnutim redoslijedom. Prvo emo napraviti jedan ili vie sloenijih
primjera namijenjenih demonstraciji razliitih mogunosti Google Android
platforme, a onda objasniti to rade kljuni dijelovi primjera. Kao to smo
istaknuli na samom poetku serijala, za praenje tako koncipiranih
nastavaka oekuje se odreeno predznanje u smislu poznavanja osnovnih
pojmova uobiajenih u programerskom argonu, poput varijable, petlje ili
procedure. Drugim rijeima, to bi trebalo znaiti da ve posjedujete
osnovno praktino znanje programiranja u nekom drugom razvojnom
alatu.
U meuvremenu, dok ekate sljedei bitno kompliciraniji nastavak
serijala, moete sami pokuati dodati u projekt nekoliko novih gumba ili
drugaijih vrsta kontrola, a onda ih povezati s osnovnim dogaajem na
korisnikom suelju (On click).

Android programiranje #5: Koritenje rasporeda kontrola u sloenim aplikacijama

Nakon to smo proli put dotjerali do kraja s neto sloenijim Android


projektom u kojem je bilo i malo vie programskog koda, doao je
trenutak da se detaljnije pozabavimo najvanijim dijelovima razvojnog
alata, kako bi u slijedeim nastavcima mogli izraivati ozbiljnije aplikacije.
Jedna od tipinih karakteristika svake sloenije aplikacije, bez obzira na
softversku platformu na kojoj se izvodi, je postojanje veeg broja prozora,
formi ili zaslona (ve prema terminologiji uobiajenoj za tu razvojnu
platformu) u okviru iste aplikacije. Ni Android aplikacije po tom pitanju
nisu nikakav izuzetak.

U dosadanja dva jednostavna primjera aplikacija iz prethodnih


nastavaka serijala koristili smo isti pogled (odnosno istu vrstu rasporeda
osnovnih objekata) pod nazivom LinearLayout. U tim primjerima
zapravo se nismo previe obazirali na karakteristike koritenog rasporeda
kontrola, nego smo jednostavno po njemu postavili ostale objekte
koritene u aplikaciji (dva gumba i jedan okvir za unos teksta). Glavna
tema dananjeg teksta posveena je upravo razliitim vrstama rasporeda
osnovnih kontrola dostupnim u okviru Android platforme, to ukljuuje
opisivanje njihovih mogunosti i naina koritenja.
U okviru Google Android platforme dostupne su slijedee vrste rasporeda
osnovnih objekata:
1.
2.
3.
4.
5.
6.

LinearLayout
AbsoluteLayout
TableLayout
RelativeLayout
FrameLayout
ScrollView
Poetni raspored osnovnih kontrola: Koristi se
podrazumijevani raspored osnovnih kontrola
LinearLayout.

Prije nego to malo detaljnije objasnimo svaki od


rasporeda, posvetimo rije, dvije izvornoj terminologiji te
hrvatskim pojmovima koritenim u tekstu. U originalnoj terminologiji
osnovni objekti (npr. gumb, okvir za tekst i slino) nazivaju se Widget, a
kad su vidljivi na zaslonu View. PojmomViewGroup (u osnovi takoer
posebnoj vrsti pogleda) oznaava se skupina osnovnih Viewa
razmjetena po zaslonu u odreenom rasporedu to je ovih 6 rasporeda
spomenutih u prethodnom nabrajanju. Sad kad smo nabrojili temeljne
engleske pojmove navedimo i to koje emo prijevode koristi u nastavku
teksta da ne stvaramo nepotrebnu zabunu. Umjesto pojmova Widget i
View koristit emo rijei objekt ili kontrola, dok e ViewGroup biti
zamijenjen s pogled ili raspored kontrola. To moda nije najbolje mogue
rjeenje prijevoda, ali s druge strane predstavlja vrlo estu terminologiju
koritenu u opisu drugih razvojnih alata. Ako ste ve koristili neki od njih,
bez problema ete pratiti reenice u tekstu kojeg upravo itate.
Vratimo se sada na glavnu temu dananjeg teksta koritenje razliitih
rasporeda osnovnih kontrola u vlastitim aplikacijama. Obavimo to istim
redom kao u ranijem nabrajanju.
LinearLayout predstavlja osnovni raspored kontrola gdje su sve
osnovne kontrole rasporeene u samo jednom redu ili samo jednom
stupcu. Tijekom rada na osnovna dva projekta u prethodnim nastavcima,
nove kontrole su se uvijek pojavljivale jedna ispod druge, jer smo koristili

upravo taj osnovni raspored kontrola automatski predloen od strane


razvojne okoline tijekom stvaranja projekta. Iako za sloenije aplikacije
ovakav raspored osnovnih kontrola nije uvijek i najpogodnije rjeenje, kod
poetnih koraka u novom razvojnom alatu zapravo nema nekih prevelikih
zamjerki na njegovo koritenje.
Kod drugog od spomenutih rasporeda
kontrola AbsoluteLayout programer nije ogranien na neki od
podrazumijevanih oblika redanja osnovnih kontrola po pozadini, nego
ima potpunu slobodu u njihovom postavljanju na dostupnom podruju. O
samim svojstvima potrebnim za pozicioniranje svake pojedine kontrole na
ovakvoj vrsti pogleda odnosno rasporeda, bit e vie rijei slijedei put.
Raspored kontrola pod nazivom TableLayout, kao to to sam naziv
govori, koristi se kod razvrstavanja osnovnih kontrola u vie redova ili
stupaca tablice, odnosno u elije tablice. Na taj nain mogu se dobiti
lijepi pravilni rasporedi osnovnih kontrola na pogledu, to se vrlo esto
koristi kod razliitih vrsta unosa podataka u aplikacijama.
U RelativeLayout rasporedu kontrole se mogu postaviti na razliita
mjesta na dostupnom prostoru za njihovo prikazivanje, ali tono mjesto
svake kontrole nije odreeno njezinim apsolutnim koordinatama kao kod
rasporeda pod nazivom AbsoluteLayout, nego je pozicija osnovne kontrole
definirana relativnim koordinatama prema drugoj osnovnoj kontroli.
FrameLayout se u aplikacijama koristi za rezerviranje mjesta za
naknadno postavljanje drugih kontrola tako da se one uvijek sidre
prema gornjem lijevom uglu FrameLayout rasporeda kontrola. Sve e biti
jasnije kad se to prikae slikom u nekoj od buduih aplikacija.
Zadnja vrsta rasporeda osnovnih kontrola pod
nazivom ScrollView koristi se u sluajevima kad na fizikim dimenzijama
zaslona jednostavno nije mogue prikazati sve potrebne osnovne kontrole
na smislen i pregledan nain (bez meusobnog preklapanja i jasnog
razdvajanja). Pogled ScrollView zapravo predstavlja posebnu vrstu
rasporeda FrameLayout na koju se u praksi obino postavlja dodatna vrsta
osnovnog rasporeda kontrola (RelativeLayout).
U okviru jedne sloene aplikacije moe se koristiti vei broj istih ili
razliitih vrsta rasporeda kontrola, izmeu kojih se prebacivanje, to jest
aktiviranje nekog drugog rasporeda, izvodi pomou programskog koda.
Pogledajmo sada kako koritenja razliitih rasporeda izgleda na nekoliko
primjera.
Osnovni raspored kontrola iz dovrenog primjera u prethodnom
nastavku, koji je koristio podrazumijevani raspored LinearLayout imao je
slijedei XML oblika zapisa.
<?xml version=1.0 encoding=utf-8?>
<LinearLayout
xmlns:android=http://schemas.android.com/apk/res/android
android:orientation=vertical
android:layout_width=fill_parent

android:layout_height=fill_parent android:background=@color/BijelaB
oja>
<TextView
android:layout_width=fill_parent
android:layout_height=wrap_content
android:text=@string/hello
/>
<EditText android:text=@+id/EditText01 android:id=@+id/EditText01
android:layout_height=wrap_content android:layout_width=fill_parent
>
</EditText>
<Button
android:id=@+id/Button01 android:layout_height=wrap_content
android:layout_width=wrap_content android:text=Prihvati
android:onClick=myClickButton1 android:scrollHorizontally=false>
</Button>
<Button
android:id=@+id/Button02 android:layout_width=wrap_content
android:layout_height=wrap_content android:text=Odbaci android:on
Click=myClickButton2>
</Button>
</LinearLayout>
Raspored kontrola AbsoluteLayout: Sve kontrole se
preklapaju jer jo nisu upisane njihove apsolutne
koordinate.
Ako u prethodnom XML kodu izmijenimo samo naziv
rasporeda LinearLayout u AbsoluteLayout, sve kontrole
skupit e se u gornjem lijevom uglu prikaza, jer bi u
ovakvom rasporedu trebalo obavezno navesti apsolutne vrijednosti
pozicija kontrola. Budui da to jo uvijek nismo napravili, uzete su
podrazumijevene vrijednosti 0, to je izazvalo spomenuto skupljanje
kontrola.
Navoenjem apsolutnih vrijednosti za poziciju i veliinu kontrola dolazi
do njihovog eljenog formatiranja, kao to to pokazuje pratea slika uz
tekst.
<?xml version=1.0 encoding=utf-8?>
<AbsoluteLayout
xmlns:android=http://schemas.android.com/apk/res/android
android:orientation=vertical
android:layout_width=fill_parent

android:layout_height=fill_parent android:background=@color/BijelaB
oja>
<TextView
android:layout_width=fill_parent
android:layout_height=wrap_content
android:text=@string/hello
/>
<EditText android:text=@+id/EditText01 android:id=@+id/EditText01
android:layout_x=40px
android:layout_y=50px
android:layout_width=400px
android:layout_height=50px>
</EditText>
<Button android:id=@+id/Button01
android:text=Prihvati
android:onClick=myClickButton1
android:layout_x=40px
android:layout_y=100px
android:layout_width=100px
android:layout_height=50px>
</Button>
<Button android:id=@+id/Button02
android:text=Odbaci
android:onClick=myClickButton2
android:layout_x=340px
android:layout_y=100px
android:layout_width=100px
android:layout_height=50px>
</Button>
</AbsoluteLayout>

Raspored kontrola AbsoluteLayout: Za svaku kontrolu su


navedene apsolutne vrijednosti za odreivanje izgleda.

Zamjenom apsolutnog rasporeda kontrola relativnim u


okviru XML definicije vie nije potrebno navoditi
apsolutne vrijednosti pozicija kontrola, nego samo njihovu relativnu
poziciju u odnosu na neku drugu kontrolu. Apsolutne vrijednosti zaduene
za definiranje veliine kontrole mogu se koristiti i dalje na isti nain.

Na temelju slijedeeg XML sadraja, pomou relativnog rasporeda


kontrola oponaan je poetni raspored kontrola LinearLayout.
<?xml version=1.0 encoding=utf-8?>
<RelativeLayout
xmlns:android=http://schemas.android.com/apk/res/android
android:orientation=vertical
android:layout_width=fill_parent
android:layout_height=fill_parent android:background=@color/BijelaB
oja>
<TextView
android:layout_width=fill_parent
android:layout_height=wrap_content
android:text=@string/hello
/>
<EditText android:text=@+id/EditText01 android:id=@+id/EditText01
android:layout_alignParentTop=true
android:layout_alignParentLeft=true
android:layout_width=400px
android:layout_height=50px>
</EditText>
<Button android:id=@+id/Button01
android:text=Prihvati
android:onClick=myClickButton1
android:layout_alignLeft=@+id/EditText01
android:layout_below=@+id/EditText01
android:layout_width=100px
android:layout_height=50px>
</Button>
<Button android:id=@+id/Button02
android:text=Odbaci
android:onClick=myClickButton2
android:layout_alignLeft=@+id/EditText01
android:layout_below=@+id/Button01
android:layout_width=100px
android:layout_height=50px>
</Button>
</RelativeLayout>
U prethodna tri primjera koriteno je nekoliko dodatnih elemenata za
definiranje rasporeda osnovnih kontrola u okviru osvnovne XML datoteke
za

Raspored kontrola RelativeLayout: U ovom sluaju je


oponaan osnovni raspored LinearLayout.
definiranje izgleda zaslona. Neto vie rijei o njihovoj
namjeni moete proitati u slijedeem poglavlju

Android programiranje #6: Koritenje osnovnih Android kontrola

Nakon to smo raspravili to su to zapravo rasporedi osnovnih kontrola,


u dananjem nastavku uvoda u Android programiranje moemo prijei na
drugi bitan preduvjet izrade korisnikog suelja, a to je upoznavanje
osnovnih kontrola namijenjenih za postavljenje na takve rasporede. No,
prije toga evo jednog primjera programskog koda (za kojeg nije bilo
mjesta u prolom nastavku), gdje se korisniko suelje u potpunosti stvara
programskim kodom.
Drugim rijeima, ako je programeru iz nekog razloga tako zgodnije, ne
mora prvo crtati korisniko suelje u odgovarajuem prozoru razvojne
okoline, a onda dodavati programski kod da oivi nacrtane kontrole,
nego sve to moe napraviti u jednom prolazu iskljuivo programskim
kodom. Ako ste ve u prolosti koristili Microsoft Visual Studio, onda e
vam sve biti mnogo jasnije kad napiemo da je rije o postupku
analognom dinamikom dodavanju kontrola na formu tijekom izvoenja
programa.
package Hello.Android;

import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;
public class HelloActivity extends Activity
{
private LinearLayout prezimeime;
private LinearLayout adresa;
private LinearLayout podloga;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
createPrezimeIme();
createAdresa();
createPodloga();
setContentView(podloga);
}
private void createPodloga()
{
podloga = new LinearLayout(this);
podloga.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT
, LayoutParams.FILL_PARENT));
podloga.setOrientation(LinearLayout.VERTICAL);
podloga.addView(prezimeime);
podloga.addView(adresa);
}
private void createPrezimeIme()
{
prezimeime = new LinearLayout(this);
prezimeime.setLayoutParams(new LayoutParams(LayoutParams.FILL_PAR
ENT, LayoutParams.WRAP_CONTENT));
prezimeime.setOrientation(LinearLayout.HORIZONTAL);
TextView prezimeLbl = new TextView(this);
prezimeLbl.setText(Prezime ime: );
TextView prezime2Lbl = new TextView(this);

prezime2Lbl.setText(Android Vid);
prezimeime.addView(prezimeLbl);
prezimeime.addView(prezime2Lbl);
}
private void createAdresa()
{
adresa = new LinearLayout(this);
adresa.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
adresa.setOrientation(LinearLayout.VERTICAL);
TextView adresaLbl = new TextView(this);
adresaLbl.setText(Adresa:);
TextView adresa2Lbl = new TextView(this);
adresa2Lbl.setText(Redacija VIDI);
adresa.addView(adresaLbl);
adresa.addView(adresa2Lbl);
}
}

Stvaranje rasporeda kontrola i samih kontrola pomou


programskog koda: Ne treba uvijek prvo nacrtati kontrole
u razvojnoj okolini.
Prethodni programski primjer tijekom svojeg izvoenja
stvara osnovni raspored kontrola pod nazivom podloga,
a onda na njega dodaje tekstualne kontrole za prikaz imena i adrese.
Slian postupak se moe primijeniti za sve vrste kontrola. Ako ne volite
prekucavati primjere, moete ga pronai na prateem digitalnom mediju
uz asopis.
Vratimo se sada glavnom dijelu teksta kontrolama namijenjenim
postavljanju na neki od osnovnih rasporeda kontrola te njihovim
najbitnijim svojstvima. Ako ste ve koristili neki od modernijih razvojnih
alata, ponovo ete pronai dosta slinosti, a ako niste, onda svakako
pogledajte tekst u nastavku te sami pokuajte napraviti nekoliko vlastitih
primjera s takvim kontrolama. Kontrole emo u nastavku prikazati prema
uestalosti u aplikacijama dakle prvo one koje se najee koriste.
TextView

Kontrola tipa TextView namijenjena je prikazu razliitih vrsta tekstova na


zaslonu, ali bez mogunosti njihove izmjene odnosno ureivanja. Zato se
ova vrsta kontrole u vlastitim aplikacijama najee koristi za prikaz
informacija korisniku poput dodatnih opisa uz glavne kontrole koje
omoguavaju ureivanje teksta. Meutim, ako dio prikazanog teksta
predstavlja web adresa, onda se kontrola moe upotrijebiti znatno
kreativnije, tako da klik miem na web adresu otvara preglednik te
prikazuje njezin sadraj (vidi primjer slike uz tekst).
Da bi demonstrirali takvo ponaanje kontrole TextView u prethodnom
programskom primjeru treba napraviti dvije izmjene. Prvo, treba u
aplikaciju ukljuiti posebnu klasu za pronalaenje veze prema veb adresi
u tekstualnom nizu znakova (klasa Linkify):
import android.widget.LinearLayout;
import android.widget.TextView;
import android.text.util.Linkify;
a onda dodati novu kontrolu nazvanu txtWeb iji tekstualni sadraj
ukljuuje web adresu:
private void createPodloga()
{
podloga = new LinearLayout(this);
podloga.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT
, LayoutParams.FILL_PARENT));
podloga.setOrientation(LinearLayout.VERTICAL);
podloga.addView(prezimeime);
podloga.addView(adresa);
TextView txtWeb = new TextView(this);
txtWeb.setText(Dodatne informacije o Android programiranju na
http://www.vidilab.com/);
Linkify.addLinks(txtWeb, Linkify.ALL);
podloga.addView(txtWeb);
}
Nakon pokretanja programa, kao to to demonstrira pratea slika uz
tekst, u sadraju kontrole pojavljuje se posebno istaknuta web adresa, a
klik na adresu otvara njezin sadraj u podrazumijevanom pregledniku.
EditText
Ako je korisniku potrebno omoguiti da u programu upie odnosno da
uredi postojei tekstualni sadraj, onda umjesto kontrole tipa
TextView treba

Koritenje kontrole TextView: Omoguava i otvaranje


sadraja zadane web adrese.
koristiti kontrolu tipa EditText. Treba istaknuti kako ni ova
vrsta kontrole nije zamiljena za upis velikih tekstova,
nego prije svega kraih podataka kakvi se obino
zapisuju u pojedine stupce baze podataka. Kontrola
EditText posjeduje brojna dodatna svojstva ijom
promjenom vrijednosti se moe bitno izmijeniti ponaanje kontrole, prije
svega nain prikaza teksta. Na primjer:
Auto text automatski ispravlja mogue pogreke tijekom upisa teksta
Capitalize pretvara upisana slova u velika slova
Numeric postavlja brojani unos podataka
Password postavlja upis lozinke (ne vide se znakovi kod upisa)
Phone number - postavlja unos telefonskog broja
Single line - definira unos teksta u jednom redu
Slijedei primjer pokazuje dinamiko dodavanje tekstualne kontrole na
osnovni raspored kontrola uz koritenje dvije dopunske metode za prikaz
dodatnih informacija uz kontrolu.
private void createPodloga()
{
podloga = new LinearLayout(this);
podloga.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT
, LayoutParams.FILL_PARENT));
podloga.setOrientation(LinearLayout.VERTICAL);
podloga.addView(prezimeime);
podloga.addView(adresa);
/* dodatak 1 primjer koritenja kontrole TextView */
TextView txtWeb = new TextView(this);
txtWeb.setText(Dodatne informacije o Android programiranju na
http://www.vidilab.com/);
Linkify.addLinks(txtWeb, Linkify.ALL);
podloga.addView(txtWeb);
/* dodatak 2 primjer koritenja kontrole EditText */
EditText txtKorisnik = new EditText(this);
txtKorisnik.setText (Upiite korisniko ime);
txtKorisnik.setHint(Pazite na upis malih i velikih slova);
txtKorisnik.setError(Pazite na veliinu slova);
podloga.addView(txtKorisnik);

}
Rezultat klika na web adresu u kontroli TextView: Prikaz
sadraja zadane adrese u pregledniku.
Posebnu vrstu kontrola za upis teksta predstavljaju
kontroleAutoCompleteTextView te MultiAutoComple
teTextView. Njihova najvanija znaajka je da tijekom
upisa/ispravljanja teksta omoguavaju automatsko
dovravanje upisanog teksta. Evo i primjera odgovarajueg programskog
koda nadopisanog na kraj postojeeg programskog koda u
funkciji createPodloga.
private void createPodloga()
{
podloga = new LinearLayout(this);
podloga.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT
, LayoutParams.FILL_PARENT));
podloga.setOrientation(LinearLayout.VERTICAL);
podloga.addView(prezimeime);
podloga.addView(adresa);
/* dodatak 1 primjer koritenja kontrole TextView */
TextView txtWeb = new TextView(this);
txtWeb.setText(Dodatne informacije o Android programiranju na
http://www.vidilab.com/);
Linkify.addLinks(txtWeb, Linkify.ALL);
podloga.addView(txtWeb);
/* dodatak 2 primjer koritenja kontrole EditText */
Primjer koritenja kontrole EditText: Kontrola se koristi za
upis i izmjenu teksta.

EditText txtKorisnik = new EditText(this);


txtKorisnik.setText (Upiite korisniko ime);
txtKorisnik.setHint(Pazite na upis malih i velikih slova);
txtKorisnik.setError(Pazite na veliinu slova);
podloga.addView(txtKorisnik);

/* dodatak 3 primjer koritenja kontrole AutoCompleteTextView */


AutoCompleteTextView actv = new AutoCompleteTextView(this);
ArrayAdapter<String> aa = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line,
new String[] {English, Hebrew, Hindi, Spanish, German,
Greek });
actv.setAdapter(aa);
podloga.addView(actv);
}
Nakon upisa poetnih slova (npr. en) automatski se predlae
podudarajua potpuna
tekstualna vrijednost, pa se ona nakon toga moe
jednostavno izabrati umjesto da se upisuje u cijelosti.
Buttons
Android platforma omoguava koritenje tri razliita
tipa gumbi osnovni gumb (Button Control), gumb sa
slikom (ImageButton Control) te gumb s mogunou
prikaza dva razliita stanja gumba (ToggleButton
Control). Osnovni tip gumba ve smo koristili u
primjerima iz prethodnih nastavaka serijala, a detaljne mogunosti
koritenja sva tri tipa gumbi predstavit emo u slijedeem nastavku
serijala zajedno s ostatkom osnovnih kontrola.

Android programiranje #7

S predstavljanjem osnovnih Android kontrola proli put smo zastali na


dobro poznatim gumbima (Buttons). Kao i u drugim modernim
operativnim sustavima ovaj tip kontrole koristi se u aplikacijama za
izvoenje razliitih operacija, a (ponovo kao i u drugim operativnim
sustavima) moe imati nekoliko pojavnih oblika.
Osnovni oblik gumba (Button) na sebi sadri samo obian tekst koji
oznaava kakvu e operaciju u okviru odreene aplikacije izazvati pritisak
na gumb. Ako zadnjih nekoliko desetljea niste proveli izolirani u samici
nekog zaostalog nedemokratskog reima bez ikakvog kontakta s
modernim raunalima, onda je prethodna reenica sasvim dovoljna da
shvatite o emu je ovdje rije. Budui da smo ovaj gumb ve nekoliko
puta koristili u primjerima iz prethodnih nastavaka serijala, kako u
pogledu izmjene osnovnih svojstava, tako i u pogledu dodavanja
programskog koda, neemo se vie ni baviti njime.
Budui da se moderna korisnika suelja sve vie temelje na slici nego
na rijei, razumljivo da je obian gumb doivio svojevrsnu vizualnu
nadogradnju, postavi tako u Android terminologiji kontrola pod nazivom
ImageButton. Namjena unaprijeene kontrole je potpuno jednaka kao i u
njezinom osnovnom obliku, jedino to takav gumb moe izgledati bitno
ljepe (to izravno ovisi o slici postavljenoj na njegovu povrinu). Upravo
je zamjena osnovnih vrsta gumbi slikovnim jedan od najvanijih, ali
ujedno i najjednostavnijih naina da vlastitu aplikaciju uinite
atraktivnijom te u konanici privlanijom potencijalnim korisnicima.
Slikovna verzija gumba povezuje se s odgovarajuom datotekom s
grafikim sadrajem pomou svojstva src, to se moe napraviti u za to
namijenjenom prozoru razvojne okoline, izravno u XML datoteci, ili
programskim kodom. U priloenoj segmentu XML datoteke prikazan je
primjer koritenja drugog od nabrojenih naina, dok se za istu namjenu u
programskom kodu treba koristiti metoda setImageResource().
Trea vrsta gumba pod nazivom ToggleButton omoguava prikaz vie
stanja iste pojave unutar aplikacije. Na primjer, jednim stanjem gumba
moe se pokazati da je ukljuen nekakav parametar odnosno izvoenje
nekakve operacije, a drugim stanjem da je parametar iskljuen odnosno
da je prekinuto izvoenje operacije. U praksi se takva vrsta gumbi
najee koristi za prilagoavanje razliitih dijelova aplikacije eljama i
potrebama korisnika aplikacije. Kao to to ponovo prikazuje priloena XML
datoteka sa definicijama sve tri vrste opisanih gumbi, pomou dva
dodatna svojstva gumba android:textOn=Pokrenuto
android:textOff=Zaustavljeno> mogue je definirati dva razliita
tekstualna sadraja za prikazivanje na samom gumbu ovisno o njegovom
trenutnom stanju (ukljueno / iskljueno).

<?xml version=1.0 encoding=utf-8?>


<LinearLayout
xmlns:android=http://schemas.android.com/apk/res/android
android:orientation=vertical
android:layout_width=fill_parent
android:layout_height=fill_parent
>
<TextView
android:layout_width=fill_parent
android:layout_height=wrap_content
android:text=@string/hello
/>
<Button android:id=@+id/Button01
android:layout_width=wrap_content
android:layout_height=wrap_content android:text=Tekst
gumb></Button>
<ImageButton android:id=@+id/ImageButton01
android:layout_width=wrap_content
android:layout_height=wrap_content
android:src=@drawable/icon></ImageButton>
<ToggleButton android:text=@+id/ToggleButton01
android:id=@+id/ToggleButton01 android:layout_width=wrap_content
android:layout_height=wrap_content android:textOn=Pokrenuto
android:textOff=Zaustavljeno></ToggleButton>
<RadioButton android:id=@+id/RadioButton01
android:layout_width=wrap_content
android:layout_height=wrap_content android:text=Opcija1
android:checked=true></RadioButton>
<RadioButton android:id=@+id/RadioButton02
android:layout_width=wrap_content
android:layout_height=wrap_content android:text=Opcija2
android:checked=false></RadioButton>
</LinearLayout>
Kako izgleda korisniko suelje nastalo na temelju prethodne XML
datoteke moete vidjeti na priloenoj slici uz dananji tekst.
Zadnjoj od prije opisanih kontrola prilino sline su jo dvije vrste
kontrola. To su CheckBox i RadioButton. Rije je o kontrolama koje su
zapravo i poznatije korisnicima aplikacija, jer su osim na Android platformi
prisutne u praktino svim modernim grafikim sueljima dananjice. Obje
od navedenih kontrola omoguavaju ukljuivanje/iskljuivanje razliitih
opcija, ali se meusobno razlikuju u situacijama kad u korisnikom suelju

aplikacije postoji vie kontrola istog tipa. CheckBox kontrole su u pogledu


meusobnog stanja neovisne jedne od druge, to znai da ukljuivanje ili
iskljuivanje jedne od kontrola ne utjee na stanje druge kontrole. Osim
promjene trenutnog stanja od strane krajnjeg korisnika aplikacije,
vrijednosti se mogu postavljati programskim kodom koritenjem metode
setChecked() dok se trenutno stanje moe dobiti pomou isChecked().
Trenutno stanje neke RadioButton kontrole ovisi o stanju drugih kontrola
iste vrste, to drugim rijeima znai da u jednom trenutku samo jedna od
takvih kontrola moe biti ukljuena, dok sve druge kontrole automatski
poprimaju vrijednost iskljueno. Zato se ova vrsta kontrola koristi za rad s
vrijednosti koje se meusobno iskljuuju. Sa stanovita programskog koda
ukljuivanje/iskljuivanje stanja kontrole provodi se na slian nain kao i
kod CheckBox kontrola. Spomenimo na ovom mjestu i to da se pojam
meusobnog iskljuivanja RadioButton kontrola odnosi na kontrole u
istom spremniku kontrola. Ako u aplikaciji trebaju postojati dvije
neovisne grupe takvih kontrola, onda treba pripremiti i dva spremnika
(npr. rasporeda kontrola).
Evo kratkog segmenta XML datoteke namijenjenog definiranju obiju vrsta
kontrola.
CheckBox kontrole:
<LinearLayout
xmlns:android=http://schemas.android.com/apk/res/android
android:orientation=vertical android:layout_width=fill_parent
android:layout_height=fill_parent>: Building User Interfaces and
Using Controls
<CheckBox android:text=Juha
android:layout_width=wrap_content
android:layout_height=wrap_content />
<CheckBox android:text=GlavnoJelo
android:layout_width=wrap_content
android:layout_height=wrap_content />
<CheckBox android:text=Desert
android:layout_width=wrap_content
android:layout_height=wrap_content />
</LinearLayout>
RadioButton kontrole:
Koritenje gumbi: Programeru su na raspolaganju tri
razliite vrste gumbi.

<LinearLayout
xmlns:android=http://schemas.android.com/apk/res/android

android:orientation=vertical android:layout_width=fill_parent
CHAPTER 4: Building User Interfaces and Using Controls 137
android:layout_height=fill_parent>
<RadioGroup android:id=@+id/rBtnGrp
android:layout_width=wrap_content
android:layout_height=wrap_content
android:orientation=vertical >
<RadioButton android:id=@+id/pRBtn android:text=Piletina
android:layout_width=wrap_content
android:layout_height=wrap_content/>
<RadioButton android:id=@+id/sRBtn android:text=Svinjetina
android:layout_width=wrap_content
android:layout_height=wrap_content/>
<RadioButton android:id=@+id/gRBtn android:text=Govedina
android:layout_width=wrap_content
android:layout_height=wrap_content/>
</RadioGroup>
</LinearLayout>
U izmiljenoj aplikaciji za naruivanje u restoranu u prvom sluaju
korisnik aplikacije moe oznaiti razliite dijelove obroka neovisno jedan o
drugome, a u drugom sluaju za glavni obrok moe izabrati samo jednu
od vrsta glavnog jela (mesa).

Android programiranje #8: Android kontrole u akciji IV

Vrlo vaan dio gotovo svake aplikacije (osim onih krajnje trivijalnih, ili
onih koje su potpuno optimizirane za neko specijalizirano podruje) je
upravljanje vremenom. ak i razliite igre, kao kategorija aplikacija kakve
se vrlo esto piu za mobilne ureaje ukljuujui i Android platformu,
esto spremaju razliite podatke o igrau ili statusu igre povezane s
datumom i vremenom. Naravno, za prikaz ili izmjenu datuma i vremena
programer uvijek moe izmisliti svoje vlastite kontrole, ali nije loe kad je i
osnovni razvojni sustav opremljen odgovarajuim kontrolama. To posebno
vrijedi kod aplikacija s naglaskom na funkcionalnosti, a ne na vizualnoj
raskoi.
Android platforma opremljena je s dvije meusobno prilino razliite vrste
kontrola za tu namjenu. Prva grupa kontrola moe samo prikazati podatke
o vremenu, dok ih druga vrsta moe prikazati, ali i dozvoliti izmjenu
vrijednosti od strane krajnjeg korisnika aplikacije. U prvu grupu kontrola
pripadaju kontroleAnalogClock i DigitalClock (sam naziv u potpunosti
govori o emu je rije). Glavni nedostatak im je odreen ve prije
spomenutom namjenom (prikazom podataka), pa se u praksi koriste
neto rjee, osim ako je dovoljno da kontrola zaista samo prikazuje datum
ili vrijeme. Zato se s navedene dvije kontrole vie neemo baviti. Ako
njihova ogranienja zadovoljavaju vae planove u izradi aplikacija,
jednostavno ih postavite na neki od standardnih rasporeda kontrola i
zaboravite na njih.

U sluaju da je potrebno omoguiti nekakav oblik


interakcije korisnika aplikacije u pogledu odabira
datuma i/ili vremena, onda je bolje upotrijebiti kontrole
pod nazivom DatePicker i TimePicker. Njihovo
postavljanje na osnovni raspored kontrola moe se
napraviti prema slijedeem primjeru.
<?xml version=1.0 encoding=utf-8?>
<LinearLayout
xmlns:android=http://schemas.android.com/apk/res/android
android:orientation=vertical

android:layout_width=fill_parent
android:layout_height=fill_parent>
<DatePicker android:id=@+id/datePicker
android:layout_width=wrap_content android:layout_height=wrap_cont
ent />
<TimePicker android:id=@+id/timePicker
android:layout_width=wrap_content android:layout_height=wrap_cont
ent />
</LinearLayout>
Prva (gornja) kontrola zaduena je za prikaz, odnosno odabir datuma, a
donja to isto radi s vremenom, kao to se to moe provjeriti na priloenoj
slici uz tekst. Kad se tome pridoda programski kod naveden u nastavku
zaduen za podeavanje poetnih vrijednosti kontrola, dobije se sasvim
funkcionalno korisniko suelje. Najvei nedostatak ove grupe kontrola je
njihova relativna nezgrapnost. Drugim rijeima jednostavno su prevelike
za intenzivno koritenje, naroito ako koristite ureaj s relativno
skromnom rezolucijom zaslona. Ako to predstavlja nepremostivu prepreku
moete se snai i sami te napraviti vlastite i bitno manje kontrole.
package Hello.Android;
import android.app.Activity;
import android.os.Bundle;
import android.widget.DatePicker;
import android.widget.TimePicker;
public class HelloActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

DatePicker dp = (DatePicker)this.findViewById(R.id.datePicker);
dp.init(2010, 11, 13, null);
TimePicker tp = (TimePicker)this.findViewById(R.id.timePicker);
tp.setIs24HourView(true);
tp.setCurrentHour(new Integer(10));
tp.setCurrentMinute(new Integer(10));
}
}
Koritenje izbornika
Osim sasvim jednostavnih uradaka veina aplikacija podrava neki oblik
sustava izbornika namijenjen izboru svih operacija koje nudi aplikacija. Ni
Android platforma po tome nije nikakav izuzetak. Zapravo mogli bi rei da
vrijedi ak suprotno programeru je na raspolaganju nekoliko razliitih
sustava izbornika, a na njemu je odlui koji od njih najvie odgovara
potrebama konkretne aplikacije. Dok ste neke od dostupnih sustava
izbornika ve susretali na drugim operativnim sustavima u vrlo slinom
obliku, Android nudi i neke novosti na ovom podruju, zbog ega emo se
izbornicima pozabaviti u dva broja asopisa.
Po obiaju kreemo od najjednostavnijeg oblika izbornika, za iju pojavu
u aplikaciji je zaduen iskljuivo programski kod nalik na onaj pridodan na
kraj prethodnog projekta za prikaz datumski i vremenski orijentiranih
kontrola (funkcija onCreateOptionsMenu). Navedeni naziv funkcije je
obavezan i ujedno povezan s odgovarajuom aktivnosti u programu.
package Hello.Android;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.DatePicker;
import android.widget.TimePicker;
public class HelloActivity extends Activity {
/** Called when the activity is first created. */

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DatePicker dp = (DatePicker)this.findViewById(R.id.datePicker);
dp.init(2010, 11, 13, null);
TimePicker tp = (TimePicker)this.findViewById(R.id.timePicker);
tp.setIs24HourView(true);
tp.setCurrentHour(new Integer(10));
tp.setCurrentMinute(new Integer(10));
}
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
menu.add(0 // Group
,1 // item id
,0 //order
,append); // title
menu.add(0,2,1,edit);
menu.add(0,3,2,clear);
return true;
}
}
Rezultat izvoenja dodatnog programskog koda su tri opcije izbornika,
koje se pojavljuju na samom dnu zaslona). Kao to to pokazuje prethodni

primjer dodavanje svake od opcija izbornika zahtijeva navoenje etiri


parametra.To su redom oznaka grupe, oznaka opcije izbornika, redoslijed
opcije u okviru izbornika, te tekst koji se prikazuje na samoj opciji
izbornika. Prve tri opcije su brojane, a etvrta je iz sasvim razumljivih
razloga tekstualna. Zadnja od nabrojenih opcija moe se u programskom
kodu za generiranje izbornika zadati izravno, kao to je to sluaj u
prethodnom primjeru, ili se odgovarajua vrijednost moe unaprijed
pripremiti u resursnoj datoteci. Istaknimo kako nije uvijek potrebno
navoditi ba sve brojane vrijednosti, nego se umjesto njih moe
upotrijebiti vrijednost Menu.None.
Ako je potrebno opcije izbornika u aplikaciji grupirati u vie od jedne
grupe, onda se to rjeava navoenjem razliitih oznaka grupe prilikom
zadavanja naredbi za stvaranje opcija izbornika. Takva podjela izbornika
na dvije grupe prikazana je u slijedeem segmentu programskog koda,
kojeg treba umetnuti u program umjesto istoimene funkcije iz prethodnog
kompletnog primjera koda. Kako e izgledati dobijeni rezultat moe se
vidjeti na priloenoj slici uz tekst.
public boolean onCreateOptionsMenu(Menu menu)
{
//Group1
int group1 = 1;
menu.add(group1,1,1,g1.item1);
menu.add(group1,2,2,g1.item2);
//Group2
int group2 = 2;
menu.add(group2,3,3,g2.item1);
menu.add(group2,4,4,g2.item2);
return true;
}
Kao to smo to ve objasnili ranije, prethodne naredbe izazivaju samo
prikaz izbornika na zaslonu ureaja, ali pritisak na te izbornike trenutno
ne izaziva ba nikakvu reakciju, jer jednostavno nedostaje odgovarajueg
programskog koda za tu namjenu. To je tema kojom emo se pozabaviti u
slijedeem broju, ba kao i dodavanjem slika na opcije izbornika, kako bi
se postigao to bolji vizualni dojam u vlastitoj aplikaciji.

U ostatku dananjeg teksta navest emo karakteristike preostalih vrsta


izbornika dostupnih na Android platformi. Prva vrsta su
takozvani proireni izbornici. Ova vrsta izbornika nastaje automatski,
ako programer pretjera s brojem opcija osnovnog izbornika. U tom
sluaju se kao opcija izbornika automatski prikazuje vrijednost More, a
njezinim odabirom korisnik aplikacije moe stii do poetno skrivenih
opcija izbornika. Jedno od ogranienja proirenih izbornika je u tome to
ne dozvoljavaju prikaz slike, pa zato prilikom pripreme izbornika treba
paziti da se na istom mjestu u aplikaciji ne pojave i trenje i vinje, to jest
opcije izbornika sa slikama i one bez slika.
Kod dodavanja ikona na opcije izbornika u igri je jo nekoliko dodatnih
ogranienja osim onog spomenutog u prethodnom odjeljku. Na opciji
izbornika s ikonom ne moe biti prikazana oznaka njezinog izbora
(kvaica), a ako je tekst opcije izbornika neto dui, onda e biti prikazan
samo poetni dio. To i nije nelogino ako odaberete ikonu koja vrlo
reprezentativno oznaava neku operaciju, zato bi je onda nairoko i
opisivali. Prednosti takvog pristupa kod stvaranja viejezinog suelja ne
trebamo posebno ni isticati.

U sluaju vrlo irokog raspona moguih operacija u


aplikaciji, neke (ili sve) opcije izbornika mogu imati
svoje podizbornike. Opcije podizbornika dodaju se
programski odgovarajuim metodama to emo
prikazati u slijedeem nastavku. Za sada istaknimo kako
i ova kategorija izbornika ne podrava prikaz ikona, iako
se formalno ne javljaju nikakve greka kod takvog pokuaja.
Izbornici ovisni o kontekstu predstavljaju posebnu vrstu izbornika iji
izgled se mijenja ovisno o smislu izvoenja pojedinog dijela aplikacije, a
aktiviraju se takozvanim dugim pritiskom na neki element korisnikog
suelja. Programer moe u vlastitu aplikaciju dodati i
standardne sistemske izbornike. Kako se to radi, takoer emo
demonstrirati slijedei put.

Android programiranje #9: Koritenje datotenog sustava

Nakon to smo u prolom nastavku pokazali kako se stvara osnovna


vrsta izbornika, danas emo objasniti kako program na najednostavniji
mogui nain putem izbornika odgovara na akcije korisnika. Ujedno emo
od ovomjesenog nastavka napraviti malo ubrzanje u izlaganju kako bi
u planiranom broju preostalih nastavaka mogli doista i napraviti nekakvu
malo sloeniju aplikaciju. Ideja je da izloenu materiju prikaemo na
meusobno povezani nain, kako nakon prolaska kroz itav serijal ne bi
imali niz nepovezanih segmenata znanja o pojedinim dijelovima Android
SDK sustava, ali bez mogunosti njihovog slaganja u smislenu cjelinu. S
druge strane, na temelju dosadanjih nastavaka vie ne bi trebali imati
previe problema s tim da pronaete gdje se umeu pojedini dijelovi
programskog koda. Zato na ovom mjestu neemo izloiti sve mogue
naine stvaranja izbornika i hvatanja operacija korisnika, jer ih ima
zbilja podosta, pa bi se izlaganje htjeli mi to ili ne, lako pretvorilo u
prepisivanje originalnih uputa. Umjesto toga emo u sloenijoj aplikaciji
koju smo maloprije najavili pokazati brojne dodatne mogunosti u
koritenju.
Osnovni oblik reakcije izbornika na djelovanje korisnika priprema se u
dva koraka prema slijedeem obrascu. U prvom koraku treba
Implementirati OnMenuClickListener suelje. U drugom koraku, koji se
izvodi nakon izbora neke od opcija od strane korisnika, poziva se
metoda onMenuItemClick(). To je ujedno mjesto gdje se izvodi stvarna
obrada dogaaja pritiska na neku od opcija izbornika.
//korak1
public class MyResponse implements OnMenuClickListener
{
//
@override
boolean onMenuItemClick(MenuItem item)
{
//izvoenje operacije
return true;
}
}
//korak 2
MyResponse myResponse = new MyResponse();
menuItem.setOnMenuItemClickListener(myResponse);

Osim osnovnog naina reakcije izbornika na dogaaje postoji jo


nekoliko varijanti koje emo demonstrirati na sloenijoj aplikaciji. U njoj
emo ujedno pokazati kako se izvornici mogu stvoriti preko odgovarajue
resursne XML datoteke, a ne samo programskim kodom.
Rad s datotekama
Svaka malo sloenija aplikacija, koja rukuje s korisnim podacima, mora
imati mogunost spremanja podataka iz aplikacije u neko spremite te
njihovo vraanje kad se za tim ukae potreba. U dananjem nastavku
pokazat emo kako se navedene dvije operacije izvode pomou
datotenog sustava ugraenog u Android SDK. Za to emo koristiti dva
specijalizirana tijeka podataka FileOutputStream iFileInputStream.
Prvi se koristi za prijenos podataka na relaciji program datoteka, a drugi
u obrnutom smjeru. Ujedno emo pokazati dvije dodatne nune operacije
kod takvog postupka. Prva je skupljanje trenutnih vrijednosti razliitih
Android kontrola upisanih od strane korisnika aplikacije kako bi se imalo
to upisati u datoteku, a druga je njihovo ponovno vraanje iz datoteke i
postavljanje na odgovarajuu kontrolu.
Pogledajmo prvo kako se izvodi spremanje podataka u datoteku na
segmentu programskog koda izvaenog iz jedne manje medicinski
orijentirane aplikacije. U ovom trenutku zapravo i nije previe bitno o
kakvim se podacima radi. Primijetimo samo da se podaci ne skupljaju
iskljuivo iz tekstualnih nego i iz drugih oblika kontrola, a prije samog
spremanja u datoteku se grupiraju u jedan sloeniji niz znakova. U njemu
su podaci meusobno odvojeni posebnim nizom znakova za odvajanje,
kako bi se olakalo njihovo obnavljanje kod suprotne operacije itanja iz
datoteke.

Spremanje podataka iz aplikacije: Prethodni primjeri koda


odnose se na jednostavnu medicinski orijentiranu
aplikaciju.

private void SpremiPodatkeCritical2() throws IOException


{
String FILENAME = PrvaPomocCritical2;
String string = ;
FileOutputStream fos;
try

{
final EditText tmp = (EditText) findViewById(R.id.txtSpol);
String tmps = tmp.getText().toString();
if (tmps.length() == 0) tmps = !!!;
final EditText tmp2 = (EditText) findViewById(R.id.txtTezina);
String tmps2 = tmp2.getText().toString();
if (tmps2.length() == 0) tmps2 = !!!;
final EditText tmp3 = (EditText) findViewById(R.id.txtKrvnaGrupa);
String tmps3 = tmp3.getText().toString();
if (tmps3.length() == 0) tmps3 = !!!;
final EditText tmp4 = (EditText) findViewById(R.id.txtRhFaktor);
String tmps4 = tmp4.getText().toString();
if (tmps4.length() == 0) tmps4 = !!!;
final CheckBox tmp5 = (CheckBox) findViewById(R.id.chkSida);
String tmps5 = N;
if (tmp5.isChecked()) tmps5 = D;
final CheckBox tmp6 = (CheckBox) findViewById(R.id.chkHepatitisC);
String tmps6 = N;
if (tmp6.isChecked()) tmps6 = D;
final CheckBox tmp7 = (CheckBox) findViewById(R.id.chkDonator);
String tmps7 = N;
if (tmp7.isChecked()) tmps7 = D;
final EditText tmp8 = (EditText) findViewById(R.id.txtAlergija);
String tmps8 = tmp8.getText().toString();
if (tmps8.length() == 0) tmps8 = !!!;
final EditText tmp9 = (EditText) findViewById(R.id.txtDijagnoza);
String tmps9 = tmp9.getText().toString();
if (tmps9.length() == 0) tmps9 = !!!;
final EditText tmp10 = (EditText) findViewById(R.id.txtTerapija);
String tmps10 = tmp10.getText().toString();

if (tmps10.length() == 0) tmps10 = !!!;


final EditText tmp11 = (EditText) findViewById(R.id.txtNapomena);
String tmps11 = tmp11.getText().toString();
if (tmps11.length() == 0) tmps11 = !!!;
string = tmps + ### + tmps2 + ### + tmps3 + ### + tmps4 +
### + tmps5 + ### + tmps6 + ### + tmps7 + ### + tmps8
+ ### + tmps9 + ### + tmps10 + ### + tmps11;
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}

Istaknimo vrlo vanu injenicu koju svakako treba uzeti u obzir kod rada
s datotenim sustavom, a to je mogunost pojave greke. Osnovni niz
naredbi za zapis podataka u datoteku:
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
moe ponekad dovesti do pojave greke, ako ni zbog ega drugog onda
zbog nedostatka prostora na mediju na kojem se nalazi datoteni sustav.
Kako se aplikacija u tom sluaju ne bi poela nekontrolirano ponaati,
treba ugraditi bar osnovni mehanizam obrade pogreke u vlastitom kodu,
to je ovdje i napravljeno koritenjem standardne try .. catch strukture.
Pogledajmo sada kako se koristi suprotni tijek podataka namijenjen
itanju spremljenih podataka.
private void VratiPodatkeCritical2() throws IOException
{

String FILENAME = PrvaPomocCritical2;


String string1 = ;
setContentView(R.layout.critical2);
FileInputStream fis;
try
{
fis = openFileInput(FILENAME);
BufferedReader buf = new BufferedReader(new InputStreamReader(fis));
string1 = buf.readLine();
String[] list = TextUtils.split(string1, ###);
final EditText tmp = (EditText) findViewById(R.id.txtSpol);
if (list[0].matches(!!!)) list[0] = ;
tmp.setText(list[0]);
final EditText tmp2 = (EditText) findViewById(R.id.txtTezina);
if (list[1].matches(!!!)) list[1] = ;
tmp2.setText(list[1]);
final EditText tmp3 = (EditText) findViewById(R.id.txtKrvnaGrupa);
if (list[2].matches(!!!)) list[2] = ;
tmp3.setText(list[2]);
final EditText tmp4 = (EditText) findViewById(R.id.txtRhFaktor);
if (list[3].matches(!!!)) list[3] = ;
tmp4.setText(list[3]);
final CheckBox tmp5 = (CheckBox) findViewById(R.id.chkSida);
tmp5.setChecked(false);
if (list[4].matches(D)) tmp5.setChecked(true);
final CheckBox tmp6 = (CheckBox) findViewById(R.id.chkHepatitisC);
tmp6.setChecked(false);
if (list[5].matches(D)) tmp6.setChecked(true);
final CheckBox tmp7 = (CheckBox) findViewById(R.id.chkDonator);
tmp7.setChecked(false);

if (list[6].matches(D)) tmp7.setChecked(true);
final EditText tmp8 = (EditText) findViewById(R.id.txtAlergija);
if (list[7].matches(!!!)) list[7] = ;
tmp8.setText(list[7]);
final EditText tmp9 = (EditText) findViewById(R.id.txtDijagnoza);
if (list[8].matches(!!!)) list[8] = ;
tmp9.setText(list[8]);
final EditText tmp10 = (EditText) findViewById(R.id.txtTerapija);
if (list[9].matches(!!!)) list[9] = ;
tmp10.setText(list[9]);
final EditText tmp11 = (EditText) findViewById(R.id.txtNapomena);
if (list[10].matches(!!!)) list[10] = ;
tmp11.setText(list[10]);
fis.close();
}
catch (FileNotFoundException e)
{
final EditText tmp = (EditText) findViewById(R.id.txtSpol);
tmp.setText($_);
final EditText tmp2 = (EditText) findViewById(R.id.txtTezina);
tmp2.setText(___);
final EditText tmp3 = (EditText) findViewById(R.id.txtKrvnaGrupa);
tmp3.setText(__);
final EditText tmp4 = (EditText) findViewById(R.id.txtRhFaktor);
tmp4.setText(_);
final CheckBox tmp5 = (CheckBox) findViewById(R.id.chkSida);
tmp5.setChecked(false);
final CheckBox tmp6 = (CheckBox) findViewById(R.id.chkHepatitisC);
tmp6.setChecked(false);
final CheckBox tmp7 = (CheckBox) findViewById(R.id.chkDonator);

tmp7.setChecked(true);
final EditText tmp8 = (EditText) findViewById(R.id.txtAlergija);
tmp8.setText($Alergija);
final EditText tmp9 = (EditText) findViewById(R.id.txtDijagnoza);
tmp9.setText($Dijagnoza);
final EditText tmp10 = (EditText) findViewById(R.id.txtTerapija);
tmp10.setText($Terapija);
final EditText tmp11 = (EditText) findViewById(R.id.txtNapomena);
tmp11.setText($Napomena);
e.printStackTrace();
}
}
Ponovno, potrebna je standardna procedura za obradu pogreaka
(throws IOException), jer se moe dogoditi da u datotenom sustavu iz
ovog ili onog razloga ne postoji, ili je oteena datoteka s podacima.
Budui da smo prilikom spremanja podatke formatirali tako da se itava
operacija njihovog spremanja izvodi u jednom koraku (to nije obavezno
te ovisi o karakteristikama vlastite aplikacije), sada emo itanje takoer
odraditi u jednom koraku, te ujedno razbiti podatke u odgovarajue
polje podataka pomou naredbe:
String[] list = TextUtils.split(string1, ###);
Preostalo je jo samo to da se na koritenom rasporedu kontrola unutar
aplikacije pronae odgovarajua kontrola te da joj se dodijeli tono
odreena vrijednost proitana iz datoteke. Za taj postupak koristi se
niz findViewById naredbi.

Android programiranje #10: Nekoliko standardnih dijelova aplikacije

Proli put smo iz neto sloenije medicinski orijentirane Android


aplikacije izvukli dio programskog koda zaduen za spremanje podataka
te za njihovo ponovno itanje kad se za tim ukae potreba. U dananjem
nastavku pokazat emo jo nekoliko karakteristinih dijelova programskog
koda, koje uz manje ili vee promjene moete upotrijebiti u vlastitim
projektima.
Prvo jedan sasvim logian, ali vaan savjet. Svaka sloenija Android
aplikacija, a naroito ako ona koristi razliite sistemske module (kao to je
to sluaj u ovom primjeru), zahtijeva ukljuivanje odgovarajuih
biblioteka. Ovisno o nainu oblikovanja korisnikog suelja i pisanju
programskog koda, taj je postupak u najveoj moguoj mjeri
automatiziran. Meutim, ako se tijekom razvoja u aplikaciji odjednom
pojavi itav niz pogreaka, postoji dosta velika vjerojatnost da nedostaje
(zbog izostanka ili sluajnog brisanja) odgovarajua import naredba. U
nastavku slijedi prikaz kako to prilino komplicirano izgleda u ovom
sluaju:
Primjer rasporeda kontrola: Jedan od
standardnih dijelova aplikacije za
prikupljanje podataka o korisniku.

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.sql.Date;
import java.text.DateFormat;
import java.util.Calendar;
import android.R.bool;
import android.R.integer;
import android.R.string;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.telephony.SmsManager;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CheckedTextView;

import android.widget.EditText;
U medicinski orijentiranoj aplikaciji ije dijelove koristimo za
demonstraciju programskog koda, zbog relativno velike koliine
prikupljenih podataka o korisniku aplikacije neprikladne za prikaz na samo
jednom zaslonu ograniene rezolucije (uobiajene kod mobilnih telefona
opremljenih Android sustavom), koristi se vie meusobno povezanih
rasporeda kontrola, a na svakom od rasporeda upotrijebljene su razliite
kontrole kako bi se to jednostavnije i preglednije unijeli relevantni
podaci. Kako to zaista izgleda na zaslonu Android ureaja moete
provjeriti na temelju priloenih slika uz tekst, a dijelovi odgovarajueg
XML koda navedeni su u nastavku.

<AbsoluteLayout android:id=@+id/AbsoluteLayout01
android:layout_width=fill_parent android:layout_height=fill_parent
xmlns:android=http://schemas.android.com/apk/res/android>
<Button android:layout_width=wrap_content
android:layout_height=wrap_content android:layout_x=0px
android:layout_y=0px android:id=@+id/btn2VratiSe
android:onClick=btn2VratiSeClick android:text=&lt;&lt;
Natrag></Button>
<Button android:layout_width=wrap_content
android:layout_height=wrap_content android:layout_y=0px
android:text=Poniti nezgodu android:minWidth=150px
android:layout_x=90px android:onClick=btn2PonistiNezgoduClick
android:id=@+id/btn2PonistiNezgodu></Button>

<TextView android:layout_height=wrap_content
android:layout_width=wrap_content
android:text=Prezime i ime: android:id=@+id/txtvPrezimeIme
android:layout_y=50px android:layout_x=2px></TextView>
<EditText android:saveEnabled=false
android:layout_height=wrap_content android:layout_width=fill_parent
android:layout_x=0px android:id=@+id/txtPrezimeIme
android:singleLine=true android:layout_y=65px></EditText>

<AbsoluteLayout android:id=@+id/AbsoluteLayout01
android:layout_width=fill_parent android:layout_height=fill_parent
xmlns:android=http://schemas.android.com/apk/res/android>

<EditText android:saveEnabled=false
android:layout_height=wrap_content
android:layout_width=wrap_content android:singleLine=true
android:layout_y=65px android:id=@+id/txtKrvnaGrupa
android:maxLength=2 android:text=__ android:layout_x=170px
android:maxWidth=50px android:minWidth=50px>

<CheckBox android:layout_height=wrap_content
android:layout_width=wrap_content android:id=@+id/chkSida
android:layout_x=0px android:text=Sida
android:layout_y=120px></CheckBox>
<CheckBox android:layout_height=wrap_content
android:layout_width=wrap_content android:layout_x=85px
android:layout_y=120px android:text=Hepatitis C
android:id=@+id/chkHepatitisC></CheckBox>
<CheckBox android:layout_height=wrap_content
android:layout_width=wrap_content android:id=@+id/chkDonator
android:text=Donator android:layout_x=210px
android:layout_y=120px></CheckBox>
U trenutku prelaska s jednog rasporeda kontrola na drugi postojei
sadraj kontrola iz starog rasporeda kontrola sprema se za kasnije
koritenje, a novi raspored kontrola se popunjava prethodno spremljenim
sadrajem (ako takav postoji zbog ranijeg koritenja aplikacije). Obje
operacije objanjene su u prethodnom nastavku serijala. Pokaimo sada
kako se programskim kodom prelazi s jednog rasporeda kontrola na drugi.
Na svakom osnovnom rasporedu postoje dva gumba za kretanje na
slijedeu odnosno prethodnu stranicu (razumljivo osim na prvom i
zadnjem). Slijedi primjer koritenja na drugom rasporedu kontrola na
njemu postoji gumb za prelazak na prvi, odnosno na trei raspored
kontrola.
public void btn3VratiSeClick(View view)
{
try {
SpremiPodatkeCritical2();
} catch (IOException e1) {
e1.printStackTrace();
}
setContentView(R.layout.critical);

try {
VratiPodatkeCritical();
} catch (IOException e) {
e.printStackTrace();
}
}
public void btn3DaljeClick(View view)
{
try {
SpremiPodatkeCritical2();
} catch (IOException e1) {
e1.printStackTrace();
}
setContentView(R.layout.critical3);
try {
VratiPodatkeCritical3();
} catch (IOException e) {
e.printStackTrace();
}
}
Kako eventualne pogreke prilikom kretanja kroz osnovne rasporede
kontrola ne bi izazvale ruenje programa, prijenos prikaza s jednog
rasproeda kontrola na drugi zamotan je u odgovarajuu strukturu za
obradu pogreke.
Osim prikaza podataka na standardnim rasporedima kontrola, vrlo esto
je u programu potrebno prikazati i odgovarajue dijaloke okvire o
statusnim informacijama, grekama u radu i slino. U nastavku je
naveden primjer programskog koda za prikaz dijalokog okvira s
podacima o autorima programa (ako za to ne namjeravate koristiti
poseban raspored kontrola zbog vee vizualne dojmljivosti takvog dijela
aplikacije).

Primjer rasporeda kontrola: Drugi standardni dio aplikacije.

public void btnPrvaPomocClick(View view)


{
AlertDialog ad = new AlertDialog.Builder(prvaPomoc.this).create();
CharSequence poruka = Autor programa \n ;
poruka = poruka + Crnko Nenad\n\n;
poruka = poruka + Struni medicinski suradnik\n;
poruka = poruka + Fusi Snjeana\n\n;
poruka = poruka + Verzija programa\n;
poruka = poruka + 25.06.2010 23:00:00;
ad.setTitle(O programu);
ad.setMessage(poruka);
ad.setButton(Zatvori, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{
}
});
ad.show();
}
U sluaju da vam to negdje zatreba, evo i ope funkcije za otvaranje
osnovnog oblika dijalokog okvira koju uz vee ili manje preinake moete

upotrijebiti u vlastitim aplikacija. Ulazni parametri funkcije su poruka koja


se prikazuje u okviru dijalokog okvira te njegovo zaglavlje.
private void MsgBox(String Poruka, String VrstaPoruke)
{
AlertDialog ad = new AlertDialog.Builder(prvaPomoc.this).create();
ad.setTitle(VrstaPoruke);
ad.setMessage(Poruka);
ad.setButton(Zatvori, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{
}
});
ad.show();
}
Navedimo na kraju dananjeg nastavka najsloeniji komad programskog
koda zaduen za pripremu i slanje SMS poruke s podacima iz programa u
sluaju nezgode. Zbog ogranienja prostora u asopisu ovim dijelom
emo se neto detaljnije pozabaviti u slijedeem nastavku serijala.
public void btnPosaljiSMSClick(View view)
{
final Button btnPosaljiSMS = (Button) findViewById(R.id.btnPosaljiSMS);
Calendar Kalendar = Calendar.getInstance ();
CharSequence mTrenutnoVrijeme = Kalendar.getTime().toString();
mGodina = Kalendar.get(Calendar.YEAR);
mMjesec = Kalendar.get(Calendar.MONTH);
mDan = Kalendar.get(Calendar.DAY_OF_MONTH);
mSati = Kalendar.get(Calendar.HOUR_OF_DAY);
mMinute = Kalendar.get(Calendar.MINUTE);
mSekunde = Kalendar.get(Calendar.SECOND );

mTrenutnoVrijeme = Integer.toString(mDan) + . +
Integer.toString(mMjesec) + . +
Integer.toString(mGodina) + +
Integer.toString(mSati) + : +
Integer.toString(mMinute) + : +
Integer.toString(mSekunde);
setContentView(R.layout.critical3);
try {
VratiPodatkeCritical3();
} catch (IOException e1) {
e1.printStackTrace();
}
final CheckBox tp = (CheckBox) findViewById(R.id.chkGPSPozicija);
String pozicija = ;
if (tp.isChecked())
{
try
{
LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
String provider = LocationManager.GPS_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
double lat = location.getLatitude();
double lng = location.getLongitude();
pozicija = + Double.toString(lat) + / + Double.toString(lat);
}
catch (Exception e)
{
e.printStackTrace();

}
}
try
{
final EditText tmp = (EditText) findViewById(R.id.txtSMSPoruka);
String tmps = tmp.getText().toString();
if (tmps.length() == 0)
{
setContentView(R.layout.main);
MsgBox(Nije definiran tekst SMS poruke!, Upozorenje);
return;
}
final EditText tmpbr = (EditText) findViewById(R.id.txtSMSBroj);
String tmpsbr = tmpbr.getText().toString();
if (tmpsbr.length() == 0)
{
setContentView(R.layout.main);
MsgBox(Nije definiran broj za slanje SMS poruke!, Upozorenje);
return;
}
setContentView(R.layout.main);
VratiPodatkeMain();
tmps = tmps + pozicija;
SmsManager sm = SmsManager.getDefault();
sm.sendTextMessage(tmpsbr, null, tmps + pozicija, null, null);
}
catch (Exception e)
{
MsgBox(e.getMessage(),Greka);
e.printStackTrace();

}
AlertDialog ad = new AlertDialog.Builder(prvaPomoc.this).create();
CharSequence poruka = Zabiljeeno vrijeme slanja SMS poruke za
pomo\n\n ;
poruka = poruka + mTrenutnoVrijeme.toString();
ad.setTitle(Potvrda operacije);
ad.setMessage(poruka);
ad.setButton(Zatvori, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{
}
});
ad.show();
btnPosaljiSMS.setText(SMS poruka: + mTrenutnoVrijeme);
try {
SpremiPodatkeMain();
} catch (IOException e) {
e.printStackTrace();
}
}

Android programiranje #11: Standardni dijelovi aplikacije

Na kraju teksta u prethodnom broju asopisa naveden je malo vei


segment programskog koda za izvoenje nekoliko bitnih stvari u
programu, ali jednostavno nije bilo dovoljno mjesta za njegovo detaljnije
objanjenje. Zato u dananjem nastavku slijedi malo detaljnija rasprava o
koritenim objektima i metodama u tom dijelu aplikacije.
Razjasnimo prvo namjenu izdvojenog dijela programskog koda s kraja
prethodnog nastavka, kako bi lake mogli pratiti detalje u nastavku. Ideja
je da korisnik aplikacije u trenutku kad doivi nekakvu nezgodu (koja bitno
utjee na njegovo zdravstveno stanje) moe to jednostavnije i bre
poslati SMS poruku na unaprijed definirani broj, kako bi izabranu osobu ili
ustanovu obavijestio o svojoj nezgodi. Pretpostavka za izvoenje takvog
postupka je da nakon nezgode ostane u svjesnom stanju, kako bi zaista
mogao pokrenuti aplikaciju te pritisnuti gumb za slanje SMS poruke. Ako
moe napraviti tu operaciju, onda moe pritisnuti i drugi gumb kako bi
zabiljeio vrijeme nezgode, jer se tako kod pruanja prve pomoi lako
moe ustanoviti koliko je vremena doista prolo od nezgode. To moe biti
vrlo bitan faktor za poduzimanje razliitih operacija nad unesreenim. ak
i ako korisnik aplikacije u trenutku kad stigne prva pomo bude u

nesvijesti, moe se proitati podatak o trenutku nezgode, kao i drugim


bitnim karakteristikama unesreenog (krvna grupa, kronine bolesti i
slino). Te informacije su dostupne i u situaciji kad SMS poruka nije
poslana, a nije zabiljeen ni trenutak nezgode bitno je samo da spasitelji
malo proeprkaju po Android mobitelu, jer je on najverojatnije negdje
pri ruci. Ostaje jo samo odgovor na pitanje zato su operacije slanja SMS
poruke i biljeenja trenutka nezgode razdvojene. Postoje situacije kad
SMS poruku, a pogotovo neke njezine dijelove (vidi nastavak teksta) nije
mogue ni pripremiti ni poslati, pa se u tom sluaju moe zabiljeiti samo
trenutak nezgode.
LocationManager: Vrlo sloen objekt na
Android platformi zaduen za dobijanje
tone geografske lokacije.

Prvi dio programskog koda je najjednostavniji za objanjavanje jer slui


za obino odreivanje tonog vremena nakon pritiska korisnika na
odgovarajui gumb aplikacije. To vrijeme se trajno pamti kako bi ga
spasitelji mogli naknadno oitati. Ovaj segment programskog koda
zamotan je u standardnu rutinu za obradu pogreke, u sluaju da se
dogodi nekakav problem tijekom izvoenja aplikacije.
public void btnPosaljiSMSClick(View view)
{
final Button btnPosaljiSMS = (Button) findViewById(R.id.btnPosaljiSMS);
Calendar Kalendar = Calendar.getInstance ();
CharSequence mTrenutnoVrijeme = Kalendar.getTime().toString();
mGodina = Kalendar.get(Calendar.YEAR);
mMjesec = Kalendar.get(Calendar.MONTH);
mDan = Kalendar.get(Calendar.DAY_OF_MONTH);
mSati = Kalendar.get(Calendar.HOUR_OF_DAY);
mMinute = Kalendar.get(Calendar.MINUTE);
mSekunde = Kalendar.get(Calendar.SECOND );
mTrenutnoVrijeme = Integer.toString(mDan) + . +

Integer.toString(mMjesec) + . +
Integer.toString(mGodina) + +
Integer.toString(mSati) + : +
Integer.toString(mMinute) + : +
Integer.toString(mSekunde);
setContentView(R.layout.critical3);
try {
VratiPodatkeCritical3();
} catch (IOException e1) {
e1.printStackTrace();
}
final CheckBox tp = (CheckBox) findViewById(R.id.chkGPSPozicija);
Da bi SMS poruka koja se alje na unaprijed definirani telefonski broj bila
to korisnija, ideja je da njezin dio bude tona geografska lokacija s koje je
poruka poslana, kako bi se to bre i jednostavnije dolo do unesreenog
korisnika aplikacije. Ako mobilni telefon (ili neki drugi ureaj koji se temelji
na Android platformi) u sebi sadri odgovarajui hardverski dio za
dobijanje takvog podatka, onda slijedei dio programskog koda koristi
Android objekt LocationManager za dobijanje potrebnog geolokacijskog
podatka.
String pozicija = ;
if (tp.isChecked())
{
try
{
LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
String provider = LocationManager.GPS_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
double lat = location.getLatitude();
double lng = location.getLongitude();
pozicija = + Double.toString(lat) + / + Double.toString(lat);

}
catch (Exception e)
{
e.printStackTrace();
}
}
Prethodne naredbe sadre jo nekoliko naredbi za formatiranje podataka
o geografskoj lokaciji, kako bi podaci u okviru poruke bili prikazani na to
itljiviji podaci razumljiv spasiteljima. Kao i obino, bitno je da takv dio
aplikacije podloan pogrekama bude obuhvaen u strukturu za obradu
pogreaka. Zahtijevani podatak moe u nekom trenutku jednostavno biti
nedostupan. Na primjer, izvor GPS podataka je uniten solarnom bakljom.
Dobro malo se alimo, mnogo je vjerojatniji neki drugi uzrok problema,
iako prema najavama nekih strunjaka 2012 godine to moda uope vie
nee biti samo ala.
LocationManager je vrlo sloen objekt na Android platformi pa njegovo
detaljno opisivanje prelazi okvire ovog teksta. Osnovni primjer prikazan u
prethodnom dijelu programskog koda, trebao bi vam posluiti kao vodi
za dodatno istraivanje prateih uputa o Android SDK sustavu.
Nakon to su pripremljeni svi potrebni podaci o geografskoj lokaciji,
preostaje jo samo njihovo spajanje s unaprijed definiranim fiksnim
dijelom SMS poruke, te slanje poruke na prije upisani mobilni broj. U
sluaju da navedena dva podatka nisu pripremljena, onda se korisniku
aplikacije javlja odgovarajua poruka kako bi se rijeio problem. Za to se
koristi funkcija o ijoj smo namjeni i djelovanju raspravljali u jednom od
prethodnih nastavaka serijala.
Sasvim je jasno da kritina situacija, u kojoj se moe nai korisnik
aplikacije, nije ba idealan trenutak da aplikacija javi kako smo u fazi
njezinog punjenja poetnim podacima zaboravili navesti neki detalj (fiksni
dio SMS poruke ili odredini broj). Otprilike se radi o istoj situaciji kao kad
bi va najnoviji automobil (dostupan uz mjesenu ratu od svega 500 kn,
ali uz uee od 30 posto i ostatak vrijednosti od 30 posto kako to danas
nude sitnim slovima neki oglasi na koje se skoro navukao i autor ovih
redova), u trenutku hitnog koenja javio nekakvu poruku da to ne moe ili
ne eli napraviti. Rjeenje problema je vrlo jednostavno. Nakon upisivanja
svih potrebnih podataka u aplikaciju na samom poetku njezina
koritenja, treba poslati probnu poruku te provjeriti je li zaista sve u redu.
try
{
final EditText tmp = (EditText) findViewById(R.id.txtSMSPoruka);

String tmps = tmp.getText().toString();


if (tmps.length() == 0)
{
setContentView(R.layout.main);
MsgBox(Nije definiran tekst SMS poruke!, Upozorenje);
return;
}
final EditText tmpbr = (EditText) findViewById(R.id.txtSMSBroj);
String tmpsbr = tmpbr.getText().toString();
if (tmpsbr.length() == 0)
{
setContentView(R.layout.main);
MsgBox(Nije definiran broj za slanje SMS poruke!, Upozorenje);
return;
}
setContentView(R.layout.main);
VratiPodatkeMain();
tmps = tmps + pozicija;
SmsManager sm = SmsManager.getDefault();
sm.sendTextMessage(tmpsbr, null, tmps + pozicija, null, null);
}
catch (Exception e)
{
MsgBox(e.getMessage(),Greka);
e.printStackTrace();
}
AlertDialog ad = new AlertDialog.Builder(prvaPomoc.this).create();
CharSequence poruka = Zabiljeeno vrijeme slanja SMS poruke za
pomo\n\n ;
poruka = poruka + mTrenutnoVrijeme.toString();

ad.setTitle(Potvrda operacije);
ad.setMessage(poruka);
ad.setButton(Zatvori, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{
}
});
ad.show();
Na kraju cijelog postupka prikazuje se tono vrijeme slanja poruke. Ne
treba posebno ni napominjati da se svi podaci iz prethodne operacije
spremaju u odgovarajua spremita u mobilnom telefonu, kako bi i
kasnije bili dostupni prema potrebi.
btnPosaljiSMS.setText(SMS poruka: + mTrenutnoVrijeme);
try {
SpremiPodatkeMain();
} catch (IOException e) {
e.printStackTrace();
}
}
Na temelju svega dosad napisanog u ovom te u prethodnih nekoliko
brojeva, ve bi trebali biti u mogunosti sami izraivati relativno sloene
Android aplikacije. Meutim, jo uvijek nismo zavrili serijal, jer nam je
preostala demonstracija koritenja nekoliko bitnih tehnika kao to je dobro
poznati Google Maps, preuzimanje podataka s ugraenih senzora,
koritenje dodatnih grafikih i zvunih mogunosti te jo poneka
zanimljivih sitnica. Ostalo je jo dosta zanimljivog materijala za slijedeih
nekoliko nastavaka, posebno ako sve te dijelove uz dodatak ve
obraenih elimo kreativno povezati u prave aplikacije.

LocationManager: Vrlo sloen objekt na


Android platformi zaduen za dobijanje
tone geografske lokacije.

Android programiranje #12: Alternativni pristup razvoju aplikacija

U prethodnih desetak (i jo malo vie) nastavaka serijala o Android


programiranju pokazali smo dosta toga to vam moe pomoi kod razvoja
vlastitih aplikacija poevi od instalacije svih potrebnih alata na vlastito
raunalo pa sve do razvoja standardnih dijelova sloenijih aplikacija. U
meuvremenu se ureaji bazirani na Androidu (telefoni, ali i tabletii te
drugi mobilni ureaji) sve bolje prodaju irom svijeta, tako da razvoj
aplikacija za ovu platformu sigurno nee biti uzaludan napor.
Iako emo se u slijedeih nekoliko nastavaka serijala pozabaviti s jo
nekoliko naprednijih programerskih tehnika, ovaj put emo se malo
detaljnije osvrnuti na alernativni (itaj bitno jednostavniji) nain za razvoj
aplikacija, takoer nastao u radionicama istog proizvoaa. Na kraju
krajeva meu itateljima asopisa sigurno ima onih s vrlo dobrim idejama
za razvoj novih aplikacija, ali im se koritenje Google SDK alata ipak ini
malo prekompliciranim. Sreom, Googleovi inenjeri intenzivno rade na
neto drugaijem pristupu itavoj stvari, pa emo vas u dananjem
nastavku upoznati s njihovim najnovim uradkom za tu namjenu.
App Inventor for Android je naziv za alat namijenjen malo manje
spretnim programerima dizajniranim tako da omoguava vizualno
orijentirani razvoj razliitih Android aplikacija izravno u pregledniku. Zbog
toga je pisanje programskog koda gotovo u potpunosti izbaeno iz alata
te zamijenjeno neim genijalno preglednim. Ako ste ipak zainteresirani za
programiranje, onda vam ovaj alat zapravo i ne treba, jer ve imate dobro
poznati Android SDK.
Iako u trenutku pisanja teksta (prema tvrdnjama iz samog Googlea) alat
jo uvijek ne podrava sve to je zamiljeno (jo uvijek se nalazi u beta
fazi razvoja) ve sada se pomou njega mogu napraviti zanimljive i
korisne aplikacije. Googleovi inenjeri naglaavaju kako se trenutni
problemi prije svega odnose na podruja instalacije upravljakih ureaja,
prijenosa dijelova razvojnog alata Java na raunalo te distribuciju same
aplikacije na odredini mobilni ureaj, odnosno postavljanje razliitih
postavki koritenja aplikacije na tom ureaju. Zato se u trenutnoj fazi
razvoja alata od zainteresiranih korisnika trai da pripreme to detaljnije

povratne informacije o koritenju alata, kako bi se to prije prevladali svi


uoeni problemi.

Priprema raunala za razvoj: Mogu se koristiti razliite


kombinacije operativnih sustava i preglednika.

Razvoj vlastitih aplikacija u alatu App Inventor for Android zapoinje


pripremom vlastitog raunala za takav zadatak. Za razliku od Microsofta
ili Applea poznatih po ograniavaju razvoja na vlastiti hardver i/ili softver,
Googleov razvojni tim kontinuirano podrava sve najpopularnije platforme
(Windows, Mac i Linux). Zato nije ni udo da se Android polako, ali
sigurno, probija prema samom vrhu popularnosti na podruju mobilnih
platformi. Nastavak teksta, te prije svega pratee slike) podrazumijevaju
razvoj vlastitih aplikacija u Google Chrome pregledniku na Windows
raunalu, ali iz prije navedenih razloga ne bi trebali imati previe
problema ni u razvoju aplikacija na nekoj drugoj konfiguraciji.
Prvi korak u pripremi raunala je preuzimanje odgovarajueg programa
za upravljanje pripremom razvojne konfiguracije. Ovaj program moe se
slobodno preuzeti usmjeravanjem preglednika na web
adresuhttp://appinventor.googlelabs.com/learn/setup/setupwindows.html
Nakon preuzimanja instalacijskog programa treba ga instalirati na
raunalo te podesiti parametre ciljnog mobilnog ureaja. U trenutnoj fazi
razvoja alata podrano je izravno svega nekoliko ureaja poput T-Mobile
G1 ili T-Mobile myTouch, dok se za ostalo ovrsje treba pomuiti malo
vie te napraviti manja ili vea podeavanja na samom telefonu. Budui
da je ovaj postupak ovisan o samom telefonu, kao takav prelazi okvire
napisanog teksta. Sve potrebne informacije moete pronai slijedei
odgovarajue linkove na prije navedenoj web adresi.

Poetak rada na aplikaciji: Zapoinje stvaranjem


projekta u ovom sluaju HelloPurr.

Izrada prve aplikacije


U nastavku teksta opisat emo izradu prve aplikacije prema Googlevoj
prateoj dokumentaciji. Za razliku od uobiajenog Hello World primjera
koji samo prikazuje dvije rijei na zaslonu, Googleov poetni primjer
odmah koristi i audio/video podatke, to jest prikazuje sliku te reproducira
zvuk. Zato kao poetni korak u izradi aplikacije treba skinuti jednu sliku
u .pngformatu, odnosno jednu zvunu datoteku u .mp3 formatu. Umjesto
onih koje nudi Google za testiranje razvojnog alata, moete upotrijebiti
svoje vlastite, ali za sada emo se drati priloene kuharice.
Razvojni alat pokreete postavljanjem preglednika na
adresuhttp://appinventor.googlelabs.com. Da bi se moglo prijei na razvoj
same aplikacije potrebno je da korisnik ima odgovarajui google email
korisniki raun. Ako ga jo nemate, ovo je prilika da ga stvorite. Kad
obavite tu formalnost, pojavljuje se stranica namijenjena pripremi novih
aplikacija, odnosno administriranju postojeih. Budui da pripremate svoj
prvi projekt, izaberite opciju New na vrhu stranice te upiite naziv
aplikacije HelloPur.

Razvojna okolina: Vrlo je jednostavna i namijenjena


korisnicima koji nisu profesionalni programeri.

Kao rezultat izvoenja prethodne operacije pojavljuje se glavna stranica


razvojnog alata namijenjena izradi aplikacije (vidi pratee slike uz tekst).
Sve izgleda vrlo jednostavno, ali je sasvim dovoljno za korisnike kojima je
namijenjena neprofesionalnim programerima s dobrim idejama za
vlastite aplikacije.
U lijevom dijelu stranice nalaze se razliite grupe kontrola namijenjene
iskoritavanju brojnih mogunosti Android sustava. Tijekom razvoja prve
aplikacije bit e nam potrebne svega dvije kontrole: Button i Label.
Jednostavnom operacijom povlaenja postavite in na sredinji dio stranice
namijenjen simuliranju zaslona mobilnog ureaja. Kontrole postavite
jednu ispod druge, a onda je preostalo da im izmijenite nekoliko svojstva,
kako bi dobili izgled suelja prikazan na jednoj od prateih slika uz tekst.
KontroliButton potrebno je obrisati poetni tekst prikazan na kontroli
(svojstvoText) te uitati prije spomenutu sliku kitty.png
(svojstvo Image). KontroliLabel potrebno je postaviti boju pozadine na
plavu (svojstvo BackgroundColor), poveati veliinu pisma na 30

(svojstvo FontSize), te upisati novi tekst Pet the Kitty. Svojstvo koje se
koristi za zadnju operaciju ve znate s prve kontrole. Sve to se izvodi u
prozoru Properties na desnoj strani osnovne stranice.

Postavljanje prve kontrole: Izvodi se obinim


povlaenjem kontrole na centralni dio koji predstavlja
zaslon mobilnog ureaja.

Na ovom stupnju razvoja aplikacije u nju je dodana slika, ali jo uvijek ne


i zvuni zapis. Zato je potrebno u aplikaciju povui jo jednu kontrolu
(Sound iz grupe Media), a onda pomou gumba na dnu stranice dodati
prije spomenutu mp3 datoteku (meow.mp3). Ovim potezom suelje je u
potpunosti dovreno s dizajnerske strane, ali je za kompletiranje aplikacije
potrebno napraviti jo neto. Da bi se tijekom izvoenja aplikacije
pritiskom na sliku umiljate makice izazvalo njezino glasanje, to jest
reprodukcija mpr datoteke, potrebno je ipak napisati mali program.
Prethodnu tvrdnju smo stavili u znake navoda, jer je za razliku od drugih
vizualno orijentiranih suelja, koja u konanici ipak zahtijevaju prilino
znanje programiranja, Google ovdje stvarno napravio korak naprijed.
Na vrhu osnovne stranice potrebno je kliknuti na opciju Open the Block
Eidtor, a ako ste to napravili prvi put, priekati odreeno vrijema kako bi
se na vae raunalo instalirala dodatna komponenta za pisanje
programskog koda. Evo ponovno navodnika, a konano i objanjenja
zato. Kad se otvori popis svih dostupnih dogaaja, oni su prikazati u
obliku svojevrsne slagalice. Potrebni dogaaj u kontekstu nekog dijela
aplikacije potrebno je jednostavno spariti s pravom operacijom, to se
izvodi obinom operacijom povlaenja. U konkretnom sluaju potrebno je
dogaaj Button1.Click povezati s operacijom Sound1.Play i to je to.
Koliko to efektno izgleda moete provjeriti na priloenoj slici ili isprobati
sami. Bravo Google!

Prozor Properties: Koristi se za izmjenu razliitih


svojstava oznaene kontrole.

Preostalo je jo samo da isprobate aplikaciju na stvarnom hardverskom


ureaju tijekom instalacije povezanim s razvojnim alatom, ili na
odgovarajuem softverskom emulatoru. Na kraju je pomou
operacijePackage for Phone mogue napraviti i distribucijski oblik
aplikacije.
Priznajte da nije bilo komplicirano, iako nismo ba detaljno opisivali nain
promjene svojstava. Ipak bi ovaj tekst trebali pratiti itatelji s bar
poetnim poznavanjem programiranja, tako da ne bi trebao biti problem
izvesti tako elementarne operacije u dizajnu aplikacije.
Pomou alata App Inventor for Android (iako je jo uvijek u fazi beta
verzije) mogu se napraviti znatno sloenije aplikacije u to se moete
uvjeriti i sami nakon malo vjebe.

Android programiranje #13: Alternativni pristup razvoju aplikacija II

Proli put smo demonstrirali osnove koritenja Googleovog alternativnog


alata za razvoj Android aplikacija namijenjenog neprogramerima i malo
manje spretnim programerima. App Inventor for Android, kako je
njegov naziv, pokazao se sasvim prikladnim za stvaranje elementarne
Android aplikacije (neto slino klasinom Hello World primjeru), a danas
emo probati prikazati da je upotrebljiv za bitno sloenije projekte.
Odgovorimo prvo na nekoliko najvanijih pitanja povezanih s koritenjem
alata na razvoju sloenijih projekata. Najvanije pitanje koje se namee
samo po sebi je potencijalna sloenost dovrene aplikacije. Tu odmah
treba biti izravan te rei da se pomou alata App Inventor for Android ne
moe napraviti ba sve to i s slubenim razvojnim alatom, ali da se moe
puno toga moe se. Osim brojnih komponenti za razvoj razliitih dijelova
suelja (to smo djelomice pokazali u u prolom uvodnom tekstu o alatu),
na raspolaganju su najvanije programske strukture
poput foreach, while, if-else (iako u neto slikovitijem obliku nego je to
uobiajeno u programskim jezicima), a mogua je i komunikacija s web
servisima te svojevrsnim spremitem podataka. Od vanijih tehnologija
karakteristinih za mobilne ureaje dananjice, trenutno nije podran
samo Bluetooth, ali se prema tvrdnjama proizvoaa intenzivno radi i na
tom segmentu.

Basic komponente: Predstavljaju osnovne grafike


elemente aplikacije.

Ako vam sluajno ni sve nabrojano nije dovoljno za


izradu vlastite aplikacije, onda alat skoro neogranieno moete
nadopunjavati izradom vlastitih komponenti u Javi. To znai da morate
ipak biti neto vjetiji u programiranju, a onda se neminovno postavlja
pitanje zato ne bi sve skupa ipak programirali u standardnom SDK
razvojnom sustavu. Ako pomou alata App Inventor for Android moete
sami odraditi vei dio projekta, onda ima smisla da za manji nedostajui
segment vlastite aplikacije angairate Java programera da vam pomogne.
Trenutno dva najvea nedostatka alata odnose se na nemogunost
izravne objave aplikacije na globalnom tritu Android aplikacija (Android
Market), te ogranienost aplikacije na samo jedan prikaz (raspored
kontrola). Google obeava kako e prvi problem biti uskoro rijeen pa se
zato njime neemo previe baviti. Napiimo zato nekoliko rijei o drugom
problemu. Na trenutnom stupnja razvoja alata ne moe se izvoditi
prebacivanje izmeu vie razliitih vrsta prikaza ili rasporeda kontrola. To
na prvi, drugi i trei pogled predstavlja zbilja veliko ogranienje u razvoju
aplikacija, ali ga je ipak mogue prevazii jednim od slijedea dva trika.
1. Naizmjeninim paljenjem i gaenjem kontrola, to jest izmjenom
vidljivosti razliitih komponenti postavljenih na jedini dostupni prikaz
kontrola.
2. Meusobnim viestrukim povezivanjem vie App Inventor for Android
aplikacija, od kojih svaka moe imati razliite rasporede kontrola na
osnovnom zaslonu. Kad su prije koje desetljee neto slino mogli
raditi autori sloenih igara na strojevima poput ZX Spectruma ili
Commodorea 64 te kasetofonom kao ureajem vanjske memorije,
nema nikakvog razloga zato se to ne bi moglo napraviti i danas sa
znatno modernijim hardverom.
Media komponente: Komponente za upravljanje
razliitim multimedijalnim dijelovima mobilnog ureaja.

Iako slijedea vijest nema nikakve veze s prethodnom


tokom, dananjim tekstom, pa ak ni cijelim serijalom u cjelini, ipak u je
spomenuti na ovom mjestu, ako je do sada ve niste sami negdje

proitali. Kultni Commodore 64 je prije kratkog vremena doivio svoju


inkarnaciju s istim izgledom izvana, ali ultramodernim hardverom i
softverom iznutra. Narudbe se mogu napraviti ve sada, a isporuka se
oekuje u petom mjesecu. Morao sam to jednostavno spomenuti prve
ljubavi se teko zaboravljaju, makar to bila i raunala.
Vratimo se sada ponovo dananjoj temi. Kljune dijelove aplikacije
moemo podijeliti u dvije velike skupine:
1. Komponente ili kontrole
2. Blokove
Komponente su osnovni grafiki dijelovi aplikacije, a meusobno se osim
po izgledu razlikuju prije svega po svojoj namjeni. Osnovna grupa
komponenti pod nazivom Basic obuhvaa zbilja osnovne komponente
karakteristine za moderna korisnika suelja poput gumbi, oznaka i slika.
Ako ste ikad probali napisati bilo kakvu aplikaciju u nekom modernijem
razvojnom alatu, trebali bi znati o emu je rije, pa se zato i neemo
previe baviti njihovim karakteristika. U istoj grupi kontrola nalaze se jo
dvije sloenije kontrole, a one ipak zahtijevaju poneku dodatnu rije. To
su Canvas i TinyDB.
Animation komponente: Preduvjet za njihovo koritenje
je postojanje komponente Canvas.

Kontrola Canvas zamiljena je kao dvodimenzionalno


podruje za crtanje likova pomou programskog koda, odnosno za
pomicanje sliica (sprites). Budui da je to isto podruje osjetljivo na
dodir, sasvim je razumljivo da predstavlja temeljni dio veine razliitih
igara razvijenih u ovom alatu. Svaka od lokacija na komponenti Canvas
oznaava se uobiajenim matematikim zapisom za dvodimenzionalne
povrine kao koordinate x i y. O vanosti navedene kontrole u razvoju
aplikacija najbolje govori injenica da je u zadnjoj reviziji alata od strane
Googlea s kraja treeg mjeseca, veliki dio poboljanja dodan upravo u
Canvas kontrolu.
Neka od tipinih svojstava i metoda Canvas kontrole, ija imena govore
sama za sebe su:
BackgroundImage, LineWidth, Touched(number x, number y,
boolean touchedSprite), Clear(), DrawLine(number x1, number
y1, number x2, number y2), DrawCircle(number x, number y,
number r).
Tijekom pisanja igara kontrola Canvas se vrlo esto upotrebljava u
kombinaciji s kontrolom Clock kako bi se osiguralo odvijanje operacija u
zadanim vremenskim intervalima. Spomenimo na ovom mjestu kako
kontrola Clock ujedno pripada grupi nevidljivih kontrola, to znai da se

ne vidi tijekom izvoenja aplikacije, ali mora biti nacrtana na osnovnoj


formi kako bi se mogle koristiti njezine mogunosti.
Kontrola TinyDB namijenjena je trajnom spremanju podataka iz aplikacije
u mobilni ureaj. Prilikom svakog prekida izvravanja aplikacije gubi se
sadraj svih koritenih kontrola te se ponovo puni inicijalnim
vrijednostima kod slijedeeg pokretanja aplikacije. Ako prilikom novog
pokretanja aplikacije treba krenuti od njezinog zadnjeg stanja, onda treba
postojati nekakav mehanizam za spremanje vrijednosti iz aplikacije u
Android ureaj, te njihovo ponovno itanje (na primjer, postavke
aplikacije, stanje bodova u privremeno prekinutoj igri i slino). Upravo za
takvu namjenu zamiljena je kontrola TinyDB, odnosno njezine dvije
jedine dostupne metode:
StoreValue(oznaka, vrijednost)
Sprema vrijednost (niz znakova ili popis) pod odreenim nazivom u
spremite na mobilnom ureaju.

GetValue(oznaka)
ita vrijednost sa zadanim nazivom iz spremita. U sluaju da traena
oznaka ne postoji u spremitu (npr. kod prvog pokuaja itanja vrijednosti
na novom ureaju), onda metoda vraa prazan niz znakova.
U sluaju da treba obrisati spremite od starih vrijednosti, onda se to
izvodi na telefonu standardnom naredbom Settings Applications
Manage Applications.
U grupi kontrola pod nazivom Media nalazi se 5 komponenti slijedeih
naziva: Camera, ImagePicker, Player, Sound i VideoPlayer. Svaka od
kontrola zaduena je za upravljanje odgovarajuim hardverskim ili
softverskim resursom, pa su u skladu s tim i dodijeljeni nazivi svojstava
odnosno metoda (npr.TakePicture ili AfterPicture za kontrolu Camera,
odnosno Start, Stop ili Pause za kontrolu Player).
Grupa kontrola Animation te njezine dvije jedine
komponente Ball odnosno ImageSprite, koriste se u kombinaciji s prije
spomenutom kontrolom Canvas za aplikacije u kojima je potrebno izvoditi
razliite vrste pokretanja grafikih objekata (dakle najee igre). Na
priloenoj slici uz tekst vidi se da je preduvjet za koritenje kontroli iz ove
grupe upravo postojanje kontrole Canvas. Pomou svojstava kontrola
poputInterval, Speed ili Rotates upravlja se uestalou, brzinom i
rotacijom sliica ili loptica u vlastitoj aplikaciji. Budui da u jednoj
aplikaciji moe biti vie Canvas kontrola, nema nikakvog razloga da
njihovim inteligentnim paljenjem i gaenjem na jednom jedinom zaslonu
(prije istaknuto ogranienje trenutne verzije razvojnog alata) napravite
prilino kompleksnu igru.

Social komponente: Zaduene su za pristup i koritenje


razliitih socijalnih podataka iz mobilnog ureaja.

Posljednja grupa kontrola koju emo spomenuti u


dananjem nastavku su kontrole iz grupe Social zaduene za pristup i
koritenje razliitih socijalnih podataka iz mobilnog ureaja
(ContactPicker, EmailPicker, PhoneCall, PhoneNumberPicker,
Texting i Twitter). Pomou ovih kontrola mogue je postii da vlastite
aplikacije upravljaju telefonskim pozivima, slanjem sms i/ili email
porukama, odnosno koritenjem usluga Twittera (npr. koritenjem metoda
poput DirectMessage, RequestDirectMessage iliRequestFriendTime
Line).
U slijedeem nastavku napravit emo pregled preostalih dostupnih
kontrola, a onda napraviti nekoliko sloenijih primjera, koji bi trebali
prikazati kako ovim alatom doista nije problem brzo napraviti i znatno
sloenije aplikacije.
Android programiranje #14: Alternativni pristup razvoju aplikacija III

Danas emo se pozabaviti preostalim komponentama dostupnim u


Googleovom alatu App Inventor for Android namijenjenom brzom razvoju
Android aplikacija. Komponente su razvrstane u nekoliko grupa slijedeih
naziva: Sensors, Screen Arrangement, LEGO MINDSTORMS, Other
stuf i Not ready for prime time. Krenimo redom.
Sensors komponente: Zaduene su za upravljanje
razliitim senzorima u mobilnom ureaju.

Sensors komponente
Danas je sasvim uobiajeno da pametni telefoni i drugi ureaji temeljeni
na Androidu imaju ugraen manji ili vei broj senzora, koji se mogu vrlo
djelotvorno iskoristiti u razliitim vrstama aplikacija (najee igrama).
Zbog toga je razvijeno nekoliko posebnih komponenti za relativno
jednostavnu podrku takvoj vrsti hardvera. Sve komponente su nevidljive
tijekom izvoenja, ali moraju biti ukljuene u aplikaciju da bi se mogle
iskoristiti njihove mogunosti.
Komponenta AccelerometerSensor zaduena je za interakciju softvera
sa senzorom za mjerenje pomicanja ureaja po sve tri osi koordinatnog
sustava. Od tuda dolaze nazivi najvanijih svojstava: XAccel, YAccel,
Zaccel. Pomou svojstva Available programer moe provjeriti jesu li

navedeni senzor uope dostupni u ureaju, a svojstvom Enabled


upravljati dozvolom koritenja senzora. Dogaajem AccelerationChanged
moe se precizno reagirati na pomicanje ureaja po bilo kojoj od
navedene tri osi (parametara dogaaja), dok je neto grublji dogaaj
Shaking namijenjen mnogo jednostavnijem zadatku obinoj provjeri
drmanja ureajem. Drugi dogaaj se najee moe upotrijebiti za
efektan prekid izvoenja razliitih operacija u aktivnoj aplikaciji.
Druga nevidljiva kontrola iz iste skupine je LocationSensor, a
namijenjena je dobijanju geografske pozicije mobilnog ureaja, ako je u
njega ugraen odgovarajui GPS prijemnik (svojstvo
HasLongitudeLatitude). Softverski je podrano mjerenje nadmorske visine
(svojstvo HasAltitude), ako i takva mogunost postoji u hardveru. Ostalim
dostupnim svojstvima moe se dobiti vrijednost svake od navedenih tri
dimenzija, dok su dogaaji LocationChanged te StatusChanged zadueni
za reakciju aplikacije na promjene pozicije ureaja u prostoru, odnosno na
promjene naina mjerenja pozicije (izravno dobijeni GPS podaci ili podaci
dobijeni od mrenog operatora).
Zadnja komponenta iz grupe OrientationSensor zaduena je za
provjeru orijentacije ureaja u prostoru (svojstva Roll, Pitch i Yaw te
dogaaj OrientationChanged). Ova sofverska komponenta se u
kombinaciji s pripadajuim senzorom koristi u razliitim aplikacijama za
promjenu naina prikaza podataka ovisno o promjeni orijentacije ureaja
(vodoravni ili vertikalni prikaz podataka).
Screen Arrangement komponente
Screen Arrangement komponente: Koriste se kao
podloga za raspored drugih kontrola.

Sve tri komponente iz ove grupe


(HorizontalArrangement, TableArrangement i HorizontalArrangement)
zaduene su za jednostavnije rasporeivanje ostalih komponenti po
zaslonu ureaja. Kao to im i nazivi govore, svaka od komponenti je
zaduena za jednu vrstu rasporeda osnovnih kontrola. Osim za poetno
rasporeivanje kontrola sve tri komponente mogu se takoer iskoristiti za
njihovo jednostavnije premjetanje ili skrivanje. Dostupna svojstva
kontrola su vrlo jednostavna te razumljiva sama po sebi (Visible, Height,
Width, Rows i Columns).
LEGO MINDSTORMS komponente
Sedam komponenti iz grupe LEGO MINDSTORMS predviene su za
upravljanje razliitih dijelovima poznatog Lego kompleta za uenje
robotike pomou nekog od Android ureaja. Iskreno, nismo imali priliku ni
zadovoljstvo isprobati kako sve to skupa djeluje u praksi, pa se zato za

sada neemo previe ni baviti ovim dijelom razvojnog alata. Nadamo se


da emo u ne tako dalekoj budunosti ipak biti u prilici isprobati simbozu
Lego i Google proizvoda.
Other stuf komponente
LEGO MINDSTORMS komponente: Zaduene su za
povezivanje s Lego ovrsjem.

aroliko drutvo softverskih komponenti iz ove grupe


nikako se po svojoj namjeni ne moe dovesti u izravnu vezu, zbog ega je
cijela grupa dobila naziv koji oznaava takvu raznolikost.
Jedna od najvanijih komponenti iz grupe je
komponenta ActivityStater. Zaduena je za pokretanje nekoliko razliitih
aktivnosti na ureaju: drugih aplikacija napravljenih u istom alatu ako
takve postoje u ureaju (ime se moe izbjei dosta ozbiljno ogranienje o
koritenju jednog zaslona ekrana po aplikaciji), aplikacije zaduene za
upravljanje kamerom (ako je kamera ugraena u mobilni ureaj),
pretraivanje web sadraja, postavljanje preglednika na tono odreenu
web adresu, odnosno postavljenje tono odreene lokacije na karti. Zbog
toga komponenta podrava razliite naine vlastitog pozivanja. Evo
primjera iz pratee dokumentacije zaduenog za pretraivanje weba u
potrazi za vampirima.
Action: android.intent.action.WEB_SEARCH
ExtraKey: query
ExtraValue: vampire
ActivityPackage: com.google.android.providers.enhancedgooglesearch
ActivityClass:
com.google.android.providers.enhancedgooglesearch.Launcher
Komponenta BarcodeScanner zaduena je za jednostavno itanje
obinih jednodimenzionalnih, ali i sve popularnijih dvodimenzionalnih bar
kodova (koritenjem metode DoScan, svojstva Result i dogaaj
AfterScan). Da je takva komponenta jednostavno neizostavna u modernim
softverskim rjeenjima, autor teksta moe posvjedoiti iz prve ruke. Na
nedavno zavrenoj Microsoftovoj konferenciji Windays 11 u Rovinju, osim
oekivanih mjesta za takvu vrstu oznaavanja, dvodimenzionalni bar
kodovi su se mogli primijetiti i na majicama nekih sudionika. Naoruani
Android ureajem te odgovarajuom aplikacijom vie ne morate gubiti
vrijeme da bi saznali osnovne informacije o vlasniku majice. Umjesto toga

u njegovom smjeru jednostavno uperite kameru i pogledate na zaslonu


sve to vam eli odati o sebi.
Other stuff komponente: Ostale komponente koje se
koriste u razvoju.

Dvije komponente slinog


naziva BluetoothServer i BluetoothClientzaduene su za podrku
obiju strana koje sudjeluju u Bluetooth komunikaciji (servera i klijenta).
Popis dostupnih metoda, svojstava i dogaaja je zbilja impresivan (bar u
usporedni s drugim komponentama iz istog alata), a potrebno je
poznavati jo poneki detalj Bluetooth tehnologije, tako da se u ovom
tekstu jednostavno ne moemo detaljnije pozabaviti njihovim koritenjem.
Kako je potpisnik ovih redova u bliskoj prolosti imao prilike raditi na
Bluetooth orijentiranom projektu namijenjenom starim dobrim Java MIDP
ureajima, osobno moe potvrditi da je koritenje Google tehnologije na
istom podruju bitno jednostavnije. Budui da sami razvojni inenjeri
tvrde da se na ovom segmentu razvojnog alata jo uvijek intenzivno radi,
ipak treba malo saekati sa zavrnom ocjenom.
Komponenta Notifier omoguava prikaz razliitih vrsti obavijesti
korisniku aplikacije odnosno trajno biljeenje takvih informacija u svrhu
kasnije analize. Za to je pripremljeno nekoliko metoda
(ShowMessageDialog, ShowChooseDialog, ShowTextDialog, ShowAlert i
LogError) ije koritenje rezultira razliitim nainom prikaza informacija
korisniku odnosno njihovom biljeenju. Na raspolaganju su takoer dva
dogaaja: AfterChoosing i ShowChooseDialog, kako bi se moglo ustanoviti
to je poduzeo korisnik kao reakciju na prikazane informacije od strane
aplikacije.
Zadnje dvije komponente iz grupe
(SpeechRecognizer i TextToSpeech) zamiljene su kao podrka za
izradu govorno orijentiranog korisnikog suelja u vlastitim Android
aplikacijama. Prva kontrola namijenjena je razumijevanju izgovorenog,
dok je druga zaduena za suprotan proces izgovaranje napisanog
teksta. Koliko to sve skupa radi ili ne radi dobro s razliitim govornim
jezicima moete isprobati sami. Obje komponente su vrlo jednostavne za
koritenje, jer se primjena svodi na upotrebu jednostavnih metoda poput
GetText, Speek, Country i Language.
Spomenimo na ovom mjestu kako se za izgovor napisanog teksta koristi
ista Google tehnologija koja je koritena u serijalu o naprednom
programiranju Windows aplikacija, objavljenom u vie prethodnih brojeva
vaeg omiljenog asopisa.
Not ready for prime time komponente

Not ready for prime time komponente: Eksperimentalne


komponente u intenzivnoj fazi razvoja.

U posljednoj grupi komponenti navedene su komponente na ijem


razvoju jo uvijek intenzivno rade Googleovi razvojni inenjeri, pa su kao
takve podlone razliitim promjenama dok ne stignu u fazu dovrenog
proizvoda. Trenutno su u tu grupu svrstane slijedee komponente:
FusionTablesControl koritenje kartografskih prikaza u kombinaciji s
FusionTables tehologijom.
GameClient povezivanje aplikacija (najee igara) s odgovarajuim
serverima za udruene NEzloinake poduhvate.
SoundRecorder biljeenje i pohranjivanje zvunih zapisa.
TinyWebDB komunikacija s web servisima zbog dvosmjerne razmjene
podataka.
Voting osnova za budue glasake listie u Android demokraciji
budunosti.
Kako su sve nabrojane komponente iz ove grupe u razvoju, za sada se
neemo previe ni baviti njima. Ipak moramo priznati da nas strano
zanima vrlo novi svijet u kojem emo praktino trenutno moi odluivati o
bitnim stvarima u zemlji, a ne ekati da to radimo od izbora do izbora.
Naalost, ipak bi se mogli okladiti na prilino velike iznose kako e takvu
tehnologiju prije prihvatiti razliiti reality spektakli nego dravna
uprava. ivi bili pa vidjeli.
Ovime je zavreno predstavljanje najvanijih segmenata Googleovog
razvojnog alata za neprogramere. Preostalo je da pomou njega probamo
napraviti jednu sloeniju aplikaciju kao demonstraciju kako razliite
komponente surauju u praksi.

Android programiranje #15: Izrada sloenijih aplikacija

Nakon to smo u prolih nekoliko nastavaka predstavili najvanije


dijelove Googleovog alata za razvoj aplikacija namijenjenog korisnicima
neprogramerima, odnosno malo manje vjetim programerima, doao je
trenutak da pokaemo kako se ti dijelovi zaista koriste u vlastitim
aplikacijama. Za razliku od prve demo aplikacije, kad smo vrlo detaljno
rijeju i slikom opisivali kako se izvode sve operacije potrebne da se
dobije dovrena aplikacija, u dananjem nastavku emo samo naznaiti
glavne smjernice u pripremi aplikacije, a na vama je da probate sami
dovesti projekt u funkcionalno stanje. Tako emo odmah pripremiti i
svojevrsnu vjebanju u koritenju alata.
Iako se danas mobilni ureaji koriste za izvoenje vie desetaka razliitih
operacija od planiranja vlastitog vremena, preko sluanja muzike i
gledanja filmova pa sve do igranja razliitih vrsta igara, mogunost
izvoenja starog, dobrog telefonskog poziva (ili bar odgovaranja na njega)
jo uvijek ostaje jedna od najbitnijih namjena veine mobilnih telefona.
Zato emo u prvom primjeru neto sloenije aplikacije demonstrirati to
moemo napraviti u Googlevom razvojnom alatu po tom pitanju, ako ne
elimo koristiti ve ugraene mogunosti u sam ureaj.
Pretpostavka za uspjeno izvoenje slijedee aplikacije na konkretnom
Android ureaju je da taj ureaj podrava izvoenje telefonskih poziva, a
ne samo razliite internet orijentirane naine vlastitog koritenja (pregled
web stranica, razmjena email poruka i slino). Takoer, u spremite
kontakata u ureaju trebalo bi biti upisano bar nekoliko telefonskih
brojeva, a nekima od brojeva trebale bi biti dodijeljenje slike njihovih
vlasnika. ak i ako svi nabrojeni zahtjevi budu zadovoljeni, moe se
dogoditi da na nekim ureajima primjer ipak ne djeluje kako se oekuje.
Razloge treba traiti u tome to u trenutnoj fazi razvoja alat App Inventor
for Android jo uvijek nije ni testiran ni optimiziran za sve dostupne
ureaje na tritu. Googleovi razvojni inenjeri obeavaju kako e takve
poroajne muke biti rijeene u bliskoj budunosti kad razvojni alat vie
ne bude u fazi svojevrsnog testiranja.
Za uspostavu telefonskog poziva iz Android ureaja, kao to to ve
znate, treba kreirati novi prazan projekt te mu dodijeliti nekakav naziv koji
simbolizira namjenu projekta. U pripremi primjera povezanog s ovim

tekstom koriten je naziv VidiPhoneCall, ali nema apsolutno nikakvog


razloga da ne odaberete neki drugi mnogo razumljiviji naziv (npr. APC
4MM Android PhoneCall System for Modern Manager). Od dostupnih
Android komponeti u projektu su nam na samom poetku potrebne samo
dvije: komponenta PhoneCall iz grupe Social te komponenta Button iz
grupe Basic. U nastavku teksta emo sline konstrukcije skraeno
pisati Social -> PhoneCall, odnosno Basic -> Button.
Social -> Phone Call: Temeljna komponenta za izvoenje
telefonskog poziva iz vlastite Android aplikacije.

Svakoj komponenti postavljenoj na osnovni zaslon


razvojni alat automatski dodjeljuju naziv sastavljen od naziva komponente
te rednog broja takve vrste komponente unutar projekta. U sluaju
jednostavnijih projekta takvi nazivi se mogu izravno koristiti za dovretak
projekta, ali dobra praksa iskusnijih programera predlae njihovo
preimenovanje u daleko razumljivije nazive, kako bi se kasnije olakalo
snalaenje u projektu. to se u nekom projektu koristi vie razliitih
komponenti (to vrijedi i za sve druge razvojne alate), to je vanije imati
smislenije nazive, da bi se programer to bre i jednostavnije mogao
snai u naknadnoj analizi i izmjeni programskog koda. Dobro, kod alata
App Inventor zapravo ni ne moemo govoriti ba o pisanju programskog
koda, jer je prije rije o neemu nalik slaganju komada slagalice
sastavljene od dostupnih dogaaja i metoda koritenih komponeti, ali
nema nikakvog razloga da ignoriramo pravilo o imenovanju komponenti.
Preimenovanje komponente postavljene na osnovni zaslon projekta
izvodi se njezinim oznaavanjem, te klikom na gumb <Rename> u
razvojnoj okolini alata. Za potrebe ovog projekta komponentu PhoneCall1
preimenovali smo u TelefonskiPoziv, a komponetu Button1
uUspostaviPoziv. Jo jednom ponavljamo budui da bi rad na ovom
projektu trebao ujedno biti vaa samostalna vjeba koritenja Googleovog
razvojnog alata, nazive komponenti moete izabrati prema vlastitim
sklonostima. Za komponentu TelefonskiPoziv moe se izmijeniti i poetna
vrijednost svojstva PhoneNumber na eljeni broj pozivatelja (ako se pozivi
najee upuuju na taj broj), dok komponenti UspostaviPoziv treba
izmijeniti svojstvo Text, kako bi zamjena za podrazumijevanu
vrijednost Text for Button1 preciznije pokazivala namjenu gumba.
U ovom trenutku je dovreno crtanje korisnikog suelja, a sad
preostaje jo samo to da se napie odgovarajui programski kod,
odnosno dovri slagalica u inovativnom Googleovom suelju za tu
namjenu (o ijem koritenju je bilo vie rijei u prvom nastavku serijala).
Sasvim konkretno u ovom sluaju potrebno je napraviti povezivanje
bloka Click iz kontrole UpostaviPoziv s blokomMakePhoneCall iz

kontrole TelefonskiPoziv. Na taj nain dovrena je prva verzija aplikacije


koja omoguava uspostavu telefonskog poziva iz Android ureaja s
upisanim odredinim brojem nakon to korisnik pritisne kontrolu (gumb)
UspostaviPoziv. Djelovanje programa moete (ili ipak ne moete) provjeriti
sami na vlastitom komadu Android hardvera, ve prema tome kako je on
trenutno podran od strane Googleovih razvojnih inenjera.
Na trenutnom stupnju razvoja nae nove aplikacije trebalo bi biti
mogue uspostaviti telefonski poziv, ali aplikacija jo uvijek nema
pojma o podacima zapisanim u bazu kontakata u okviru samog ureaja,
nego se svi telefonski brojevi moraju upisivati u cijelosti. Budite iskreni
pa priznajte sami sebi koliko esto u praksi zaista izvodite operaciju
upisivanja broja pozivatelja u odnosu na uestalost biranja dostupnih
brojeva iz baze kontakata. Zato aplikaciju treba dodatno proiriti tako da
postane svjesna ranije pripremljenih telefonskih brojeva.

Dovreno suelje aplikacije za telefoniranje: Omoguava


koritenje podataka iz spremita kontakata u samom
ureaju.

U drugoj verziji aplikacije emo na osnovni zaslon aplikacije dodati jo


jednu novu kontrolu: Social -> PhoneNumberPicker, a onda joj
izmijeniti predloeni naziv u IzaberiBroj, odnosno tekst koji se prikazuje
na kontroli s poetne vrijednosti Text for PhoneNumberPicker1 za
hrvatsku verziju aplikacije primjereniji oblik Izaberi broj. Kontrola tipa
PhoneNumberPicker predstavlja svojevrsnu verziju obinog gumba, s tom
razlikom da pritisak na kontrolu automatski izaziva prikaz podataka iz
postojee baze kontakata u ureaju. Kad smo napisali prikaz podataka,
onda smo zaista mislili samo na to, jer odabir telefonskog broja iz
prikazanih podataka jo uvijek nije mogu, bar ne tako dugo dok se
ponovo ne pripremi odgovarajua slagalica za upravljanje izvoenjem
programa.
Da bi se na temelju izabranog podatka iz popisa kontakata zaista
ostvario telefonski poziv, potrebno je spojiti blok AfterPicking kontrole
IzaberiBroj s blokom MakePhoneCall iz kontrole TelefonskiPoziv.
Potrebno je napraviti jo prijenos odgovarajueg parametra (izabranog
telefonskog broja) izmeu te dvije kontrole, to se izvodi dodatnim
vezanjem blokaPhoneNumber kontrole IzaberiBroj s prije navedenim
blokom MakePhoneCall. Ovim korakom, ako je sve pravilno izvedeno,
trebala bi biti dovrena druga faza u razvoju aplikacije. Sada je aplikacija
spremna za izvoenje telefonskih poziva na temelju prije spremljenih
podataka u bazu kontakata.

U smislu poboljanja grafikog izgleda aplikacije mogue je u aplikaciju


dodati jo poneki detalj. Premda se u trenutnoj verziji broj iz baze
kontakata zaista moe izabrati kao temelj za telefonski poziv, korisnik
aplikacije jo uvijek ne moe vidjeti o kojem je telefonskom broju rije. Da
ne spominjemo nemogunost prikaza slike vlasnika telefonskog broja, ako
takva postoji u ureaju. Unapreenje korisnikog suelja aplikacije moe
se postii tako da se u okviru istog bloka AfterPicking kontrole
IzaberiBroj, naprave dva dodatna povezivanja. Blok PhoneNumber iz
kontrole IzaberiBroj treba povezati s blokom Text ranije opisanog gumba
UspostaviPoziv, a blok Picture iz kontrole IzaberiBroj spojiti s
blokom Image, takoer svojstvom gumba UspostaviPoziv. Navedenim
operacijama je aplikacija poboljana u vizualnom smislu pa osim
zahtijevane funkcionalnosti sada posjeduje i odgovarajue korisniko
suelje.
Trenutna verzija aplikacija se i dalje moe nadograivati, pa evo nekoliko
ideja koje moete probati napraviti sami:
1. Osim prijenosa broja koji se poziva iz baze spremljenih kontakata,
probajte prenijeti jo neke podatke na osnovni zaslon aplikacije (prije
svega prezime i ime korisnika). Razmislite prvo trebaju li vam kakve
dodatne kontrole na suelju, da bi to zaista mogli napraviti. Ova toka
ne bi trebala biti prezahtijevna za realizaciju.
2. Podaci o uspostavljenim pozivima mogli bi se sauvati za kasniju
analizu. Kako je u ovom sluaju rije o malo zahtijevnijem postupku, o
njemu e vie rijei biti neki drugi put.
Na kraju, ambiciozniji itatelji mogu probati sami napraviti slian projekt
ispoetka tako da se umjesto uspostave telefonskog poziva izvodi slanje
dobre, stare SMS poruke. U tom sluaju temeljnu kontrolu za rad
aplikacije (Social -> PhoneCall), treba zamijeniti neim drugim, ali vam
to sada neemo otkriti, nego vam ostavljamo da na temelju prethodnih
nastavaka serijala i vlastitog eksperimentiranja sami pronae o emu je
rije. U svakom sluaju preporuamo vam da sami probate odraditi cijeli
posao oko dananje aplikacije, kako bi mogli lake pratiti slijedei projekt,
gdje emo jo manje detaljizirati oko biranja kontrola i njihovog koritenja
nego to je to bi sluaj danas. Budui da emo raditi na mnogo sloenijem
projektu jednostavno moramo pretpostaviti da su vam dobro poznate
osnovne stvari oko koritenja Googleovog alata za neprogramere.

Android programiranje #16: Koritenje kartografskih servisa

U dananjem zavrnom nastavku svojevrsnog podserijala o koritenju


Googleovog alata za brzo prototipiranje aplikacija, pokazat emo kako se
u okviru tog alata koriste kartografske mogunosti Googleovih servisa,
jedne od najee koritenih tehnologija u aplikacijama na mobilnim
ureajima.Dodatna vrlo zanimljiva razvojna tehnika demonstrirana u
istom primjeru je pozivanje jedne Android aplikacije iz druge Android
aplikacije. Ve smo nekoliko puta spomenuli kako je trenutno jedno od
najveih ogranienja Googleovog razvojnog alata za neprogramere u
tome to se unutar jedne aplikacije moe koristiti samo jedan raspored
kontrola. Upravo sposobnou pozivanja jedne aplikacije iz druge moe se
zaobii spomenuto ogranienje. Nain koritenja kartografskih servisa na
kojem se temelji dananji tekst prikazan je u Googeovom primjeru
pripremljenom od strane profesora Davida Wolbera sa sveuilita u San
Franciscu.
Prije nego to nastavimo s detaljnijim objanjavanjem primjera istaknimo
na ovom mjestu jo jednu bitnu mogunost operativnog sustava Android
u pogledu izrade rjeenja koje se sastoji od veeg broja sastavnih
dijelova. Dok za pozivanje drugog dijela aplikacije iz poetnog dijela treba
koristiti komponentu ActivityStarter, povratak unatrag se izvodi potpuno
automatski. Dovoljno je samo izabrati standardnu operaciju operativnog
sustava za tu namjenu, to jest odgovarajuu tipku na samom ureaju.

Prvi dio aplikacije (suelje): Sastoji se od tri osnovne


kontrole: Image1, ListPicker1 i ActivityStater1.

U prvom dijelu aplikacije na osnovni zaslon projekta postavljene su


svega tri kontrole: Image1, ListPicker1 i ActivityStater1.
Kontrole su redom namijenjene za prikaz poetne slike programa, izbor
triju razliitih odredita za prikaz na karti, te na kraju komponente za
pokretanje dodatne kartografski orijetirane aplikacije. Prve dvije kontrole
ne bi trebale biti posebno teke za koritenje, tako da ih neemo ni

posebno opisivati. Uostalom, kontrolu za prikaz slika koristili smo ve u


prvom, najtrivijalnijem primjeru koritenja alata.
Neto vie vremena posvetit emo koritenju komponente ActivityStarter,
zato to ona zahtijeva oblik znanja kakav je uobiajen u krugovima pravih
Android programera, ali nije ba uobiajen za korisnike neprogramere.
Drugim rijeima, druga komponenta cjelokupnog rjeenja mora se pozvati
iz prve prema tonom definiranom protokolu, to bi u ovom sluaju imalo
otprilike slijedei oblik:
ActivityStarter svojstvo

Vrijednost

Action android.intent.action.VIEW
ActivityClass com.google.android.maps.MapsActivity
ActivityPackage com.google.android.apps.maps

Prvi dio aplikacije (programski blokovi): Najvaniji dio


povezan je aktivnostima kontrole ActivityStarter.

Programski blokovi povezani s aplikacijom podijeljeni su u dva dijela. Prvi


dio je zajedno s prateim deklaracijama vrijednostima zaduen za
pripremu poetnog izgleda aplikacije (vidi prateu sliku uz tekst), dok se
drugi izvodi nakon odabira neke od zadanih lokacija: Tour Eiffel, Musee
du Louvre i Cathedrale Notre Dame. Nakon odabira jednog od
navedena tri mjesta iz popisa prelazi se na izvoenje programskog
blokaListPicker1.AfterPicking.
Na ovom mjestu dolazimo do male dodatne komplikacija pa je treba
objasniti neto detaljnije. Da bi se pomou komponente ActivityStarter
mogla uspjeno pokrenuti druga komponenta za prikaz nekog mjesta na
mapi, potrebno je komponenti prenijeti adresu u tono propisanom
formatu, a to u ovom sluaju znai popunjavanje
svojstvaActivityStater.DataUri. U spomenuto svojstvo mora se postaviti
kombinacija vrijednosti geo:0,0?q= te konkretne vrijednosti za
izabranu lokaciju iz popisa dostupnih mjesta (ListPicker1.Selection). Za
to se koristi posebni programski blok zaduen za rukovanje nizovima
znakova (make text). U sluaju odabira druge od dostupnih vrijednosti
dobije se konana vrijednost: geo:0,0?q=Musee du Louvre.

Izvoenje aplikacije: Osnovni oblik izvoenja aplikacije u


Android emulatoru.

Sad je konano sve spremno za pozivanje drugog dijela aplikacije, pa


prvi dio aplikacije zaista predaje kontrolu izvoenja drugom dijelu na
ranije opisani nain. Po elji se (to smo isto ve spomenuli) moete vratiti
na prvi dio koritenjem standardne operacije u operativnom sustavu
Android.
Sirovi oblik kartografskog prikaza kakav je u ovom trenutku prisutan u
aplikaciji moe se dalje nadograivati tako da se modulu zaduenom za
prikaz objekta mnogo preciznije zada nain prikaza nekog mjesta prema
sintaksi propisanoj od strane Googlea. Na primjer, za znatno atraktivniji
nain prikaza svih triju lokacija mogla bi se navesti malo sloenije
odrednice:
Eiffel Tower
http://maps.google.com/maps?
f=q&source=s_q&hl=en&geocode=&q=eiffel+tower&sll=37.0625,95.677068
&sspn=48.909425,72.333984&ie=UTF8&hq=Tour+Eiffel&hnear=Tour+Ei
ffel,+Quai+Branly,+75007+Paris,+Ile-de-France,
+France&ll=48.857942,2.294748&spn=0.001249,0.002207&t=h&z=19
Musee Louvre
http://maps.google.com/maps?
f=q&source=s_q&hl=en&q=louvre&sll=48.86096,2.335421&sspn=0.002
499,0.004415&ie=UTF8&t=h&split=1
&filter=0&rq=1&ev=zi&radius=0.12&hq=louvre&hnear=&ll=48.86096,2.
335421&spn=0.002499,0.004415&z=18
Notre Dame, Street View
ttp://maps.google.com/maps?
f=q&source=s_q&hl=en&q=french+landmarks&sll=48.853252,2.349111
&sspn=0.002411,0.004415

&ie=UTF8&t=h&radius=0.12&split=1&filter=0&rq=1&ev=zi&hq=french
+landmarks&hnear=&ll=48.853252,2.349111&spn=0,0.004415
&z=18&layer=c&cbll=48.853046,2.348861&panoid=74fLTqeYdgkPYj6KKL
lqgQ&cbp=12,63.75,,0,-35.58
U sluaju da elite provjeriti sami kako sve to skupa lijepo djeluje u praksi,
a nemaze ni vremena ni volje da ispoetka razvijate cijelu aplikaciju,
moete krenuti linijom manjeg otpora te usmjeriti svoj preglednik na
adresu http://appinventor.googlelabs.com/learn/tutorials/maptour/maptou
r.html

Kontinuirani razvoj alata

Napredno izvoenje aplikacije: U prikaz su ukljuene


dodatne opcije za prikaz slika na zadanoj lokaciji.

U razdoblju od prvog spominjanja razvojnog alata App Inventor for


Android u ovom serijalu, pa do dananjeg nastavka, Googleovi razvojni
inenjeri marljivo su radili na njegovim unapreenjima (a rade i dalje).
Budui da se razvoj aplikacija izvodi izravno u nekom od preglednika nije
potrebno preuzimati nikakve nove verzije alata da bi se iskoristile te
novosti, nego su one odmah dostupne im se alat slijedei put pokrene
nakon njegovog auriranja na Googleovom serveru.
Osim ispravke uoenih pogreaka prijavljenih od strane korisnika,
izgleda da se najintenzivnije radi na daljnjim doradama komponenti u
okviru kolekcije Other Stuf. Komponenta Web zamiljena je tako da
osigurava dodatne mogunosti u izravnom preuzimanju podataka s web
servera, za to se do sada morao koristiti poseban Java kod (ili programski
kod u nekom drugom programskom jeziku) distribuiran na server. Sada je
postalo mogue pozivati odreene skupine API funkcija izravno preko Web
komponente. Na primjer, koritenjem poziva funkcija iz Yahoo Finance API

biblioteke prilino je jednostavno u Android aplikaciju dodati prikaz


razliitih poslovnih informacija o ijoj pripremi i pouzdanosti brine Yahoo.
Iako to nema izravne veze s temom dananjeg teksta, za eventualno
zainteresirane ipak spomenimo kako se sve potrebne informacije o
koritenju Yahoo Finance API tehnologije nalaze na
adresi:http://www.gummy-stuff.org/Yahoo-data.htm

Web komponenta u akciji: Izravno koritenje Yahoo


Finance API tehnologije.
Za sada toliko o ovoj temi. Nadamo se da vas je sve do
sada napisano potaklo da ponete razmiljati o razvoju
vlastitih Android aplikacija, ak i ako niste programer, ili ako to nikada
niste ni mislili postati. Kad savladate razvojni alat za neprogramere
moda ete poeljeti da se u budunosti ponete baviti i pravim Google
Android programiranjem. Na njega emo se ponovo vratiti u slijedeem
nastavku, kako bi pokazali jo nekoliko naprednijih tehnika koritenja
osnovnog SDK alata.
Android programiranje #17: to je novo u 3.x izdanjima

Da ovjek jednostavno ne povjeruje kako vrijeme brzo leti od poetka


serijala o programiranju koritenjem Googleovog razvojnog alata Android
SDK, ve je prolo vie od godinu dana, a u meuvremenu se je mnogo
toga dobrog dogodilo sa samim alatom u smislu proirenja njegovih
mogunosti. Za to je prije svega zasluna prava eksplozija pojave novih
modela tablet raunala, jer je upravo ona dovela do potrebe optimiziranja
Android sustava za takvu vrstu hardvera.
Novosti u alatu App Inventor for Android
Prije nego se pozabavimo osnovnim Android SDK razvojnim sustavom
namijenjenom pravim programerima, napiimo nekoliko dodatnih rijei
o najnovijim vijestima povezanim s Googleovim alternativnim alatom za
brzo prototipiranje aplikacija (App Inventor for Android), jer smo se upravo
njime bavili zadnjih nekoliko brojeva. Ako vam se alat dopao, pa zato
planirate njegovo dugoronije koritenje, vano je znati to vam oekuje u
budunosti.
Prvo, i trenutno najvanije, kao novu web adresa za online koritenje
alata App Inventor for Android trebati e ubudue
koristiti www.appinventorbeta.com umjesto dosadanje
adrese appinventor.googlelabs.com. U duhu voenja brige za postojee

korisnike vlastitih proizvoda, uobiajenom kod velikih IT poduzea, sve


postojee aplikacije registriranih korisnika sauvane su i dostupne na
novoj adresi, tako da nema potreba za nekakvim prepisivanjem
aplikacija s jedne adrese na drugo.

Android 3.x: Donosi brojne promjene u korisnikom


suelju optimizirane za moderne tablet ureaje.

Drugo, te jednako vano za budue koritenje alata, Google prestaje s


izravnim radom na odravanju i razvoju alata App Inventor for Android. To
na sreu ne znai da e alat nestati, nego da on prelazi u open source
kategoriju. Za budui status alata brigu e voditi novoosnovani Center
for Mobile Learning u okviru MIT Media Laba, te biti pod stalnim
nadzorom tri profesora s istog sveuilita: Hal Abelson, Eric
Klopfer i Mitchel Resnik. Prva osoba iz nabrojene trojke zasluna je za
predlaganje i pokretanje itavog projekta 2008 godine zajedno s
poduzeem Google, iz laboratorija drugog profesora potekla je prva
verzija razvojnog alata, i to upravo na temelju ideje zadnjeg imena s
popisa. Dovretak cijelog postupka oekuje se do kraja godine, a postojei
korisnici alata e redovito dobijati informacije o svim promjenama.

Novosti u osnovnom Android sustavu


Nakon razjanjavanja trenutne i budue situacije s alatom za brzo
prototipiranje Android aplikacija, vratimo se sada na osnovni razvojni alat
Android SDK. Od trenutka poetka pisanja serijala, kojeg upravo itate,
razvojni alat je promijenio svoju prvu brojanu oznaku verzije s 2 na 3, to
uvijek znai da je dolo do bitnih promjena u nekom softverskom paketu.
Kao to smo to ve spomenuli na samom poetku ovog teksta, kljuni
okida za takve promjene je sveopa zaluenost tablet raunalima,
kako od strane proizvoaa, tako i od strane korisnika mobilnih ureaja.
Budui da se po dijelu svojih hardverskih karakteristika takvi ureaji
razlikuju od mobilnih telefona, Android sustav doivio je bitne promjene
to simbolizira nova poetna oznaka verzije.
Pogledajmo prvo to se najvanijeg dogodilo sa stanovita krajnjeg
korisnika.
Najvanije su, naravno, promjene na dimenzijama i rezoluciji
zaslona, jer su ove vrijednosti u pravilu dosta vee nego kod mobilnih

telefona. Poveanje zaslona pretpostavka je za dodatnu zabavu u


korisnikom suelju, kako u pogledu redizajna postojeih dijelova, tako i u
pogledu dodavanja potpuno novih dijelova suelja poput sistemske ili
akcijske trake. Kad govorimo o promjenama u korisnikom suelju onda se
to odnosi na dio vidljiv na zaslonu, ali i na sistemske, grafiki orijentirane
module u pozadin,i koji su takoer morali doivjeti brojne promjene.
Na veem zaslonu ureaja mogla se izmeu ostalog redizajnirati
softverska tipkovnica namijenjena unosu znakova. Tipkovnica je
jednostavno postala udobnija te bra za koritenje nego prije, jer se do
dijela tipki vie ne mora dolaziti zaobilazno. Jo jedna bitna stvar
povezana s korisnikim sueljem je poboljana mogunost upravljanja
operacijama oznaavanja, isijecanja, kopiranja i umetanja teksta. Sada se
za tu operaciju koriste dodatne strelice prikazane na zaslonu.

Promjene u poznatim aplikacijama: Na primjer, aplikacija


za upravljanje ugraenom kamerom.

Prva od prije spomenutih traka, smjetena na samom dnu zaslona,


namijenjena je za brzi pristup obavijestima, statusnim pokazateljima
sustava te navigacijskim gumbima postavljenim na sam zaslon. U pravilu
sistemska traka dostupna je stalno, iako se ako je to ba potrebno moe
sakriti u sluaju da neka aplikacija treba iskoristiti cijeli dostupni prostor
zaslona. Jo jedan vaan zadatak sistemske trake je upravljanje
viezadatkovnim radom preko popisa nedavno koritenih aplikacija
(Recent Apps). Druga traka (akcijska) nalazi se na vrhu zaslona, a izgled i
djelovanje ovise joj o kontekstu izvoenja aplikacije, to znai da
promjenom njezinog izgleda upravlja aplikacija, a ne sam Android sustav.
Od ostalih novosti svakako treba spomenuti nove mogunosti
povezivanja tablet raunala s vanjskim ureajima pomou Media/Picture
Transfer Protocola, odnosno povezivanje prave tipkovnice s ureajem kako
bi se jo vie olakalo upisivanje teksta. Na kraju tu je i nekoliko
poboljanja standardnih aplikacija preglednik, elektronika pota,
kamera, galerija i imenik. U jo novijim verzijama nasljednicama s oznaka
3.1 i 3.2 uvedena su dodatna unapreenja u korisnikom suelju te
povezivanju s vanjskim ureajima (npr. razliiti dodaci za igru) i Wi-Fi, dok
je sam Android sustav optimiziran za brojne tablet ureaje, koji su se na
tritu pojavili u meuvremenu.
U ovom nabrajanju ne smijemo nikako zaboraviti na jo jednu promjenu,
budui da ona nije vidljiva na prvi pogled, ali pridonosi ukupnom

zadovoljstvu koritenja Android platforme. Osim to u verziji 3.x Android


podrava istovremeno koritenje veeg broja aplikacija, sada se te
aplikacije mogu izvoditi i na veem broju procesora odnosno jezgri, ako je
takva hardverska konfiguracija ugraena u mobilni ureaj. Android ureaji
tako e uskoro moi rjeavati najsloenije probleme, a da ne spominjemo
kako e dobro na njima izgledati razliite igre. U meuvremenu su se na
tritu zaista pojavili viejezgreni ureaji, tako da ovo vie nije samo
teoretska mogunost sustava.
Sad kad smo ukratko naveli to je sve novo u sustavu sa stanovita
krajnjeg korisnika, pogledajmo to to zapravo znai za programere, ako
ele pisati optimizirane aplikacije za nove verzije Andrioda s poetnom
verzijom 3. Svaka nova verzija Androida sa sobom donosi izmijenjeno
programsko suelje s odreenim brojem novih poziva API funkcija,
odnosno izmjene u nainu koritenja postojeih funkcija. Budui da su se
u verziji 3.0 (i novijima) pojavili potpuno novi dijelovi korisnikog suelja,
kao to je akcijska traka ili sistemska traka, najvanije API promjene
povezane su upravo s tim dijelovima. Drugim rijeima, dobili smo sasvim
dovoljno grae za jo nekoliko nastavaka serijala u kojima bi se
demonstrirale najnovije mogunosti platforme.
Navedimo sada primjer dijela programskog koda namijenje koritenju
akcijske trake u vlastitim aplikacijama, tek toliko da steknete dojam kako
to izgleda Detaljnije djelovanje programskog koda koji upravlja alatnom
trakom, ali i drugim novostima verzije 3.x objasnit emo na sloenijem
primjeru kojeg poinjemo izraivati slijedei put.
package com.example.android.apis.app;
import com.example.android.apis.R;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import android.widget.TextView;
import android.widget.Toast;
public class ActionBarTabs extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action_bar_tabs);
}
public void onAddTab(View v) {
final ActionBar bar = getActionBar();
final int tabCount = bar.getTabCount();
final String text = Tab + tabCount;
bar.addTab(bar.newTab()
.setText(text)
.setTabListener(new TabListener(new TabContentFragment(text))));
}
public void onRemoveTab(View v) {
final ActionBar bar = getActionBar();
bar.removeTabAt(bar.getTabCount() 1);
}
public void onToggleTabs(View v) {
final ActionBar bar = getActionBar();
if (bar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE,
ActionBar.DISPLAY_SHOW_TITLE);

} else {
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
}
}
public void onRemoveAllTabs(View v) {
getActionBar().removeAllTabs();
}
private class TabListener implements ActionBar.TabListener {
private TabContentFragment mFragment;
public TabListener(TabContentFragment fragment) {
mFragment = fragment;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(R.id.fragment_content, mFragment, mFragment.getText());
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(mFragment);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(ActionBarTabs.this, Reselected!,
Toast.LENGTH_SHORT).show();
}
}
private class TabContentFragment extends Fragment {
private String mText;

public TabContentFragment(String text) {


mText = text;
}
public String getText() {
return mText;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View fragView = inflater.inflate(R.layout.action_bar_tab_content,
container, false);
TextView text = (TextView) fragView.findViewById(R.id.text);
text.setText(mText);
return fragView;
}
}
}

You might also like