117169381-Mala-škola-Androida-VIDI

October 20, 2017 | Author: jalija | Category: N/A
Share Embed Donate


Short Description

Android...

Description

     

Mala škola Androida  by  Vidi                  android.vidilab.com    

            RIPed by: Memhis                                                         (12/2012) 

Sadržaj:  1. Priprema razvojne okoline za pisanje Google Android aplikacija  2. Pisanje i pokretanje prvog programa  3. Interakcija s korisnikom  4. Uvod u pisanje programskoga koda  5. Korištenje rasporeda kontrola u složenim aplikacijama  6. Korištenje osnovnih Android kontrola  7. Android programiranje  8. Android kontrole u akciji IV  9. Korištenje datotečnog sustava   10. Nekoliko standardnih dijelova aplikacije  11. Standardni dijelovi aplikacije  12. Alternativni pristup razvoju aplikacija  13. Alternativni pristup razvoju aplikacija II  14. Alternativni pristup razvoju aplikacija III  15. Izrada složenijih aplikacija  16. Korištenje kartografskih servisa  17. Što je novo u 3.x izdanjima 

         

1. Priprema razvojne okoline za pisanje Google Android  aplikacija  Želimo  li  programirati  za  platformu  Google  Android  najprije  na  računalo  trebamo  instalirati  i  konfigurirati razvojne alate. Već na tom koraku mnogi odustaju, jer se za razvoj koriste tri različita  alata, a svaki od njih ima drugačijeg proizvođača. Da bi sve proradilo kako treba, instalaciju treba  napraviti baš „prema propisima“.  Krenimo  redom,  uz  jednu  bitnu  pretpostavku.  Postupak  instalacije  opisan  je  za  „čisto“  Windows  računalo, što znači da je na njemu instaliran samo operativni sustav, bez neke od starijih inačica  alata  koje  ćemo  spomenuti  u  nastavku.  Na računalu nisu pokrenuti ni svakakvi antivirusni programi, vatrozid ili slični programi, jer bi oni  mogli  blokirati  neke  od  opisanih  postupaka.  U  takvom  slučaju  ne  možemo  pretpostaviti  svaku  moguću situaciju u praksi, odnosno objasniti kako riješiti nastali problem, pa zato preporučujemo  da postupak započnete od nulte konfiguracije sustava.  Kao  što  smo  to  već  ranije  spomenuli,  na  računalo  treba  instalirati  tri  razvojna  alata  različitih  proizvođača.  Iako  sve  može  proraditi  i  ako  se  ne  koriste  baš  inačice  s  identičnim  oznakama  na  „zadnju  decimalu“,  nego  neke  druge  brojčano  slične  inačice,  preporučujemo  vam  da  koristite  isključivo one opisane u nastavku teksta jer s njima sve sigurno i provjereno radi. Osim toga, sva tri  alata  dostupna  su  na  DVD‐u  travanjskog  broja  časopisa  VIDI,  ukoliko  ne  želite  gubiti  vrijeme  na  njihovo preuzimanje s weba.  Alate treba instalirati ovim redoslijedom:  1. jdk‐6u17‐javafx‐1_2_1‐windows‐i586.exe  2. eclipse‐java‐galileo‐SR2‐win32.zip  3. android‐sdk_r04‐windows.zip  Datoteka  jdk‐6u17‐javafx‐1_2_1‐windows‐i586.exe  Sunov  je  razvojni  alat  za  Java  aplikacije  pod  oznakom Java SE Development Kit 6 Update 17. U toj datoteci nalazi se Sunov razvojni alat za RIA  aplikacije  s  oznakom  JavaFX  1.2  SDK.  Kad  već  morate  instalirati  Javu  kao  preduvjet  za  pisanje  Google  Android  aplikacija,  zašto  ne  biste  instalirali  i  razvojni  alat  za  RIA  aplikacije  istog  proizvođača?  Možda  vam  nekad  zatreba  nešto  takvo,  iako  JavaFX  SDK  nije  preduvjet  za  razvoj  Android aplikacija.  Instalacija Sunovog proizvoda najviše liči na instalaciju profesionalnog razvojnog alata na kakvu ste  vjerojatno navikli, pa je zato nećemo ni posebno opisivati, jer je doista riječ o trivijalnom postupku.  Dovoljno  je  pokrenuti  prije  spomenutu  datoteku  te  jednostavno  prihvatiti  sve  podrazumijevane  postavke instalacije. Jedini izuzetak mogla bi biti činjenica da na podrazumijevanom disku nemate  dovoljno  prostora,  ali  odgovarajuća  korekcija  zaista  ne  bi  trebala  stvoriti  previše  problema  kod  instalacije.  Za instalaciju druge datoteke eclipse‐java‐galileo‐SR2‐win32.zip, potreban vam je neki od alata za  raspakiravanje zip datoteka, na čije ste korištenje vjerojatno navikli, pa ni tu nećemo gubiti previše  prostora na opisivanje postupka rapakiravanja. Rezultat raspakiravanja jest mapa eclipse zajedno s  pripadajućim podmapama. Mapu možete „objesiti“ izravno na korijensku mapu \, ili je staviti na za  to uobičajeno mjesto C:\Program Files. U navedenoj mapi nalazi se izvršna datoteka eclipse.exe na 

koju nakon toga možete napraviti prečac na radnoj površini operativnog sustava, kako biste je što  jednostavnije pokretali tijekom budućeg korištenja.  Objasnimo ukratko što je to zapravo Eclipse? Riječ je o vrlo naprednoj razvojnoj okolini za pisanje  različitih  vrsta  aplikacija,  a  upravo  je  tu  razvojnu  okolinu  predvidio  i  Google  za  razvoj  Android  aplikacija.  Za  sada  o  njoj  samo  toliko,  a  nešto  više  detalja  o  korištenju  navest  ćemo  u  budućim  nastavcima kad nam zatrebaju različite mogućnosti razvojne okoline u pisanju aplikacija. 

Prve komplikacije  Kod trećeg koraka nastupaju komplikacije. Googleov razvojni alat nalazi se također u ZIP obliku pa  ga kao i Eclipse treba prvo otpakirati. Kao rezultat dobiva se mapa android‐sdk‐windows. Njezino  mjesto odaberite na isti način kao u prethodnom koraku.  U  ovom  slučaju  potrebno  je  napraviti  još  jednu  dodatnu  operaciju,  a  to  je  postavljanje  varijable  operativnog sustava Path, tako da pokazuje na tu mapu. I ovo bi trebao biti postupak poznat nešto  iskusnijim korisnicima Windowsa, dok one manje iskusne upućujemo na prvu prateću sliku uz tekst  koja pokazuje kako se taj postupak izvodi u hrvatskoj inačici Windowsa 7. Druga slika pokazuje istu  stvar u engleskoj inačici.  Ukratko,  treba  otvoriti  upravljačku  ploču  Windowsa  (Control  Panel)  te  u  njoj  pronaći  opciju  namijenjenu  dodatnom  podešavanju  parametara  operativnog  sustava,  kao  što  su  performanse  sustava (uključujući virtualnu memoriju), korisnički profili i slično. Na tom mjestu nalazi se gumb za  podešavanje  varijabli  okruženja  (Environment  Variables).  Nakon  otvaranja  istoimenog  dijaloškog  okvira u popisu sistemskih varijabli, treba pronaći varijablu Path te u nju uključiti putanju do mape  android‐sdk‐windows. U slici na primjeru to je napravljeno na samom početku varijable. 

Zajednički jezik  Ako je do sada sve prošlo bez problema, na računalo su instalirana sva tri osnovna alata, ali smo  još prilično daleko od pisanja prvih aplikacija. Treba napraviti još nekoliko dodatnih koraka kako bi  se  sva  tri  alata  međusobno  „razumjela“  te  tako  doista  omogućila  stvaranje  vlastitih  Android  aplikacija. Krenimo kroz novi niz koraka u konfiguriranju sustava.  Prvo treba pokrenuti Eclipse. Kod prvog pokretanja razvojne okoline bit će zatraženo da izaberemo  neku  mapu  na  disku  koja  će  u  budućnosti  služiti  kao  radni  prostor  za  druge  projekte.  Možemo  izabrati mapu poput C:\workspace, ili nešto drugo prema vlastitom nahođenju. Nakon toga otvara  se glavni prozor razvojne okoline u kojem treba izvesti sljedeći niz koraka da bi se Eclipse povezao s  Google Android sustavom.           

1. Za početak u razvojnoj okolini treba izabrati naredbu Help > Install New Software… 

    2. U dijaloškom okviru Install, koji se otvara nakon toga, treba kliknuti na gumb Add. 

 

3. Kao rezultat prethodne operacije, otvara se dijaloški okvir Add Site s okvirima Name i Location.  U  prvi  okvir  treba  upisati  nešto  što  će  označavati  o  kakvim  je  dodacima  za  Eclipse  riječ  –  na  primjer,  Android  dodaci  ili  Android  Plugin.  U  drugo  polje  (Location)  treba  upisati  sljedeći  tekst:  https://dl‐ssl.google.com/android/eclipse/ 

  4. Nakon toga treba kliknuti na gumb OK. 

 

5.  Nakon  povratka  na  prethodni  dijaloški  okvir,  trebali  biste  vidjeti  oznaku  novog  dodatka.  Na  ovom  dijaloškom  okviru  označite  okvir  Developer  Tools,  a  onda  preostaje  dva  puta  kliknuti  na  gumb Next te završiti prvi dio podešavanja radne okoline.  Napomena:  Vrijeme  koje  je  potrebno  da  razvojna  okolina  „posloži“  sve  što  treba  nakon  prvog  pritiska na gumb Next može biti prilično dugo (ovisno o brzini računala i vezi na Internet, to može  potrajati čak desetak minuta). Nemojte nikako na silu prekidati postupak, jer je sve u redu, samo  što  zbog  nekog  razloga  sve  traje  poprilično  dugo.  Na  kraju  ovog  koraka  treba  još  prihvati  uvjete  korištenje licence, a onda kliknuti na gumb Finish.  6. Sada izađite iz razvojne okoline Eclipse pa je nakon toga ponovno pokrenite. U slučaju da prije  svoga  zatvaranja  razvojna  okolina  želi  napraviti  određena  ažuriranja  vlastitih  postavki,  strpljivo  sačekajte da se dovrši i taj postupak.  7.  Nakon  ponovnog  otvaranja  razvojne  okoline,  izaberite  naredbu  izbornika  Windows  >  Preferences  kako  biste  otvorili  dijaloški  okvir  Preferences.  Na  prikazanom  popisu  u  lijevoj  strani  prozora treba pronaći vrijednost Android, a onda na desnoj strani u okvir SDK Locations upisati (ili  izabrati) putanju do Google Android SDK paketa te potvrditi odabir pomoću gumba OK. 

  8. Konačno smo stigli i do posljednjeg koraka u podešavanju, ali će on nažalost vremenski potrajati  kao  svi  prethodno  nabrojani  koraci,  počevši  od  instalacije  Sunovog  paketa.  Potrebno  je  izabrati  naredbu Windows > Android SDK and AVD Manager. Kao rezultat izvođenja prethodne operacije,  otvara se istoimeni dijaloški okvir s prikazom dostupnih te trenutno instaliranih inačica Androida.  Kako  na  početku  nije  instalirana  još  ni  jedna  inačica  paketa,  izaberite  sve  koje  želite  koristiti  u  praksi te prihvatite njihovu instalaciju pomoću gumba Install Selected. 

  Nakon  dovršetka  ovog  koraka,  vaše  računalo  konačno  je  spremno  za  razvoj  Google  Android  aplikacija  jer  su  na  njemu  svi  potrebni  sistemski  moduli,  a  što  je  najvažnije,  sada  se  konačno  i  međusobno razumiju. To možete provjeriti tako da u razvojnoj okolini  Eclipse izaberete naredbu  File  >  New  >  Project.  Nakon  toga,  u  dijaloškom  okviru  New  Project  trebali  biste  moći  započeti  Android Project, dok biste u sljedećem dijaloškom okviru New Android Project trebali moći izabrati  razvoj aplikacija u različitim inačicama Androida. 

 

Važna napomena za kraj. Ako namjeravate na vlastito računalo u koraku 8 izabrati instalaciju svih  inačica Androida, onda se trebate naoružati popriličnom dozom strpljenja. Najbolje je da potvrdu  preuzimanja  svih  inačica  „okinete“  prije  početka  nekakve  dobre  nogometne  ili  bar  rukometne  utakmice,  jer  čitav  postupak  traje  beskrajno  duuuuuugooooooo.  Ne  nije  nikakva  šala.  Baš  kad  završi utakmica lige prvaka, instalacija će biti dovršena. Na ovaj detalj upozoravamo vas zato što bi  većina  korisnika  nenavikla  na  tako  dugo  vrijeme  odziva  računala  na  zadanu  operaciju  vjerojatno  nasilno prekinula korak 8, a zapravo je sve u redu. Jednostavno nema pomoći – morate sačekati da  se postupak završi kako biste mogli početi s pisanjem vlastitih aplikacija. 

  2. Pisanje i pokretanje prvog programa    Prošli put smo u malo podužem početnom tekstu objasnili zašto pokrećemo novu školu  programiranja i koji su nam sve alati potrebni za nju, odnosno kako ih treba instalirati na računalo  da bi sve proradilo na odgovarajući način. Budući da je za razvoj Google Android aplikacija  potrebno instalirati nekoliko alata različitih proizvođača, takva instalacija nikad ne prolazi tako  glatko kao kad je riječ o instalaciji pojedinačnoga razvojnog alata samo jednog proizvođača.  Ok,  ako  ste  napravili  sve  što  smo  napisali  u  prošlom  nastavku,  sad  biste  trebali  imati  računalo  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 odgovarajućeg hardverskog uređaja, jer na kraju krajeva,  tek  u  njemu  možemo  vidjeti  rezultate  rada  našeg  programa  na  smisleni  način.  Nakon  toga  se  u  sljedećim  brojevima  možemo  pozabaviti  samim  programiranjem  i  naprednijim  programskim  tehnikama. 

 

Stvaranje projekta HelloWorld: Ovako izgleda početni dijaloški 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 nešto postane zaista neophodno. Ipak, ako ste do sad već koristili neku od modenijih razvojnih  okolina  za  razvoj  aplikacija  (a  napomenuli  smo  da  praćenje  serijala  zahtijeva  određeno  predznanje),  onda  ne  biste  trebali  imati  previše  problema  ni  sa  snalaženjem  u  razvojnoj  okolini  Eclipse.  Kao što to dobra programerska tradicija nalaže, priču o programiranju u Google Androidu započet  ćemo  od  trivijalnog  HelloWorld  primjera.  Njegova  namjena  jest  pokazati  kako  se  u  novom  razvojnom  okruženju  prikazuje  jednostavna  poruka  korisniku  programa.  Za  mlađe  (ili  starije)  čitatelje  koji  možda  upravo  sada  prvi  put  započinju  avanturu  programiranja  u  nekom  programskom  jeziku,  treba  napisati  samo  kratko  objašnjenje  zašto  se  u  gotovo  svakoj  školi  programiranja  započinje  s  tako  trivijalnim  primjerom  budući  da  on  sam  za  sebe  zapravo  ne  radi  ništa korisno. Ideja u pripremi tako jednostavnog primjera jest u tome da se programer što brže  upozna s novim programskim jezikom, ali i njegovim razvojnim okruženjem, kako bi se nakon toga  što brže moglo prijeći na složenije probleme.  Za pisanje novog programa potrebno je u razvojnoj okolini Eclipse izabrati naredbu File > New >  Project  te  u  dijaloškom  okviru  prikazanom  u  nastavku  odabrati  odgovarajuću  vrstu  projekta.  U  ovom  slučaju  to  je  Android  Project.  Kao  rezultat  izvođenja  prethodne  operacije,  pojavljuje  se  dijaloški  okvir  New  Android  Project  gdje  se  od  programera  očekuje  upisivanje  nekoliko  polaznih  podataka o vlastitom projektu.  Project  Name  predstavlja  naziv  projekta  na  kojem  trenutno  radimo.  U  ovom  slučaju,  to  će  biti  HelloWorld.  Osim  naziva  projekta,  potrebno  je  izabrati  mjesto  na  disku  za  spremanje  njegovih  sastavnih  dijelova.  To  može  biti  podrazumijevana  radna  površina  definirana  prilikom  prvog  pokretanja  radne  okoline,  neko  točno  određeno  mjesto  na  disku,  ili  se  u  razvoj  projekta  može  krenuti od već postojećeg projekta – recimo nekog od pratećih primjera Google Android projekata.  Za  sada  na  ovom  mjestu  možemo  ostaviti  podrazumijevane  vrijednosti,  dakle  –  uključene  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 slučaju da je na računalo instalirano više inačica razvojnih paketa Google Android SDK, potrebno  je izabrati jedan od njih, nakog čega će se odgovarajuća oznaka inačice pojaviti u okviru Min SDK  Version na dnu dijaloškog 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 može 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 međusobno odvojena točkom – na  primjer  helloWorld.java  (prema  uobičajenim  konvencijama  prvo  slovo  treba  biti  malo).  U  okvir  Create  Activity  treba  upisati  naziv  prve  aktivnosti  u  Google  Android  projektu  –  na  primjer  helloWorld.  Sada  je  moguće  kliknuti  na  gumb  Next  te  tako  prijeći  na  sljedeći  dijaloški  okvir  namijenjen  za  stvaranje odgovarajućega pomoćnog projekta za testiranje. Projekti za testiranje namijenjeni su za  pojednostavljeno ponavljanje testiranja vrlo složenih Google Android projekta (kakav HelloWorld  zasigurno nije), ali ćemo na ipak kreirati takav projekt kako bismo se upoznali i s tom mogućnošću  razvojnog alata. Na ovom mjestu mogu se ostaviti sve predložene vrijednosti što za posljedicu ima  stvaranje projekta HelloWorldTest. Nakon izvođenja svih prethodno nabrojenih operacija, u radnoj  površini  na  disku  stvara  se  čitava  „hrpa“  datoteka,  a  sadržaj  svake  od  njih  može  se  vidjeti  u  odgovarajućem prozoru radne okoline. Za jednostavnije snalaženje najbolje je koristi hijerarhijski  prikaz dijelova projekta u posebnom prozoru na lijevom dijelu razvojne okoline (Navigator). 

  Upravljanje  virtualnim  uređajima:  Omogućuje  testiranje  projekta  na  različitim  emulacijama  hardverskih karakteristika. 

Budući  da  je  razvojna  okolina  automatski  pripremila  čitav  niz  datoteka,  prva  ideja  koja  nam  svakako  mora  pasti  na  pamet  isprobavanje  je  nastale  situacije.  Najjednostavniji  način  za  to  jest  odabir  naredbe  Run  As  >  Android  Application  iz  padajućeg  izbornika  povezanog  s  projektom  HelloWorld.  Podrazumijeva  se  da  se  ista  naredba  može  izvesti  na  bar  još  nekoliko  načina  kao  u  svim  modernim  razvojnim  okolinama  –  na  primjer  odabirom  istoimene  naredbe  iz  glavnog  izbornika ili odgovarajuće ikone na alatnoj traci prozora. Na taj detalj više se nećemo vraćati ni u  ovom  ni  u  budućim  tekstovima,  nego  istraživanje  alternativnih  mogućnosti  ostavljamo  samim  čitateljima.  Budući  da  je  cijeli  Android  sustav  namijenjen  razvoju  aplikacija  za  prijenosne  mobilne  uređaje,  razumljivo je da se aplikacija ne može izvesti „u zraku“, nego nam je za to potreban nekakav uređaj  za  njezino  izvođenje  –  ako  ništa  drugo,  onda  bar  u  obliku  softverske  emulacije.  Takav  softverski  „stroj“ naziva se Android Virtual Device ili skraćeno AWD. Ako nekakva konfiguracija emulatora već  ne  postoji  od  prije,  treba  je  pripremiti  prema  konkretnim  potrebama  za  testiranje  vlastite  aplikacije.  Za  upravljanje  virtualnim  uređajima  koristi  se  dijaloški  okvir  Android  SDK  and  AVD  Manager, što uključuje operacije poput stvaranja uređaja, njegovog brisanja, ispravljanja te možda  najvažnije, pokretanja uređaja. Ključni hardverski parametri koji se mogu definirati kod stvaranja  novoga virtualnog stroja jesu količina raspoložive radne memorije te rezolucija zaslona.  Nakon  stvaranja  novoga  virtualnog  uređaja,  u  njega  je  moguće  učitati,  a  nakon  toga  i  isprobati  vlastitu aplikaciju. Budući da za sada naša aplikacija predstavlja samo goli kostur aplikacije te kao  takva zapravo ne radi ništa pametno, ni u virtualnom uređaju nema se mnogo toga za vidjeti osim  osnovne  poruke  korisniku  programa.  U  slučaju  da  se  tekst  iz  aplikacije  ne  prikaže  automatski  u  virtualnom uređaju, kliknite na gumb Menu prikazan na prozoru virtualnog uređaja.  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 smještenu 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  sličan  način,  otvaranjem  datoteke  main.xls  smještene  u  mapi  res/layout,  može  se  oblikovati  grafičko  sučelje  aplikacije  na  način  vrlo  sličan  izvođenju  odgovarajućih  postupaka  u  drugim  modernim  razvojnim  okolinama  –  na  primjer  Microsoft  Visual  Studio.  Kao  osnovnu  vježbu  u  korištenju  razvojne  okoline,  probajte  u  vlastitu  aplikaciju  dodati  jedan  gumb  te  mu  eventualno  podesiti neka od svojstava za određivanje izgleda u prozoru Properties. 

  Virtualni  uređaj  u  akciji:  Stvarni  izgled  ovisi  o  parametrima  definiranim  prilikom  njegovog  stvaranja. 

  Vizualna priprema sučelja aplikacije: Izvodi se u posebnom prozoru radne okoline. 

Spomenimo  na  ovom  mjestu  kako  se  čitava  operacija  prevođenja  izvornoga  koda,  pokretanja  virtualnog uređaja te učitavanja prevedenog programa u uređaj može opisati svakako, ali sigurno  ne  pojmom  „brza  operacija“,  bez  obzira  na  snagu  računala.  Ako  ste  već  ranije  probali  slične  kombinacije  razvojnih  alata  i  emulatora  drugih  proizvođača,  onda  sigurno  niste  iznenađeni  prethodnom  tvrdnjom,  jer  ste  na  to  već  jednostavno  navikli.  Dobra  vijest  je  da  je  vrijeme  učitavanja  nove  inačice  aplikacije  u  već  pokrenuti  virtualni  uređaj  bitno  kraće,  što  znači  da  je  isprobavanje  vlastite  aplikacije  nakon  manjih  promjena  izvornoga  koda  ipak  prilično  bezbolan  proces.  Spomenimo na kraju današnjeg predstavljanja početnih koraka u razvoju Android aplikacija, jer se  dovršena  i  testirana  Android  aplikacija  može  pripremiti  za  distribuciju  u  obliku  datoteke  s  nastavkom  .apk.  Riječ  je  o  komprimiranoj  datoteci  sastavljenoj  od  većeg  broja  datoteka  koje  sadrže  sve  potrebne  informacije  za  izvođenje  aplikacije  na  uređaju  s  ugrađenom  podrškom  za  Google  Android.  Kad  završite  ovu  školu  i  napišete  prve  kvalitetne  aplikacije,  prruža  vam  se  mogućnost  da  ponešto  i  zaradite  putem  online  trgovine  Google  Android  aplikacija,  koja  svakodnevno dobiva sve veći broj naslova od programera širom svijeta.   

3. Interakcija sa korisnikom    Drugi  nastavak  nove  škole  programiranja  u  razvojnom  alatu  Google  Android  bio  je  namijenjen  izradi „klasične aplikacije“ u svim školama programiranja – općepoznatog primjera HelloWorld. Cilj  projekta bio je brzo upoznavanje dijelova razvojne okoline potrebnih za izradu vlastitih aplikacija,  dok  o  samom  programiranju  nije  bilo  rečeno  baš  mnogo.  U  biti,  u  prošlom  tekstu  samo  smo  isprobali  ono  što  je  automatski  pripremila  razvojna  okolina.  Ovaj  put  idemo  korak  dalje  pa  počinjemo u početnu aplikaciju dodavati prve objekte, a nakon toga i programski kod za njihovu  reakciju  na  događaje  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  počnemo  „zaozbiljno“,  dopustite  da  se  osvrnemo  na  bitan  tehnički  detalj.  Moderna  razvojna okolina kao što je Eclipse ima čitav niz prozora za definiranje različitih dijelova projekta,  pa  se  početniku  nije  baš  uvijek  lako  snaći  sa  svim  tim  dijelovima,  posebno  ako  je  neki  od  bitnih  prozora zatvoren ili premješten s podrazumijevanog mjesta slučajno ili namjerno. Kako bi olakšao  praćenje teksta, autor se trudi da priložene slike uz tekst uvijek pokazuju bitne dijelove. Problem  nastaje kad se zbog ovog ili onog razloga (najčešće nedostatka prostora u časopisu), neka od slika  mora izostaviti, ili se smanji tako  da je teško  razaznati neke dijelove.  Zato ćemo (bar u početku)  stalno navoditi ne samo što treba napraviti da bi se dovršila neka operacija nego i kako se zapravo  stiže do tog mjesta.  Navedimo  prvo  što  želimo  postići  u  današnjem  i  sljedećem  nastavku.  U  osnovni  projekt,  HelloWorld, iz prošlog 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 početnom vrijednošću, a pritisak mišem na bilo koji od  dodatna  dva  gumba  izaziva  zamjenu  početnog  sadržaja  drugačijim  tekstom.  Dakle,  ništa  spektakularno  u  smislu  izvođenja  programa,  ali  i  tako  jednostavan  primjer  demonstrira  različite  načine korištenja Google Android sustava u razvoju aplikacija za mobilne uređaje. 

    Rad  na  proširenju  početnog  HelloWorld  projekta  započinjemo  otvaranjem  datoteke  main.xml  u  prozoru  radne  okoline,  pod  nazivom  Android  Layout  Editor,  jer  je  on  namijenjen  grafičkom  uređivanju izgleda vlastite aplikacije. Naravno, budući da je u osnovi riječ o običnoj .xml datoteci,  možemo  je  otvoriti  i  u  nekom  od  tekstualno  orijentiranih  prozora,  ali  se  to  baš  ne  preporučuje  početniku. Na ovom mjestu postoji velik stupanj analogije sa stvaranjem HTML dokumenata (što je  vjerojatno  poznato  bar  dijelu  čitatelja).  HTML  dokument  možemo  stvoriti  izravnim  upisivanjem  sastavnih  dijelova  u  tekstualnom  obliku  (teži  način),  ili  njihovim  „crtanjem“  u  odgovarajućem  grafički  orijentiranom  alatu  (lakši  način).  Za  sada  ćemo  i  u  razvojnoj  okolini  Eclipse  izabrati  lakši  način izrade korisničkog sučelja, a kad postanete iskusniji, možete koristiti oba načina. Spomenimo  na  ovom  mjestu  namjenu  prozora  Outline,  koji  zapravo  predstavlja  „nešto  između“.  U  njemu  je  vidljiv  samo  popis  osnovnih  dijelova  od  kojih  se  sastoji  korisničko  sučelje  aplikacije,  kao  i  njihov  međusobni  odnos,  ali  ne  i  drugi  detalji  za  određivanje  izgleda.  Korisničko  sučelje  aplikacije  iz  prošlog nastavka bilo je sastavljeno od svega dva dijela: LinearLayout i TextView. Prvi dio pripada  grupi  objekata  namijenjenih  određivanju  međusobnog  rasporeda  osnovnih  objekata  koji  čine  korisničko sučelje (u terminologiji Google Androida to su layouts objekti). U današnjem nastavku  nećemo  se  detaljnije  baviti  ovim  dijelom  oblikovanja  korisničkog  sučelja,  nego  to  ostavljano  za  buduće  nastavke  serijala.  Za  sada  spomenimo  samo  da  je  tijekom  inicijalne  pripreme  projekta  uporabljen prilično 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  običan  prikaz  pozdravne  poruke.  U  terminologiji  Google  Androida,  takvi  objekti  s  vlastitim  vizualnim  izgledom,  namijenjeni  izgradnji  različitih  dijelova  korisničkog  sučelja  za  interakciju  s  korisnikom  aplikacije – nazivaju se widgets. 

    Već smo spomenuli da ćemo u korisničko sučelje dodati još tri dijela pa sad prelazimo na izvođenje  odgovarajućih  operacija.  Iz  prozora  Views  treba  redom  povući  tri  objekta  na  dio  koji  prikazuje  grafičku reprezentaciju aplikacije (objekt LinearLayout). Jednom to treba napraviti s objektom tipa  EditText, a dva puta s objektom tipa Button. O samom mjestu „ispuštanja“ objekta ne treba voditi  previše računa, jer se pozicioniranje nacrtanih objekata ionako izvodi automatski zbog korištenja  vrlo  jednostavnog  načina  raspoređivanja  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  inačicu  Microsoftove  razvojne okoline, bit će vam potpuno jasno što se je dogodilo u prethodnom koraku.  Isto  tako,  prepoznat  ćete  način  za  pregled  i  izmjenu  podrazumijevanih  vrijednosti  svojstava  aktivnog objekta. Za to se koristi prozor Properties, a u njemu treba jednostavno pronaći svojstvo  čiji sadržaj 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  označiti  LinearLayout,  a  kao  vrijednost  svojstva  Background  upisati  vrijednost  #FFFFFF.  Na  sličan način možemo gumbima Button01 i Button02 izmijeniti početni tekst na vrijednost Prihvati  odnosno  Odbaci,  tako  da  za  svaki  gumb  izvedemo  korekciju  vrijednosti  svojstva  Text.  Objektu  EditText01 također izmijenimo vrijednost svojstva Layout width na unaprijed definiranu vrijednost  fill_parent,  kako  bi  se  objekt  proširio  na  punu  širinu.  Za  vježbu,  možete  promijeniti  početnu  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  služe  druga  dostupna  svojstva  tako  da  im  izmijene početnu vrijednosti, a mi ćemo u sljedećim nastavcima serijala objašnjavati neka od njih  kad  nam  zatrebaju.  Objasnimo  na  ovom  mjestu  nešto  zaobilazniji  način  za  izmjenu  vrijednosti  svojstava. Vrijednost #FFFFFF na prvi, drugi pa čak i treći pogled početniku ne odaje da je riječ o  bijeloj boji, a priznat ćete da ni iskusnijima nije baš lako pamtiti slične vrijednosti, ako ih ne koriste  svakodnevno.  Postoji  li  način  da  se  takve  vrijednosti  koriste  na  „humaniji“  način?  Srećom,  da,  a  odgovarajući postupak opisujemo u nastavku teksta.  U hijerarhijskom pregledu dijelova projekta (prozor Navigator) treba pronaći i otvoriti datoteku res  \  values  \  strings.xml.  U  ovoj  datoteci  nalaze  se  definicije  resursa  uporabljenih  na  različitim  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  dijaloški  okvir  za  odabir  kategorije resursa. U njemu sasvim logično treba izabrati kategoriju Color, iako se potpuno sličan  postupak primjenjuje za druge vrste  resursa.  Preostaje  još samo  da  se kao  naziv  resursa  (Name)  upiše vrijednost BijelaBoja, a kao njegova vrijednost (Value) #FFFFFF. Naravno, nemojte zaboraviti  ni na spremanje nove vrijednosti resursa pomoću ikone diskete na alatnoj traci razvojne okoline.  Ako  sada  zatvorimo  datoteku  strings.xml,  vraćamo  se  ponovno  na  grafičku  reprezentaciju  korisničkog  sučelja.  Ponovno  kao  aktivni  objekt  izaberimo  LinearLayout  te  pronađimo  svojstvo  Background.  Nakon  klika  na  gumb  s  tri  točke  na  samom  desnom  kraju  reda,  otvara  se  dijaloški  okvir Reference Chooser. U njemu možemo pronaći 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  način  od  upisa  heksadecimalnoga  koda  iste  boje.  Na  sličan  način  možemo definirati druge vrijednosti koje namjeravamo uporabiti u različitim dijelovima programa.  Za  kraj  današnjeg  nastavka,  otvorimo  ponovno  datoteku  main.xml,  ali  sada  u  običnome  tekstualnom editoru. Dobit ćemo nešto poput: 

             

  Sve ono što smo ranije dobili grafičkim oblikovanjem sučelja u nekoliko prozora razvojne okoline,  ovdje  je  prikazano  u  običnom  XML  formatu  zapisa.  Iskusniji  programeri  mogu  na  ovom  mjestu  izravno  izvoditi  promjene,  pa  čak  i  dodavanje  novih  objekata  na  sučelje.  Na  primjer,  probajte  jednostavno umnožiti dio teksta namijenjen definiranju gumba Button02 pa ćete dobiti još jedan  identičan gumb na korisničkom sučelju. 

Primijetimo  na  kraju  današnjeg  nastavka  da  u  XML  opisu  oba  gumba  postoji  veza  prema  programskom kodu za obradu događaja onClick, jer je autor teksta to već pripremio u primjeru, ali  zbog  zadane  veličine  svakog  pojedinog  nastavka  serijala,  o  tome  će  nešto  više  riječi  biti  u  sljedećem broju.   

4. Uvod u pisanje programskog koda    U  prošlom,  trećem  nastavku  škole  Google  Android  programiranja,  u  početnu  inačicu  aplikacije  HelloWorld dodali smo nekoliko osnovnih grafičkih objekata, te usput objasnili više bitnih dijelova  razvojne  okoline  Eclipse,  povezanih  s  postavljanjem  i  pregledom  grafičkih  objekata  korištenih  u  aplikaciji, odnosno pripremom i izmjenom njihovih svojstava. Međutim, tako dugo dok nacrtanim  objektima ne dodamo nekakav programski kod, oni u aplikaciji služe manje‐više samo kao ukras,  pa  kao  takvi  ne  rade  ništa  pametno.  Tek  kada  se  objektima  pridruže  odgovarajuće  funkcije  za  reakciju objekta na „podražaj“ iz okoline (recimo pritisak na objekt od strane korisnika aplikacije  na zaslonu uređaja), počinje se doista nešto događati.  Vratimo  se  na  trenutak  ponovno  na  tekstualni  prikaz  dijela  datoteke main.xml,  zadužene  za  definiranje  izgleda  objekata  u  aplikaciji,  ali  istovremeno  i  za  povezivanje  nacrtanih  objekata  s  dijelovima programskoga koda. Usredotočimo se u nastavku na sljedeće dijelove datoteke:    …      … 

  Povezivanje  objekata  s  programskim  kodom:  Izvedivo  je  izravnim  uređivanjem  tekstualnog  sadržaja datoteke Main.xml.  Dijelovi označeni istaknutim pismom zaduženi su za povezivanje oba „nacrtana“ gumba u sučelju s  odgovarajućom  funkcijom  u  programskom  kodu  –  u  ovom  slučaju  ona  je  zadužena  za  obradu  događaja izazvanog pritiskom korisnika na kontrolu. Da odmah razjasnimo jednu vrlo bitnu stvar  (kako se čitatelji ne bi našli u svojevrsnoj konfuziji pri praćenju teksta), iako smo je već spomenuli  na kraju prethodnog nastavka. Ako se pozorno pratili tekst iz prošlog broja te pokušali ponoviti sve  opisane  operacije,  onda  u  vašem  projektu  trenutno nema navedenih  dijelova.  U  projektu  autora  teksta  ti  dijelovi  postoje,  jer  je  primjer  prvo  napravljen  do  kraja,  a  tek  onda  je  započeto  pisanje  teksta. Odatle dolazi do istaknute razlike između projekata, ali ćemo odmah poduzeti sve potrebne  operacije da ih uklonimo.  Na koji način u vlastite projekte možete dodati dio koji nedostaje? Jedan od načina izravni je upis  prije  označenoga  teksta  u  prozoru  zaduženom  za  tekstualni  prikaz  sadržaja  datoteke  main.xml.  Drugi način korištenje je prozora Properties, nakon što željeni objekt postane aktivan objekt (vidi  priloženu sliku uz tekst). U našem primjeru oba objekta povezana su s istim dijelom programskog  koda,  jer  se  u  njemu  na  jedinstven  način  prvo  provjerava  objekt  na  koji  je  korisnik  programa  napravio  pritisak.  Moguće  je  napraviti  i  drugačije  rješenje.  Svaki  gumb  može  biti  povezan  s  posebnom funkcijom za obradu događaja. Na autoru programa je odlučiti što je najbolje izabrati u  određenoj situaciji.  Pripadajući  programski  kod  primjera  u  ovom  trenutku  ima  sljedeći  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 uočiti tri glavna dijela. Prvo je naveden čitav niz import naredaba  kako bi se u vlastiti program uključili svi potrebni dijelovi za izvođenje aplikacije. Pomoću dijela:  public void onCreate(Bundle savedInstanceState) {  započinje  drugi  dio,  odnosno  izvođenje  glavnog  dijela  programa.  U  njemu  se,  osim  inicijalizacije  same  aplikacije,  postavlja  početna  vrijednost  tekstualnog  sadržaja  za  trenutno  jedini  objekt  u  aplikaciji  zadužen  za  prikaz  odnosno  unos  teksta  (EditText01).  Za  to  su  zadužene  naredbe  za  njegovo  „pronalaženje“  među  postojećim  objektima,  a  nakon  toga  za  postavljanje  početne  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 zajednički  dio programskoga koda za obradu događaja. 

  Alternativni način povezivanja: Korištenje prozora Properties u razvojnoj okolini Eclipse.  Pomoću naredbe switch provjerava se o kojem je gumbu doista riječ, a onda se izvodi jedan od dva  moguća nastavka. Svaki od njih izaziva prikaz drugačije poruke u prije spomenutomu tekstualnom  okviru.  Ako  je  sve  napravljeno  precizno,  prema  uputama  iz  ovog  i  prethodnog  nastavka  serijala,  tijekom izvođenja programa trebali biste dobiti identično ponašanje programa kao na slikama uz  tekst. 

Pokupajmo sada u svrhu svojevrsne vježbe opisati sve potrebne izmjene kako bi u programskom  kodu  primjera  svaki  gumb  imao  vlastitu  proceduru  za  obradu  događaja.  U  praksi  je  to  zapravo  češće  rješenje  zbog  velike  razlike  između  namjene  pojedinih  gumba  u  aplikaciji.  Postojeći  programski kod primjera helloWorld.java u tom slučaju treba izmijeniti u sljedeći 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”); 

}  } 

  Početni izgled prozora: Nakon pokretanja programa pojavljuje se početna poruka.  Budući da zajednička funkcija za obradu događaja nakon pritiska na gumb više ne postoji, nego je  zamijenjena s dvije pojedinačne funkcije, treba korigirati veze između oba gumba i pripadajućega  programskoga  koda.  To  se  ponovno  može  napraviti  izmjenom  svojstva On  click u  prozoru Properties te  upisivanjem  vrijednosti myClickButton1, odnosno myClickButton2.  Klikom  na gumb na krajnjoj desnoj strani toga reda može se prikazati i dijaloški okvir za odabir postojećih  dijelova programskoga koda. Alternativni način za izvođenje iste operacije (nešto brži, ali zahtijeva  veću preciznost u pisanju) izravna je izmjena tekstualnog sadržaja datoteke main.xml. U konačnici,  bez obzira na uporabljeni način izmjene vrijednosti, u toj datoteci treba biti sljedeći sadržaj.    …     

…  Ovime je dovršen početni niz tekstova o razvoju aplikacija pomoću Google Android platforme. Ako  ste pozorno pratili sve što je do sada napisano o ovoj temi, sada biste na vlastitom računalu trebali  imati  pravilno  instaliran  razvojni  sustav,  a  ujedno  biste  ga  trebali  poznavati  do  razine  korištenja  koja  omogućuje  praćenje  i  upis  primjera  iz  sljedećih  nastavaka  serijala.  Kao  i  obično  u  školama  programiranja,  praćenje  tekstova  olakšat  ćemo  izdavanjem  pratećih  primjera  na  digitalnomu  mediju uz časopis.  Što  ćemo  raditi  u  budućim  nastavcima?  Zbog  relativne  ograničenosti  prostora  za  ovaj  serijal  u  časopisu,  škola programiranja u razvojnom alatu Google 

  Izgled prozora nakon klika na prvi gumb: Početna poruka zamjenjuje se novom porukom.  Android  dalje  će  izgledati  nešto  drugačije  nego  što  je  to  bio  slučaj  s  prethodnim  sličnim  materijalima  istog  autora.  To  znači  da  nećemo  obrađivati  segment  po  segment  programskoga  jezika  ni  pratećih  biblioteka  funkcija,  a  onda  izmišljati  odgovarajući  primjer  za  njihovu  demonstraciju, nego ćemo raditi upravo obrnutim redoslijedom. Prvo ćemo napraviti jedan ili više  složenijih primjera namijenjenih demonstraciji različitih mogućnosti Google Android platforme, a  onda objasniti što rade ključni dijelovi primjera. Kao što smo istaknuli na samom početku serijala,  za  praćenje  tako  koncipiranih  nastavaka  očekuje  se  određeno  predznanje  u  smislu  poznavanja  osnovnih  pojmova  uobičajenih  u  programerskom  žargonu,  poput  varijable,  petlje  ili  procedure.  Drugim riječima, to bi trebalo značiti da već posjedujete osnovno praktično znanje programiranja u  nekom drugom razvojnom alatu.  U međuvremenu, dok čekate sljedeći bitno kompliciraniji nastavak serijala, možete sami pokušati  dodati u projekt nekoliko novih gumba ili drugačijih vrsta kontrola, a onda ih povezati s osnovnim  događajem na korisničkom sučelju (On click). 

5. Korištenje rasporeda kontrola u složenim aplikacijama    Nakon što smo prošli put „dotjerali do kraja“ s nešto složenijim Android projektom u kojem je bilo  i   malo  više  programskog  koda,  došao  je  trenutak  da  se  detaljnije  pozabavimo  najvažnijim  dijelovima  razvojnog  alata,  kako  bi  u  slijedećim  nastavcima  mogli  izrađivati  ozbiljnije  aplikacije.  Jedna  od  tipičnih  karakteristika  svake  složenije  aplikacije,  bez  obzira  na  softversku  platformu  na  kojoj  se  izvodi,  je  postojanje  većeg  broja  prozora,  formi  ili  zaslona  (već  prema  terminologiji  uobičajenoj za tu razvojnu platformu) u okviru iste aplikacije. Ni Android aplikacije po tom pitanju  nisu nikakav izuzetak.  U dosadašnja 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  previše  obazirali  na  karakteristike  korištenog  rasporeda  kontrola,  nego smo jednostavno po njemu postavili ostale objekte korištene u aplikaciji (dva gumba i jedan  okvir  za  unos  teksta).  Glavna  tema  današnjeg  teksta  posvećena  je  upravo  različitim  vrstama  rasporeda  osnovnih  kontrola  dostupnim  u  okviru  Android   platforme,  što  uključuje  opisivanje  njihovih mogućnosti i načina korištenja.  U okviru Google Android platforme dostupne su slijedeće vrste rasporeda osnovnih objekata:  1. 2. 3. 4. 5. 6.

LinearLayout  AbsoluteLayout  TableLayout  RelativeLayout  FrameLayout  ScrollView 

 

Početni  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  korištenim  u  tekstu.  U  originalnoj  terminologiji  osnovni  objekti  (npr.  gumb,  okvir  za  tekst  i  slično)  nazivaju  se Widget,  a  kad  su  vidljivi  na  zaslonu View.  Pojmom ViewGroup (u  osnovi  također  posebnoj  vrsti  pogleda)  označava  se  skupina  osnovnih  „Viewa“ razmještena po zaslonu u određenom 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 riječi objekt ili kontrola, dok će ViewGroup biti zamijenjen s pogled ili  raspored kontrola. To možda nije najbolje moguće rješenje prijevoda, ali s druge strane predstavlja  vrlo čestu terminologiju korištenu u opisu drugih razvojnih alata. Ako ste već koristili neki od njih,  bez problema ćete pratiti rečenice u tekstu kojeg upravo čitate.  Vratimo  se  sada  na  glavnu  temu  današnjeg  teksta  –  korištenje  različitih  rasporeda  osnovnih  kontrola u vlastitim aplikacijama. Obavimo to istim redom kao u ranijem nabrajanju.  LinearLayout predstavlja osnovni raspored kontrola gdje su sve osnovne kontrole raspoređene 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  predložen  od  strane  razvojne  okoline  tijekom  stvaranja  projekta. Iako za složenije aplikacije ovakav raspored osnovnih kontrola nije uvijek i najpogodnije  rješenje, kod početnih koraka u novom razvojnom alatu zapravo nema nekih prevelikih zamjerki na  njegovo korištenje.  Kod drugog od spomenutih rasporeda kontrola AbsoluteLayout programer nije ograničen na neki  od podrazumijevanih oblika „redanja“ osnovnih kontrola po pozadini, nego ima potpunu slobodu u  njihovom postavljanju  na dostupnom području. O samim svojstvima  potrebnim za pozicioniranje  svake pojedine kontrole na ovakvoj vrsti pogleda odnosno rasporeda, bit će više riječi slijedeći put.  Raspored  kontrola  pod  nazivom TableLayout,  kao  što  to  sam  naziv  govori,  koristi  se  kod  razvrstavanja osnovnih  kontrola u više redova ili stupaca tablice, odnosno u čelije tablice. Na taj  način  mogu  se  dobiti  „lijepi“  pravilni  rasporedi  osnovnih  kontrola  na  pogledu,  što  se  vrlo  često  koristi kod različitih vrsta unosa podataka u aplikacijama.  U RelativeLayout rasporedu kontrole se mogu postaviti na različita mjesta na dostupnom prostoru  za  njihovo  prikazivanje,  ali  točno  mjesto  svake  kontrole  nije  određeno  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 prikaže slikom u nekoj od budućih aplikacija.  Zadnja vrsta rasporeda osnovnih kontrola pod nazivom ScrollView koristi se u slučajevima kad na  fizičkim dimenzijama zaslona jednostavno nije moguće prikazati sve potrebne osnovne kontrole na  smislen  i  pregledan  način  (bez  međusobnog  preklapanja  i  jasnog  razdvajanja).  Pogled  ScrollView  zapravo  predstavlja  posebnu  vrstu  rasporeda  FrameLayout  na  koju  se  u  praksi  obično  postavlja  dodatna vrsta osnovnog rasporeda kontrola (RelativeLayout). 

U  okviru  jedne  složene  aplikacije  može  se  koristiti  veći  broj  istih  ili  različitih  vrsta  rasporeda  kontrola, između kojih se prebacivanje, to jest aktiviranje nekog drugog rasporeda, izvodi pomoću  programskog  koda.  Pogledajmo  sada  kako  korištenja  različitih  rasporeda  izgleda  na  nekoliko  primjera.  Osnovni  raspored  kontrola  iz  dovršenog  primjera  u  prethodnom  nastavku,  koji  je  koristio  podrazumijevani raspored LinearLayout imao je slijedeći XML oblika zapisa.                     

  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. Budući da to još uvijek nismo napravili,  uzete su podrazumijevene vrijednosti 0, što je izazvalo spomenuto skupljanje kontrola.  Navođenjem  apsolutnih  vrijednosti  za  poziciju  i  veličinu  kontrola  dolazi  do  njihovog  željenog  formatiranja, kao što to pokazuje prateća slika uz tekst.                     

  Raspored  kontrola  AbsoluteLayout:  Za  svaku  kontrolu  su  navedene  apsolutne  vrijednosti  za  određivanje izgleda.  Zamjenom  apsolutnog  rasporeda  kontrola  relativnim  u  okviru  XML  definicije  više  nije  potrebno  navoditi apsolutne vrijednosti pozicija kontrola, nego samo njihovu relativnu poziciju u odnosu na  neku  drugu  kontrolu.  Apsolutne  vrijednosti  zadužene  za  definiranje  veličine  kontrole  mogu  se  koristiti i dalje na isti način.  Na  temelju  slijedećeg  XML  sadržaja,  pomoću  relativnog  rasporeda  kontrola  oponašan  je  početni  raspored kontrola LinearLayout.                      U  prethodna  tri  primjera  korišteno  je  nekoliko  dodatnih  elemenata  za  definiranje  rasporeda  osnovnih kontrola u okviru osvnovne XML datoteke za 

  Raspored kontrola RelativeLayout: U ovom slučaju je oponašan osnovni raspored LinearLayout.  definiranje izgleda zaslona. Nešto više riječi o njihovoj namjeni možete pročitati u slijedećem  broju.     

6. Korištenje osnovnih Android kontrola    Nakon  što  smo  raspravili  što  su  to  zapravo  rasporedi  osnovnih  kontrola,  u  današnjem  nastavku  uvoda u Android programiranje možemo prijeći na drugi bitan preduvjet izrade korisničkog sučelja,  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 prošlom nastavku), gdje se  korisničko sučelje u potpunosti stvara programskim kodom.  Drugim  riječima,  ako  je  programeru  iz  nekog  razloga  tako  zgodnije,  ne  mora  prvo  „crtati“  korisničko sučelje u odgovarajućem prozoru razvojne okoline, a onda dodavati programski kod da  „oživi“  nacrtane  kontrole,  nego  sve  to  može  napraviti  u  jednom  prolazu  isključivo  programskim  kodom. Ako ste već u prošlosti koristili Microsoft Visual Studio, onda će vam sve biti mnogo jasnije  kad napišemo da je riječ o postupku analognom dinamičkom dodavanju kontrola na formu tijekom  izvođenja 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_PARENT,  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  pomoću  programskog  koda:  Ne  treba  uvijek  prvo  nacrtati kontrole u razvojnoj okolini.  Prethodni  programski  primjer  tijekom  svojeg  izvođenja  stvara  osnovni  raspored  kontrola  pod  nazivom podloga,  a  onda  na  njega  dodaje  tekstualne  kontrole  za  prikaz  imena  i  adrese.  Sličan  postupak se može primijeniti za sve vrste kontrola. Ako ne volite prekucavati primjere, možete ga  pronaći na pratećem 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  pronaći  dosta  sličnosti,  a  ako  niste,  onda  svakako  pogledajte  tekst  u  nastavku  te  sami  pokušajte  napraviti  nekoliko  vlastitih  primjera  s  takvim  kontrolama. Kontrole ćemo u nastavku prikazati prema učestalosti u aplikacijama – dakle prvo one  koje se najčešće koriste. 

TextView  Kontrola  tipa  TextView namijenjena  je  prikazu  različitih  vrsta  tekstova  na  zaslonu,  ali  bez  mogućnosti  njihove  izmjene  odnosno  uređivanja.  Zato  se  ova  vrsta  kontrole  u  vlastitim  aplikacijama  najčešće  koristi  za  prikaz  informacija  korisniku  poput  dodatnih  opisa  uz  glavne  kontrole koje omogućavaju uređivanje teksta. Međutim, ako dio prikazanog teksta predstavlja web  adresa, onda se kontrola može upotrijebiti znatno kreativnije, tako da klik mišem na web adresu  otvara preglednik te prikazuje njezin sadržaj (vidi primjer slike uz tekst). 

Da  bi  demonstrirali  takvo  ponašanje  kontrole  TextView  u  prethodnom  programskom  primjeru  treba napraviti dvije izmjene. Prvo, treba u aplikaciju uključiti posebnu klasu za pronalaženje 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 sadržaj uključuje 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  prateća  slika  uz  tekst,  u  sadržaju  kontrole  pojavljuje  se  posebno  istaknuta  web  adresa,  a  klik  na  adresu  otvara  njezin  sadržaj  u  podrazumijevanom pregledniku. 

EditText  Ako je korisniku potrebno omogućiti da u programu upiše odnosno da uredi postojeći tekstualni  sadržaj, onda umjesto kontrole tipa TextView treba 

  Korištenje kontrole TextView: Omogućava i otvaranje sadržaja zadane web adrese.  koristiti  kontrolu  tipa  EditText.  Treba  istaknuti  kako  ni  ova  vrsta  kontrole  nije  zamišljena  za  upis  velikih tekstova, nego prije svega kraćih podataka kakvi se obično zapisuju u pojedine stupce baze  podataka.  Kontrola  EditText  posjeduje  brojna  dodatna  svojstva  čijom  promjenom  vrijednosti  se  može bitno izmijeniti ponašanje kontrole, prije svega način prikaza teksta. Na primjer:  Auto text – automatski ispravlja moguće pogreške tijekom upisa teksta  Capitalize – pretvara upisana slova u velika slova  Numeric – postavlja brojčani 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  Slijedeći primjer pokazuje dinamičko dodavanje tekstualne kontrole na osnovni raspored kontrola  uz korištenje 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 korištenja 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 korištenja kontrole EditText */  EditText txtKorisnik = new EditText(this);  txtKorisnik.setText (“Upišite korisničko ime”);  txtKorisnik.setHint(“Pazite na upis malih i velikih slova”);  txtKorisnik.setError(“Pazite na veličinu slova”);  podloga.addView(txtKorisnik);  } 

 

Rezultat klika na web adresu u kontroli TextView: Prikaz sadržaja zadane adrese u pregledniku.  Posebnu  vrstu  kontrola  za  upis  teksta  predstavljaju  kontrole AutoCompleteTextView te MultiAutoCompleteTextView.  Njihova  najvažnija  značajka  je  da tijekom upisa/ispravljanja teksta omogućavaju automatsko dovršavanje upisanog teksta. Evo i  primjera  odgovarajućeg  programskog  koda  nadopisanog  na  kraj  postojećeg  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 korištenja 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 korištenja kontrole EditText */ 

 

Primjer korištenja kontrole EditText: Kontrola se koristi za upis i izmjenu teksta.  EditText txtKorisnik = new EditText(this);  txtKorisnik.setText (“Upišite korisničko ime”);  txtKorisnik.setHint(“Pazite na upis malih i velikih slova”);  txtKorisnik.setError(“Pazite na veličinu slova”);  podloga.addView(txtKorisnik);  /* dodatak 3 – primjer korištenja kontrole AutoCompleteTextView */  AutoCompleteTextView actv = new AutoCompleteTextView(this);  ArrayAdapter aa = new ArrayAdapter(this,  android.R.layout.simple_dropdown_item_1line,  new String[] {“English”, “Hebrew”, “Hindi”, “Spanish”, “German”, “Greek” });  actv.setAdapter(aa);  podloga.addView(actv);  } 

 

Nakon  upisa  početnih  slova  (npr.  en)  automatski  se  predlaže  podudarajuća  potpuna  tekstualna  vrijednost, pa se ona nakon toga može jednostavno izabrati umjesto da se upisuje u cijelosti. 

Buttons  Android platforma omogućava korištenje tri različita tipa gumbi – osnovni gumb (Button Control),  gumb sa slikom (ImageButton Control) te gumb s mogućnošću prikaza dva različita stanja gumba  (ToggleButton Control). Osnovni tip gumba već smo koristili u primjerima iz prethodnih nastavaka  serijala, a detaljne mogućnosti korištenja sva tri tipa gumbi predstavit ćemo u slijedećem nastavku  serijala zajedno s ostatkom osnovnih kontrola.   

7. Android programiranje   

S predstavljanjem osnovnih Android kontrola prošli put smo zastali na dobro poznatim gumbima  (Buttons).  Kao  i  u  drugim  modernim  operativnim  sustavima  ovaj  tip  kontrole  koristi  se  u  aplikacijama  za  izvođenje  različitih  operacija,  a  (ponovo  kao  i  u  drugim  operativnim  sustavima)  može imati nekoliko pojavnih oblika.  Osnovni oblik gumba (Button) na sebi sadrži samo običan tekst koji označava kakvu će operaciju u  okviru određene aplikacije izazvati pritisak na gumb. Ako zadnjih nekoliko desetljeća niste proveli  izolirani  u  samici  nekog  zaostalog  nedemokratskog  režima  bez  ikakvog  kontakta  s  modernim  računalima, onda je prethodna rečenica sasvim dovoljna da shvatite o čemu je ovdje riječ. Budući  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,  nećemo  se  više ni baviti njime.  Budući da se moderna korisnička sučelja sve više temelje na slici nego na riječi, razumljivo da je  običan  gumb  doživio  svojevrsnu  vizualnu  nadogradnju,  postavši  tako  u  Android  terminologiji  kontrola  pod  nazivom  ImageButton.  Namjena  unaprijeđene  kontrole  je  potpuno  jednaka  kao  i  u  njezinom osnovnom obliku, jedino što takav gumb može izgledati bitno ljepše (što izravno ovisi o  slici postavljenoj na njegovu površinu). Upravo je zamjena osnovnih vrsta gumbi slikovnim jedan  od najvažnijih, ali ujedno i najjednostavnijih načina da vlastitu aplikaciju učinite atraktivnijom te u  konačnici  privlačnijom  potencijalnim  korisnicima.  Slikovna  verzija  gumba  povezuje  se  s  odgovarajućom datotekom s grafičkim sadržajem pomoću svojstva src, što se može napraviti u za  to  namijenjenom  prozoru  razvojne  okoline,  izravno  u  XML  datoteci,  ili  programskim  kodom.  U  priloženoj  segmentu  XML  datoteke  prikazan  je  primjer  korištenja  drugog  od  nabrojenih  načina,  dok se za istu namjenu u programskom kodu treba koristiti metoda setImageResource().  Treća  vrsta  gumba  pod  nazivom  ToggleButton  omogućava  prikaz  više  stanja  iste  pojave  unutar  aplikacije. Na primjer, jednim stanjem gumba može se pokazati da je uključen nekakav parametar  odnosno izvođenje nekakve operacije, a drugim stanjem da je parametar isključen odnosno da je  prekinuto  izvođenje  operacije.  U  praksi  se  takva  vrsta  gumbi  najčešće  koristi  za  prilagođavanje  različitih dijelova aplikacije željama i potrebama korisnika aplikacije. Kao što to ponovo prikazuje  priložena XML datoteka sa definicijama sve tri vrste opisanih gumbi, pomoću dva dodatna svojstva  gumba  android:textOn=”Pokrenuto”  android:textOff=”Zaustavljeno”>  moguće  je  definirati  dva 

različita tekstualna sadržaja za prikazivanje na samom gumbu ovisno o njegovom trenutnom stanju  (uključeno / isključeno).                    Kako  izgleda  korisničko  sučelje  nastalo  na  temelju  prethodne  XML  datoteke  možete  vidjeti  na  priloženoj slici uz današnji tekst.  Zadnjoj  od  prije  opisanih  kontrola  prilično  slične  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  praktično  svim  modernim  grafičkim  sučeljima  današnjice.  Obje  od  navedenih  kontrola  omogućavaju  uključivanje/isključivanje  različitih  opcija,  ali  se  međusobno  razlikuju  u  situacijama  kad  u  korisničkom  sučelju  aplikacije  postoji  više  kontrola  istog  tipa.  CheckBox  kontrole  su  u  pogledu  međusobnog  stanja  neovisne  jedne  od  druge,  što  znači  da  uključivanje ili isključivanje jedne od kontrola ne utječe na stanje druge kontrole. Osim promjene  trenutnog  stanja  od  strane  krajnjeg  korisnika  aplikacije,  vrijednosti  se  mogu  postavljati  programskim  kodom  korištenjem  metode  setChecked()  dok  se  trenutno  stanje  može  dobiti  pomoću isChecked().  Trenutno  stanje  neke  RadioButton  kontrole  ovisi  o  stanju  drugih  kontrola  iste  vrste,  što  drugim  riječima znači da u jednom trenutku samo jedna od takvih kontrola može biti uključena, dok sve  druge  kontrole  automatski  poprimaju  vrijednost  isključeno.  Zato  se  ova  vrsta  kontrola  koristi  za  rad  s  vrijednosti  koje  se  međusobno  isključuju.  Sa  stanovišta  programskog  koda  uključivanje/isključivanje stanja kontrole provodi se na sličan način kao i kod CheckBox kontrola.  Spomenimo  na  ovom  mjestu  i  to  da  se  pojam  međusobnog  isključivanja  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:  : Building User Interfaces and Using Controls                 

RadioButton kontrole: 

  Korištenje gumbi: Programeru su na raspolaganju tri različite vrste gumbi.                U izmišljenoj aplikaciji za naručivanje u restoranu u prvom slučaju korisnik aplikacije može označiti  različite  dijelove  obroka  neovisno  jedan  o  drugome,  a  u  drugom  slučaju  za  glavni  obrok  može  izabrati samo jednu od vrsta glavnog jela (mesa).  Nekoliko riječi o hardveru  Dozvolite  da  na  kraju  današnjeg  nastavka  softverskog  serijala  napišemo  par  riječi  o  dosta  zanimljivom hardverskom uređaju – Eken M001. Riječ je o 7 inčnom uređaju s ugrađenom Goolge  Android  platformom  u  verziji  1.6,  te  dobrim  mogućnostima  proširivanja  i  povezivanja  s  običnim  računalom. U slučaju da pripadate grupi programera koja završno testiranje vlastitog softvera želi  provesti  na  pravom  hardveru,  a  ne  samo  njegovom  simulatoru,  teško  da  ćete  proći  jeftinije.  Hardver nabrojen u slijedećoj tablici možete dobiti po cijeni manjoj od 100 dolara, a zanimljivo je  da se uređaj može pronaći čak i po domaćim malim oglasnicima. 

  Eken M001: Vrlo jeftini hardver s implementacijom Google Android platforme.  U  posljednje  vrijeme  domaći  operateri  mobilnih  usluga  počeli  su  nuditi  podosta  naprednije  uređaje  od  navedenog.  Ako  odaberete  odgovarajući  pretplatnički  odnos  možete  proći  čak  i  jeftinije, ali ne smijete zaboraviti da vas pretplatnički odnos veže na indirektno plaćanje uređaja na  najmanje  godinu  ili  dvije  dana.  S  druge  strane  nabavkom  M001,  dobivate  sasvim  upotrebljivi  uređaj za čitanje različitih materijala spremljenih izravno u njegovu memoriju ili pristupom preko  Wi‐fi  mreže,  igranje,  reprodukciju  multimedijalnih  sadržaja  i  još  ponešto.  Nije  iPod,  ali  iz  daljine  nitko to neće ni primijetiti.  Prema iskustvima autora teksta najvažniji nedostatak uređaja je prilično skromno trajanje baterija  pa budite spremni da osim sa sobom stalno nosite i ispravljač za njegovo nadopunjavanje. 

8. Android kontrole u akciji IV    Vrlo  važan  dio  gotovo  svake  aplikacije  (osim  onih  krajnje  trivijalnih,  ili  onih  koje  su  potpuno  optimizirane  za  neko  specijalizirano  područje)  je  upravljanje  vremenom.  Čak  i  različite  igre,  kao  kategorija aplikacija kakve se vrlo često pišu za mobilne uređaje uključujući i Android platformu,  često  spremaju  različite  podatke  o  igraču  ili  statusu  igre  povezane  s  datumom  i  vremenom.  Naravno,  za  prikaz  ili  izmjenu  datuma  i  vremena  programer  uvijek  može  izmisliti  svoje  vlastite  kontrole,  ali  nije  loše  kad  je  i  osnovni  razvojni  sustav  opremljen  odgovarajućim  kontrolama.  To  posebno vrijedi kod aplikacija s naglaskom na funkcionalnosti, a ne na vizualnoj raskoši.  Android platforma opremljena je s dvije međusobno prilično različite vrste kontrola za tu namjenu.  Prva grupa kontrola može samo prikazati podatke o vremenu, dok ih druga vrsta može prikazati, ali  i  dozvoliti   izmjenu  vrijednosti  od  strane  krajnjeg  korisnika  aplikacije.  U  prvu  grupu  kontrola  pripadaju  kontrole AnalogClock i DigitalClock (sam  naziv  u  potpunosti  govori  o  čemu  je  riječ).  Glavni nedostatak im je određen već prije spomenutom namjenom (prikazom podataka), pa se u  praksi  koriste  nešto  rjeđe,  osim  ako  je  dovoljno  da  kontrola  zaista  samo  prikazuje  datum  ili  vrijeme.  Zato  se  s  navedene  dvije  kontrole  više  nećemo  baviti.  Ako  njihova  ograničenja  zadovoljavaju  vaše  planove  u  izradi  aplikacija,  jednostavno  ih  postavite  na  neki  od  standardnih  rasporeda kontrola i zaboravite na njih. 

  U slučaju da je potrebno omogućiti 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 može se napraviti prema slijedećem primjeru.   

        Prva  (gornja)  kontrola  zadužena  je  za  prikaz,  odnosno  odabir  datuma,  a  donja  to  isto  radi  s  vremenom,  kao  što  se  to  može  provjeriti  na  priloženoj  slici  uz  tekst.  Kad  se  tome  pridoda  programski kod naveden u nastavku zadužen za podešavanje početnih vrijednosti kontrola, dobije  se  sasvim  funkcionalno  korisničko  sučelje.  Najveći  nedostatak  ove  grupe  kontrola  je  njihova  relativna nezgrapnost. Drugim riječima jednostavno su prevelike za intenzivno korištenje, naročito  ako  koristite  uređaj  s  relativno  skromnom  rezolucijom  zaslona.  Ako  to  predstavlja  nepremostivu  prepreku možete se snaći 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));  }  } 

Korištenje izbornika  Osim  sasvim  jednostavnih  uradaka  većina  aplikacija  podržava  neki  oblik  sustava  izbornika  namijenjen izboru svih operacija koje nudi aplikacija. Ni Android platforma po tome nije nikakav  izuzetak. Zapravo mogli bi reći da vrijedi čak suprotno – programeru je na raspolaganju nekoliko  različitih  sustava  izbornika,  a  na  njemu  je  odluči  koji  od  njih  najviše  odgovara  potrebama  konkretne  aplikacije.  Dok  ste  neke  od  dostupnih  sustava  izbornika  već  susretali  na  drugim  operativnim sustavima u vrlo sličnom obliku, Android nudi i neke novosti na ovom području, zbog  čega ćemo se izbornicima pozabaviti u dva broja časopisa.  Po  običaju  krećemo  od  najjednostavnijeg  oblika  izbornika,  za  čiju  pojavu  u  aplikaciji  je  zadužen  isključivo 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 odgovarajućom 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  izvođenja  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  navođenje  č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  brojčane,  a  četvrta  je  iz  sasvim  razumljivih  razloga  tekstualna.  Zadnja  od  nabrojenih  opcija može se u programskom kodu za generiranje izbornika zadati izravno, kao što je to slučaj u 

prethodnom  primjeru,  ili  se  odgovarajuća  vrijednost  može  unaprijed  pripremiti  u  resursnoj  datoteci.  Istaknimo  kako  nije  uvijek  potrebno  navoditi  baš  sve  brojčane  vrijednosti,  nego  se  umjesto njih može upotrijebiti vrijednost Menu.None.  Ako  je  potrebno  opcije  izbornika  u  aplikaciji  grupirati  u  više  od  jedne  grupe,  onda  se  to  rješava  navođenjem različitih oznaka grupe prilikom zadavanja naredbi za stvaranje opcija izbornika. Takva  podjela  izbornika  na  dvije  grupe  prikazana  je  u  slijedećem  segmentu  programskog  koda,  kojeg  treba umetnuti u program umjesto istoimene funkcije iz prethodnog kompletnog  primjera koda.  Kako će izgledati dobijeni rezultat može se vidjeti na priloženoj 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  uređaja,  ali  pritisak  na  te  izbornike  trenutno  ne  izaziva  baš  nikakvu  reakciju,  jer  jednostavno  nedostaje odgovarajućeg programskog koda za tu namjenu. To je tema kojom ćemo se pozabaviti  u  slijedećem  broju,  baš  kao  i  dodavanjem  slika  na  opcije  izbornika,  kako  bi  se  postigao  što  bolji  vizualni dojam u vlastitoj aplikaciji.  U  ostatku  današnjeg  teksta  navest  ćemo  karakteristike  preostalih  vrsta  izbornika  dostupnih  na  Android  platformi.  Prva  vrsta  su  takozvani prošireni  izbornici.  Ova  vrsta  izbornika  nastaje  automatski,  ako  programer  „pretjera“  s  brojem  opcija  osnovnog  izbornika.  U  tom  slučaju  se  kao  opcija  izbornika  automatski  prikazuje  vrijednost More,  a  njezinim  odabirom  korisnik  aplikacije  može  stići  do  početno  skrivenih  opcija  izbornika.  Jedno  od  ograničenja  proširenih  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 trešnje i višnje, to jest opcije izbornika sa slikama i one bez  slika. 

Kod  dodavanja  ikona  na  opcije  izbornika  u  igri  je  još  nekoliko  dodatnih  ograničenja  osim  onog  spomenutog u prethodnom odjeljku. Na opciji izbornika s ikonom ne može biti prikazana oznaka  njezinog  izbora  (kvačica),  a  ako  je  tekst  opcije  izbornika  nešto  duži,  onda  će  biti  prikazan  samo  početni  dio.  To  i  nije  nelogično  –  ako  odaberete  ikonu  koja  vrlo  reprezentativno  označava  neku  operaciju, zašto bi je onda naširoko i opisivali. Prednosti takvog pristupa kod stvaranja višejezičnog  sučelja ne trebamo posebno ni isticati. 

  U slučaju vrlo širokog raspona mogućih operacija u aplikaciji, neke (ili sve) opcije izbornika mogu  imati  svoje podizbornike.   Opcije  podizbornika  dodaju  se  programski  odgovarajućim  metodama  što  ćemo  prikazati  u  slijedećem  nastavku.  Za  sada  istaknimo  kako  i  ova  kategorija  izbornika  ne  podržava prikaz ikona, iako se formalno ne javljaju nikakve greška kod takvog pokušaja.  Izbornici  ovisni  o  kontekstu predstavljaju  posebnu  vrstu  izbornika  čiji  izgled  se  mijenja  ovisno  o  smislu  izvođenja  pojedinog  dijela  aplikacije,  a  aktiviraju  se  takozvanim dugim  pritiskom  na  neki  element  korisničkog  sučelja.  Programer  može  u  vlastitu  aplikaciju  dodati  i  standardne sistemske  izbornike. Kako se to radi, također ćemo demonstrirati slijedeći put.   

       

9. Korištenje datotečnog sustava  Nakon što smo u prošlom nastavku pokazali kako se stvara osnovna vrsta izbornika, danas ćemo  objasniti  kako  program  na  najednostavniji  mogući  način  putem  izbornika  odgovara  na  akcije  korisnika. Ujedno ćemo od ovomjesečnog nastavka napraviti malo „ubrzanje“ u izlaganju kako bi u  planiranom  broju  preostalih  nastavaka  mogli  doista  i  napraviti  nekakvu  malo  složeniju  aplikaciju. Ideja  je  da  izloženu  materiju  prikažemo  na  međusobno  povezani  način,  kako  nakon  prolaska  kroz  čitav  serijal  ne  bi  imali  niz  nepovezanih  segmenata  znanja  o  pojedinim  dijelovima  Android SDK sustava, ali bez mogućnosti njihovog slaganja u smislenu cjelinu. S druge strane, na  temelju dosadašnjih nastavaka više ne bi trebali imati previše problema s tim da pronađete gdje se  umeću  pojedini  dijelovi  programskog  koda.  Zato  na  ovom  mjestu  nećemo  izložiti  sve  moguće  načine  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  složenijoj aplikaciji koju smo maloprije najavili pokazati brojne dodatne mogućnosti u korištenju.  Osnovni  oblik  reakcije  izbornika  na  djelovanje  korisnika  priprema  se  u  dva  koraka  prema  slijedećem  obrascu.  U  prvom  koraku  treba  implementirati OnMenuClickListener sučelje.  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 događaja – pritiska  na neku od opcija izbornika.  //korak1  public class MyResponse implements OnMenuClickListener  {  //…  @override  boolean onMenuItemClick(MenuItem item)  {  //izvođenje operacije  return true;  }  }  //korak 2  MyResponse myResponse = new MyResponse(…);  menuItem.setOnMenuItemClickListener(myResponse); 

…  Osim  osnovnog  načina  reakcije  izbornika  na  događaje  postoji  još  nekoliko  varijanti  koje  ćemo  demonstrirati na složenijoj aplikaciji. U njoj ćemo ujedno pokazati kako se izvornici mogu stvoriti  preko odgovarajuće resursne XML datoteke, a ne samo programskim kodom. 

Rad s datotekama  Svaka malo složenija aplikacija, koja rukuje s korisnim podacima, mora imati mogućnost spremanja  podataka  iz  aplikacije  u  neko  spremište  te  njihovo  vraćanje  kad  se  za  tim  ukaže  potreba.  U  današnjem nastavku pokazat ćemo kako se navedene dvije operacije izvode pomoću datotečnog  sustava  ugrađenog  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  nužne  operacije kod  takvog postupka. Prva je „skupljanje“ trenutnih vrijednosti različitih Android kontrola upisanih od  strane  korisnika  aplikacije  kako  bi  se  imalo  što  upisati  u  datoteku,  a  druga  je  njihovo  ponovno  vraćanje iz datoteke i postavljanje na odgovarajuću kontrolu.  Pogledajmo prvo kako se izvodi spremanje podataka u datoteku na segmentu programskog koda  „izvađenog“  iz  jedne  manje  medicinski  orijentirane  aplikacije.  U  ovom  trenutku  zapravo  i  nije  previše bitno o kakvim se podacima radi. Primijetimo samo da se podaci ne skupljaju isključivo iz  tekstualnih  nego  i  iz  drugih  oblika  kontrola,  a  prije  samog  spremanja  u  datoteku  se  grupiraju  u  jedan složeniji niz znakova. U njemu su podaci međusobno odvojeni posebnim nizom znakova za  odvajanje, kako bi se olakšalo 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 važnu činjenicu koju svakako treba uzeti u obzir kod rada s datotečnim sustavom, a  to je mogućnost pojave greške. Osnovni niz naredbi za zapis podataka u datoteku:  fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);  fos.write(string.getBytes());  fos.close();  može ponekad dovesti do pojave greške, ako ni zbog čega drugog onda zbog nedostatka prostora  na  mediju  na  kojem  se  nalazi  datotečni  sustav.  Kako  se  aplikacija  u  tom  slučaju  ne  bi  počela  nekontrolirano ponašati, treba ugraditi bar osnovni mehanizam obrade pogreške u vlastitom kodu,  što je ovdje i napravljeno korištenjem 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  pogrešaka  (throws  IOException),  jer  se  može dogoditi da u datotečnom sustavu iz ovog ili onog razloga ne postoji, ili je oštećena datoteka  s  podacima.  Budući  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  također  „odraditi“  u  jednom  koraku,  te  ujedno  razbiti  podatke  u  odgovarajuće polje podataka pomoću naredbe:  String[] list = TextUtils.split(string1, “###”);  Preostalo  je  još  samo  to  da  se  na  korištenom  rasporedu  kontrola  unutar  aplikacije  pronađe  odgovarajuća kontrola te da joj se dodijeli točno određena vrijednost pročitana iz datoteke. Za taj  postupak koristi se niz findViewById naredbi. 

  10. Nekoliko standardnih djelova aplikacije    Prošli  put  smo  iz  nešto  složenije  medicinski  orijentirane  Android  aplikacije  „izvukli“  dio  programskog  koda  zadužen  za  spremanje  podataka  te  za  njihovo  ponovno  čitanje  kad  se  za  tim  ukaže  potreba.  U  današnjem  nastavku  pokazat  ćemo  još  nekoliko  karakterističnih  dijelova  programskog koda, koje uz manje ili veće promjene možete upotrijebiti u vlastitim projektima.  Prvo jedan sasvim logičan, ali važan savjet. Svaka složenija Android aplikacija, a naročito ako ona  koristi  različite  sistemske  module  (kao  što  je  to  slučaj  u  ovom  primjeru),  zahtijeva  uključivanje  odgovarajućih  biblioteka.  Ovisno  o  načinu  oblikovanja  korisničkog  sučelja  i  pisanju  programskog  koda, taj je postupak u najvećoj mogućoj mjeri automatiziran. Međutim, ako se tijekom razvoja u  aplikaciji odjednom pojavi čitav niz pogrešaka, postoji dosta velika vjerojatnost da nedostaje (zbog  izostanka  ili  slučajnog  brisanja)  odgovarajuća import naredba.  U  nastavku  slijedi  prikaz  kako  to  prilično komplicirano izgleda u ovom slučaju: 

  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 količine prikupljenih podataka o korisniku aplikacije neprikladne za prikaz na  samo  jednom  zaslonu  ograničene  rezolucije  (uobičajene  kod  mobilnih  telefona  opremljenih  Android  sustavom),  koristi  se  više  međusobno  povezanih  rasporeda  kontrola,  a  na  svakom  od  rasporeda  upotrijebljene  su  različite  kontrole  kako  bi  se  što  jednostavnije  i  preglednije  unijeli  relevantni podaci. Kako to zaista izgleda na zaslonu Android uređaja možete provjeriti na temelju  priloženih slika uz tekst, a dijelovi odgovarajućeg XML koda navedeni su u nastavku. 

…        …      …      …     

  U  trenutku  prelaska  s  jednog  rasporeda  kontrola  na  drugi  postojeći  sadržaj  kontrola  iz  starog  rasporeda  kontrola  sprema  se  za  kasnije  korištenje,  a  novi  raspored  kontrola  se  popunjava  prethodno  spremljenim  sadržajem  (ako  takav  postoji  zbog  ranijeg  korištenja  aplikacije).  Obje  operacije  objašnjene  su  u  prethodnom  nastavku  serijala.  Pokažimo  sada  kako  se  programskim  kodom prelazi s jednog rasporeda kontrola na drugi. Na svakom osnovnom rasporedu postoje dva  gumba za kretanje na slijedeću odnosno prethodnu stranicu (razumljivo osim na prvom i zadnjem).  Slijedi primjer korištenja na drugom rasporedu kontrola – na njemu postoji gumb za prelazak na  prvi, odnosno na treći 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  pogreške  prilikom  kretanja  kroz  osnovne  rasporede  kontrola  ne  bi  izazvale  rušenje  programa,  prijenos  prikaza  s  jednog  rasproeda  kontrola  na  drugi  „zamotan“  je  u  odgovarajuću strukturu za obradu pogreške.  Osim prikaza podataka na standardnim rasporedima kontrola, vrlo često je u programu potrebno  prikazati  i  odgovarajuće  dijaloške  okvire  o  statusnim  informacijama,  greškama  u  radu  i  slično.  U  nastavku je naveden primjer programskog koda za prikaz dijaloškog okvira s podacima o autorima  programa  (ako  za  to  ne  namjeravate  koristiti  poseban  raspored  kontrola  zbog  veće  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 + “Stručni medicinski suradnik\n”;  poruka = poruka + “Fusić Snježana\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  slučaju  da  vam  to  negdje  zatreba,  evo  i  opće funkcije  za otvaranje  osnovnog  oblika  dijaloškog  okvira koju uz veće ili manje preinake možete upotrijebiti u vlastitim aplikacija. Ulazni parametri  funkcije su poruka koja se prikazuje u okviru dijaloškog 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  današnjeg  nastavka  najsloženiji  „komad“  programskog  koda  zadužen  za  pripremu  i  slanje  SMS  poruke  s  podacima  iz  programa  u  slučaju  nezgode.  Zbog  ograničenja  prostora  u  časopisu  ovim  dijelom  ćemo  se  nešto  detaljnije  pozabaviti  u  slijedećem  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(),”Greška”);  e.printStackTrace();  }  AlertDialog ad = new AlertDialog.Builder(prvaPomoc.this).create();  CharSequence poruka = “Zabilježeno 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();  }  } 

  11. Standardni dijelovi aplikacije    Na kraju teksta u prethodnom broju časopisa naveden je malo veći segment programskog koda za  izvođenje nekoliko bitnih stvari u programu, ali jednostavno nije bilo dovoljno mjesta za njegovo  detaljnije  objašnjenje.  Zato  u  današnjem  nastavku  slijedi  malo  detaljnija  rasprava  o  korištenim  objektima i metodama  u  tom dijelu aplikacije.  Razjasnimo prvo namjenu izdvojenog dijela programskog koda s kraja prethodnog nastavka, kako  bi  lakše  mogli  pratiti  detalje  u  nastavku.  Ideja  je  da  korisnik  aplikacije  u  trenutku  kad  doživi  nekakvu nezgodu (koja bitno utječe na njegovo zdravstveno stanje) može što jednostavnije i brže  poslati SMS poruku na unaprijed definirani broj, kako bi izabranu osobu ili ustanovu obavijestio o  svojoj  nezgodi.  Pretpostavka  za  izvođenje  takvog  postupka  je  da  nakon  nezgode   ostane  u  svjesnom  stanju,  kako  bi  zaista  mogao  pokrenuti  aplikaciju  te  pritisnuti  gumb  za  slanje  SMS  poruke.  Ako  može  napraviti  tu  operaciju,  onda  može  pritisnuti  i  drugi  gumb  kako  bi  zabilježio  vrijeme  nezgode,  jer  se  tako  kod  pružanja  prve  pomoći  lako  može  ustanoviti  koliko  je  vremena  doista  prošlo  od  nezgode.  To  može  biti  vrlo  bitan  faktor  za  poduzimanje  različitih  operacija  nad  unesrećenim.  Čak  i  ako  korisnik  aplikacije  u  trenutku  kad  stigne  prva  pomoć  bude  u  nesvijesti,  može se pročitati podatak o trenutku nezgode, kao i drugim bitnim karakteristikama unesrećenog  (krvna grupa, kronične bolesti i slično). Te informacije su dostupne i u situaciji kad SMS poruka nije  poslana, a nije zabilježen ni trenutak nezgode – bitno je samo da spasitelji malo „pročeprkaju“ po  Android mobitelu, jer je on najverojatnije negdje pri ruci. Ostaje još samo odgovor na pitanje zašto  su operacije slanja SMS poruke i bilježenja trenutka nezgode razdvojene. Postoje situacije kad SMS  poruku,  a  pogotovo  neke  njezine  dijelove  (vidi  nastavak  teksta)  nije  moguće  ni  pripremiti  ni  poslati, pa se u tom slučaju može zabilježiti samo trenutak nezgode. 

  LocationManager: Vrlo složen objekt na Android platformi zadužen za dobijanje točne geografske  lokacije.  Prvi  dio  programskog  koda  je  najjednostavniji  za  objašnjavanje  jer  služi  za  obično  određivanje  točnog  vremena  nakon  pritiska  korisnika  na  odgovarajući  gumb  aplikacije.   To  vrijeme  se  trajno  pamti kako bi ga spasitelji mogli naknadno očitati. Ovaj segment programskog koda „zamotan“ je u  standardnu rutinu za obradu pogreške, u slučaju da se dogodi nekakav problem tijekom izvođenja  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  točna  geografska  lokacija  s  koje  je  poruka  poslana,  kako  bi  se  što  brže  i  jednostavnije došlo do unesrećenog korisnika aplikacije. Ako mobilni telefon (ili neki drugi uređaj  koji se temelji na Android platformi) u sebi sadrži odgovarajući hardverski dio za dobijanje takvog  podatka,  onda  slijedeći  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  sadrže  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  obično,  bitno  je  da  takv  dio  aplikacije  podložan  pogreškama  bude  obuhvaćen  u  strukturu  za  obradu pogrešaka. Zahtijevani podatak može u nekom trenutku jednostavno biti nedostupan.  Na  primjer,  izvor  GPS  podataka  je  uništen  solarnom  bakljom.  Dobro  –  malo  se  šalimo,  mnogo  je  vjerojatniji  neki  drugi  uzrok  problema,  iako  prema  najavama  nekih  stručnjaka  2012  godine  to  možda uopće više neće biti samo šala.  LocationManager je vrlo složen objekt na Android platformi pa njegovo detaljno opisivanje prelazi  okvire  ovog  teksta.  Osnovni  primjer  prikazan  u  prethodnom  dijelu  programskog  koda,  trebao  bi  vam poslužiti kao vodič za dodatno istraživanje pratećih 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  slučaju  da  navedena  dva  podatka  nisu  pripremljena,  onda  se  korisniku  aplikacije  javlja odgovarajuća poruka kako bi se riješio problem. Za to se koristi funkcija o čijoj smo namjeni i  djelovanju raspravljali u jednom od prethodnih nastavaka serijala.  Sasvim  je  jasno  da  kritična  situacija,  u  kojoj  se  može  naći  korisnik  aplikacije,  nije  baš  idealan  trenutak da aplikacija javi kako smo u fazi njezinog punjenja početnim podacima zaboravili navesti  neki detalj (fiksni dio SMS poruke ili odredišni broj). Otprilike se radi o istoj situaciji kao kad bi vaš  najnoviji  automobil  (dostupan  uz  mjesečnu  ratu  od  svega  500  kn,  ali  uz  učešće  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 kočenja javio nekakvu poruku da to ne može ili ne  želi napraviti. Rješenje problema je vrlo jednostavno. Nakon upisivanja svih potrebnih podataka u  aplikaciju  na  samom  početku  njezina  korištenja,  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(),”Greška”);  e.printStackTrace();  }  AlertDialog ad = new AlertDialog.Builder(prvaPomoc.this).create();  CharSequence poruka = “Zabilježeno 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  točno  vrijeme  slanja  poruke.  Ne  treba  posebno  ni  napominjati  da  se  svi  podaci  iz  prethodne  operacije  spremaju  u  odgovarajuća  „spremišta“  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  mogućnosti sami izrađivati relativno složene Android aplikacije. Međutim, još uvijek nismo završili  serijal,  jer  nam  je  preostala  demonstracija  korištenja  nekoliko  bitnih  tehnika  kao  što  je  dobro  poznati Google Maps, preuzimanje podataka s ugrađenih senzora, korištenje dodatnih grafičkih i  zvučnih mogućnosti te još poneka zanimljivih sitnica. Ostalo je još dosta zanimljivog materijala za  slijedećih  nekoliko  nastavaka,  posebno  ako  sve  te  dijelove  uz  dodatak  već  obrađenih  želimo  kreativno povezati u prave aplikacije. 

  LocationManager: Vrlo složen objekt na Android platformi zadužen za dobijanje točne geografske  lokacije.  Budući da smo u zadnjih nekoliko brojeva „vadili“ dijelove programskog koda iz relativno složene  aplikacije, nismo na pratećem digitalnom mediju objavljivali dijelove projekta. Od slijedećeg puta  ponovo  se  vraćamo  na  staru  dobru  praksu  korištenja  pratećeg  medija  uz  časopi,  kako  se  ne  bi  trebali  sami  mučiti  s  prekucavanjem  manjih  ili  većih  dijelova  programskog  koda  u  korisničko  sučelje vlastitog računala. 

       

12. Alternativni pristup razvoju aplikacija  U  prethodnih  desetak  (i  još  malo  više)  nastavaka  serijala  o  Android  programiranju  pokazali  smo  dosta  toga  što  vam  može  pomoći  kod  razvoja  vlastitih  aplikacija  –  počevši  od  instalacije  svih  potrebnih alata na vlastito računalo pa sve do razvoja standardnih dijelova složenijih aplikacija. U  međuvremenu se uređaji bazirani na Androidu (telefoni, ali i „tabletići“ te drugi mobilni uređaji)  sve  bolje  prodaju  širom  svijeta,  tako  da  razvoj  aplikacija  za  ovu  platformu  sigurno  neće  biti  uzaludan napor.  Iako  ćemo  se  u  slijedećih  nekoliko  nastavaka  serijala  pozabaviti  s  još  nekoliko  naprednijih  programerskih  tehnika,  ovaj  put  ćemo  se  malo  detaljnije  osvrnuti  na  alernativni  (čitaj  bitno  jednostavniji) način za razvoj aplikacija, također nastao u radionicama istog proizvođača. Na kraju  krajeva  među  čitateljima  časopisa  sigurno  ima  onih  s  vrlo  dobrim  idejama  za  razvoj  novih  aplikacija,  ali  im  se  korištenje  Google  SDK  alata  ipak  čini  malo  prekompliciranim.  Srećom,  Googleovi  inženjeri  intenzivno  rade  na  nešto  drugačijem  pristupu  čitavoj  stvari,  pa  ćemo  vas  u  današnjem 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 omogućava vizualno orijentirani razvoj različitih Android aplikacija izravno u  pregledniku.  Zbog  toga  je  pisanje  programskog  koda  gotovo  u  potpunosti  izbačeno  iz  alata  te  zamijenjeno nečim 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 podržava sve  što je zamišljeno (još uvijek se nalazi u beta fazi razvoja) već sada se pomoću njega mogu napraviti  zanimljive  i  korisne  aplikacije.  Googleovi  inženjeri  naglašavaju  kako  se  trenutni  problemi  prije  svega odnose na područja instalacije upravljačkih uređaja, prijenosa dijelova razvojnog alata Java  na  računalo  te  distribuciju  same  aplikacije  na  odredišni  mobilni  uređaj,  odnosno  postavljanje  različitih  postavki  korištenja  aplikacije  na  tom  uređaju.  Zato  se  u  trenutnoj  fazi  razvoja  alata  od  zainteresiranih  korisnika  traži  da  pripreme  što  detaljnije  povratne  informacije  o  korištenju  alata,  kako bi se što prije prevladali svi uočeni problemi. 

 

Priprema  računala  za  razvoj:  Mogu  se  koristiti  različite  kombinacije  operativnih  sustava  i  preglednika.  Razvoj vlastitih aplikacija u alatu App Inventor for Android započinje pripremom vlastitog računala  za  takav  zadatak.  Za  razliku  od  Microsofta  ili  Applea  poznatih  po  ograničavaju  razvoja  na  vlastiti  hardver  i/ili  softver,  Googleov  razvojni  tim  kontinuirano  podržava  sve  najpopularnije  platforme  (Windows, Mac i Linux). Zato nije ni čudo da se Android polako, ali sigurno, probija prema samom  vrhu  popularnosti  na  području  mobilnih  platformi.  Nastavak  teksta,  te  prije  svega  prateće  slike)  podrazumijevaju razvoj vlastitih aplikacija u Google Chrome pregledniku na Windows računalu, ali  iz  prije  navedenih  razloga  ne  bi  trebali  imati  previše  problema  ni  u  razvoju  aplikacija  na  nekoj  drugoj konfiguraciji.  Prvi korak u pripremi računala je preuzimanje odgovarajućeg programa za upravljanje pripremom  razvojne  konfiguracije.  Ovaj  program  može  se  slobodno  preuzeti  usmjeravanjem  preglednika  na  web adresuhttp://appinventor.googlelabs.com/learn/setup/setupwindows.html  Nakon preuzimanja instalacijskog programa treba ga instalirati na računalo te podesiti parametre  ciljnog mobilnog uređaja. U trenutnoj fazi razvoja alata podržano je izravno svega nekoliko uređaja  poput T‐Mobile G1 ili T‐Mobile myTouch, dok se za ostalo  „očvrsje“ treba pomučiti malo više te  napraviti  manja  ili  veća  podešavanja  na  samom  telefonu.  Budući  da  je  ovaj  postupak  ovisan  o  samom  telefonu,  kao  takav  prelazi  okvire  napisanog  teksta.  Sve  potrebne  informacije  možete  pronaći slijedeći odgovarajuće linkove na prije navedenoj web adresi. 

  Početak rada na aplikaciji: Započinje stvaranjem projekta – u ovom slučaju HelloPurr. 

   

Izrada prve aplikacije  U nastavku teksta opisat ćemo izradu prve aplikacije prema Googlevoj pratećoj dokumentaciji. Za  razliku od uobičajenog Hello World primjera koji samo prikazuje dvije riječi na zaslonu, Googleov  početni  primjer  odmah  koristi  i  audio/video  podatke,  to  jest  prikazuje  sliku  te  reproducira  zvuk.  Zato kao početni korak u izradi aplikacije treba skinuti jednu sliku u .png formatu, odnosno jednu  zvučnu  datoteku  u.mp3 formatu.  Umjesto  onih  koje  nudi  Google  za  testiranje  razvojnog  alata,  možete upotrijebiti svoje vlastite, ali za sada ćemo se držati priložene „kuharice“.  Razvojni  alat  pokrećete  postavljanjem  preglednika  na  adresu http://appinventor.googlelabs.com.  Da bi se moglo prijeći na razvoj same aplikacije potrebno je da korisnik ima odgovarajući google  email korisnički račun. Ako ga još nemate, ovo je prilika da ga stvorite. Kad obavite tu formalnost,  pojavljuje  se  stranica  namijenjena  pripremi  novih  aplikacija,  odnosno  administriranju  postojećih.  Budući  da  pripremate  svoj  prvi  projekt,  izaberite  opciju New na  vrhu  stranice  te  upišite  naziv  aplikacije HelloPur. 

  Razvojna okolina: Vrlo je jednostavna i namijenjena korisnicima koji nisu profesionalni programeri.  Kao  rezultat  izvođenja  prethodne  operacije  pojavljuje  se  glavna  stranica  razvojnog  alata  namijenjena izradi aplikacije (vidi prateće 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  različite  grupe  kontrola  namijenjene  iskorištavanju  brojnih  mogućnosti  Android  sustava.  Tijekom  razvoja  prve  aplikacije  bit  će  nam  potrebne  svega  dvije  kontrole: Button iLabel. Jednostavnom operacijom povlačenja postavite in na središnji dio stranice  namijenjen simuliranju zaslona mobilnog uređaja. Kontrole postavite jednu ispod druge, a onda je  preostalo  da  im  izmijenite  nekoliko  svojstva,  kako  bi  dobili  izgled  sučelja  prikazan  na  jednoj  od 

pratećih  slika  uz  tekst.  Kontroli Button potrebno  je  obrisati  početni  tekst  prikazan  na  kontroli  (svojstvo Text) te učitati prije spomenutu sliku kitty.png  (svojstvo Image). Kontroli Label potrebno  je  postaviti  boju  pozadine  na  plavu  (svojstvo BackgroundColor),  povećati  veličinu  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  običnim  povlačenjem  kontrole  na  centralni  dio  koji  predstavlja zaslon mobilnog uređaja.  Na  ovom  stupnju  razvoja  aplikacije  u  nju  je  dodana  slika,  ali  još  uvijek  ne  i  zvučni  zapis.  Zato  je  potrebno u aplikaciju povući još jednu kontrolu (Sound iz grupe Media), a onda pomoću gumba na  dnu  stranice  dodati  prije  spomenutu mp3 datoteku  (meow.mp3).  Ovim  potezom  sučelje  je  u  potpunosti dovršeno s dizajnerske strane, ali je za kompletiranje aplikacije potrebno napraviti još  nešto.  Da  bi  se  tijekom  izvođenja  aplikacije  pritiskom  na  sliku  umiljate  mačkice  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 sučelja, koja u  konačnici  ipak  zahtijevaju  prilično  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,  pričekati  određeno  vrijema  kako  bi  se  na  vaše  računalo  instalirala  dodatna  komponenta  za  „pisanje  programskog  koda“.  Evo  ponovno  navodnika,  a  konačno  i  objašnjenja   zašto.  Kad  se  otvori  popis  svih  dostupnih  događaja,  oni  su  prikazati  u  obliku  svojevrsne slagalice. Potrebni događaj u kontekstu nekog dijela aplikacije potrebno je jednostavno  „spariti“  s  pravom  operacijom,  što  se  izvodi  običnom  operacijom  povlačenja.  U  konkretnom  slučaju potrebno je događaj Button1.Click povezati s operacijom Sound1.Play i to je to. Koliko to  efektno izgleda možete provjeriti na priloženoj slici ili isprobati sami. Bravo Google! 

  Prozor Properties: Koristi se za izmjenu različitih svojstava označene kontrole.  Preostalo je još samo da isprobate aplikaciju na stvarnom hardverskom uređaju tijekom instalacije  povezanim s razvojnim alatom, ili na odgovarajućem softverskom emulatoru. Na kraju je pomoću  operacijePackage for Phone moguće napraviti i distribucijski oblik aplikacije.  Priznajte da nije bilo komplicirano, iako nismo baš detaljno opisivali način promjene svojstava. Ipak  bi  ovaj  tekst  trebali  pratiti  čitatelji  s  bar  početnim  poznavanjem  programiranja,  tako  da  ne  bi  trebao biti problem izvesti tako elementarne operacije u dizajnu aplikacije.  Pomoću  alata  App  Inventor  for  Android  (iako  je  još  uvijek  u  fazi  beta  verzije)  mogu  se  napraviti  znatno složenije aplikacije u što se možete uvjeriti i sami nakon malo vježbe. 

  Dodavanje programskog koda: Zaista se izvodi na vizualno efektan način. 

  Izvođenje programa: Osim na samom uređaju, moguće je i u odgovarajućem emulatoru. 

 

13. Alternativni pristup razvoju aplikacija II   

Prošli put smo demonstrirali osnove korištenja 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  (nešto  slično  klasičnom  Hello  World  primjeru),  a  danas  ćemo  probati  prikazati  da  je  upotrebljiv za bitno složenije projekte.  Odgovorimo  prvo  na  nekoliko  najvažnijih  pitanja  povezanih  s  korištenjem  alata  na  razvoju  složenijih  projekata.  Najvažnije  pitanje  koje  se  nameće  samo  po  sebi  je  potencijalna  složenost  dovršene  aplikacije.  Tu  odmah  treba  biti  izravan  te  reći  da  se  pomoću  alata  App  Inventor  for  Android ne može napraviti baš sve što i s službenim razvojnim alatom, ali da se može puno toga –  može se. Osim brojnih komponenti za razvoj različitih dijelova sučelja (što smo djelomice pokazali  u  u  prošlom  uvodnom  tekstu  o  alatu),  na  raspolaganju  su  najvažnije  programske  strukture  poput foreach, while, if‐else (iako u nešto slikovitijem obliku nego je to uobičajeno u programskim  jezicima),  a  moguća  je  i  komunikacija  s  web  servisima  te  svojevrsnim  spremištem  podataka.  Od  važnijih  tehnologija  karakterističnih  za  mobilne  uređaje  današnjice,  trenutno  nije  podržan  samo  Bluetooth, ali se prema tvrdnjama proizvođača intenzivno radi i na tom segmentu. 

  Basic komponente: Predstavljaju osnovne grafičke elemente aplikacije.  Ako  vam  slučajno  ni  sve  nabrojano  nije  dovoljno  za  izradu  vlastite  aplikacije,  onda  alat  skoro  neograničeno možete nadopunjavati izradom vlastitih komponenti u Javi. To znači da morate ipak  biti  nešto  vještiji  u  programiranju,  a  onda  se  neminovno  postavlja  pitanje  zašto  ne  bi  sve  skupa  ipak  programirali  u  standardnom  SDK  razvojnom  sustavu.  Ako  pomoću  alata  App  Inventor  for 

Android možete sami odraditi veći dio projekta, onda ima smisla da za manji nedostajući segment  vlastite aplikacije angažirate Java programera da vam pomogne.  Trenutno  dva  najveća  nedostatka  alata  odnose  se  na  nemogućnost  izravne  objave  aplikacije  na  globalnom  tržištu  Android  aplikacija  (Android  Market),  te  ograničenost  aplikacije  na  samo  jedan  prikaz  (raspored  kontrola).  Google  obećava  kako  će  prvi  problem  biti  uskoro  riješen  pa  se  zato  njime  nećemo  previše  baviti.  Napišimo  zato  nekoliko  riječi  o  drugom  problemu.  Na  trenutnom  stupnja  razvoja  alata  ne  može  se  izvoditi  prebacivanje  između  više  različitih  vrsta  prikaza  ili  rasporeda kontrola. To na prvi, drugi i treći pogled predstavlja zbilja veliko ograničenje u razvoju  aplikacija, ali ga je ipak moguće prevazići jednim od slijedeća dva trika.  1. Naizmjeničnim  „paljenjem  i  gašenjem“  kontrola,  to  jest  izmjenom  vidljivosti  različitih  komponenti postavljenih na jedini dostupni prikaz kontrola.  2. Međusobnim  višestrukim  povezivanjem  više  App  Inventor  for  Android  aplikacija, od  kojih  svaka  može  imati  različite  rasporede  kontrola  na  osnovnom  zaslonu.  Kad  su  prije  koje  desetljeće nešto slično mogli raditi autori složenih igara na strojevima poput ZX Spectruma  ili  Commodorea  64  te  kasetofonom  kao  uređajem  vanjske  memorije,  nema  nikakvog  razloga zašto se to ne bi moglo napraviti i danas sa znatno modernijim hardverom. 

  Media  komponente:  Komponente  za  upravljanje  različitim  multimedijalnim  dijelovima  mobilnog  uređaja.  Iako slijedeća vijest nema nikakve veze s prethodnom točkom, današnjim tekstom, pa čak ni cijelim  serijalom  u  cjelini,  ipak  ću  je  spomenuti  na  ovom  mjestu,  ako  je  do  sada  već  niste  sami  negdje  pročitali. Kultni Commodore 64 je prije kratkog vremena doživio svoju inkarnaciju s istim izgledom  izvana, ali ultramodernim hardverom i softverom iznutra. Narudžbe se mogu napraviti već sada, a  isporuka  se  očekuje  u  petom  mjesecu.  Morao  sam  to  jednostavno  spomenuti  –  prve  ljubavi  se  teško zaboravljaju, makar to bila i računala. 

Vratimo se sada ponovo današnjoj temi. Ključne dijelove aplikacije možemo podijeliti u dvije velike  skupine:  1. Komponente ili kontrole  2. Blokove  Komponente su osnovni grafički dijelovi aplikacije, a međusobno se osim po izgledu razlikuju prije  svega po svojoj namjeni. Osnovna grupa komponenti pod nazivom Basic obuhvaća zbilja osnovne  komponente  karakteristične  za  moderna  korisnička  sučelja  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  nećemo  previše  baviti  njihovim  karakteristika.  U  istoj  grupi  kontrola  nalaze  se  još  dvije  složenije  kontrole,  a  one  ipak  zahtijevaju  poneku  dodatnu  riječ.  To  su Canvas i TinyDB. 

  Animation komponente: Preduvjet za njihovo korištenje je postojanje komponente Canvas.  Kontrola  Canvas  zamišljena  je  kao  dvodimenzionalno  područje  za  crtanje  likova  pomoću  programskog koda, odnosno za pomicanje sličica („sprites“). Budući da je to isto područje osjetljivo  na dodir, sasvim je razumljivo da predstavlja temeljni dio većine različitih igara razvijenih u ovom  alatu. Svaka od lokacija na komponenti Canvas označava se uobičajenim matematičkim zapisom za  dvodimenzionalne  površine  –  kao  koordinate  x  i  y.  O  važnosti  navedene  kontrole  u  razvoju  aplikacija  najbolje  govori  činjenica  da  je  u  zadnjoj  reviziji  alata  od  strane  Googlea  s  kraja  trećeg  mjeseca, veliki dio poboljšanja dodan upravo u Canvas kontrolu.  Neka od tipičnih 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  znači da se ne vidi tijekom izvođenja aplikacije, ali mora biti nacrtana na osnovnoj formi kako bi se  mogle koristiti njezine mogućnosti.  Kontrola  TinyDB  namijenjena  je  trajnom  spremanju  podataka  iz  aplikacije  u  mobilni  uređaj.  Prilikom svakog prekida izvršavanja aplikacije gubi se sadržaj svih korištenih kontrola te se ponovo  puni inicijalnim vrijednostima kod slijedećeg 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  uređaj,  te  njihovo  ponovno  čitanje  (na  primjer,  postavke aplikacije, stanje bodova u privremeno prekinutoj igri i slično). Upravo za takvu namjenu  zamišljena je kontrola TinyDB, odnosno njezine dvije jedine dostupne metode: 

StoreValue(oznaka, vrijednost)  Sprema  vrijednost  (niz  znakova  ili  popis)  pod  određenim  nazivom  u  spremište  na  mobilnom  uređaju. 

GetValue(oznaka)  Čita  vrijednost  sa  zadanim  nazivom  iz  spremišta.  U  slučaju  da  tražena  oznaka  ne  postoji  u  spremištu  (npr.  kod  prvog  pokušaja  čitanja  vrijednosti  na  novom  uređaju),  onda  metoda  vraća  prazan niz znakova.  U  slučaju  da  treba  obrisati  spremište  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   slijedećih  naziva: Camera,  ImagePicker,  Player,  Sound i VideoPlayer.  Svaka  od  kontrola  zadužena  je  za  upravljanje  odgovarajućim  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 kontroluPlayer).  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  različite vrste pokretanja grafičkih objekata (dakle najčešće igre). Na priloženoj slici uz tekst vidi se  da  je  preduvjet  za  korištenje  kontroli  iz  ove  grupe  upravo  postojanje  kontrole  Canvas.  Pomoću  svojstava  kontrola  poput Interval, Speed ili Rotates upravlja  se  učestalošću,  brzinom  i  rotacijom  „sličica ili loptica“ u vlastitoj aplikaciji. Budući da u jednoj aplikaciji može biti više Canvas kontrola,  nema  nikakvog  razloga  da  njihovim  inteligentnim  paljenjem  i  gašenjem  na  jednom  jedinom  zaslonu  (prije  istaknuto  ograničenje  trenutne  verzije  razvojnog  alata)  napravite  prilično  kompleksnu igru. 

  Social  komponente:  Zadužene  su  za  pristup  i  korištenje  različitih  socijalnih  podataka  iz  mobilnog  uređaja.  Posljednja  grupa  kontrola  koju  ćemo  spomenuti  u  današnjem  nastavku  su  kontrole  iz  grupe Social zadužene  za  pristup  i  korištenje  različitih  socijalnih  podataka  iz  mobilnog  uređaja  (ContactPicker,  EmailPicker,  PhoneCall,  PhoneNumberPicker,  Texting i Twitter).  Pomoću  ovih  kontrola moguće je postići da vlastite aplikacije upravljaju telefonskim pozivima, slanjem sms i/ili  email  porukama,  odnosno  korištenjem  usluga  Twittera  (npr.  korištenjem  metoda  poput DirectMessage, RequestDirectMessage ili RequestFriendTimeLine).  U  slijedećem  nastavku  napravit  ćemo  pregled  preostalih  dostupnih  kontrola,  a  onda  napraviti  nekoliko  složenijih  primjera,  koji  bi  trebali  prikazati  kako  ovim  alatom  doista  nije  problem  brzo  napraviti i znatno složenije aplikacije. 

  14. Alternativni pristup razvoju aplikacija II    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  slijedećih  naziva: Sensors, Screen  Arrangement, LEGO  MINDSTORMS, Other  stuff i Not ready for prime time. Krenimo redom. 

  Sensors komponente: Zadužene su za upravljanje različitim senzorima u mobilnom uređaju. 

Sensors komponente  Danas  je  sasvim  uobičajeno  da  pametni  telefoni  i  drugi  uređaji  temeljeni  na  Androidu  imaju  ugrađen  manji  ili  veći  broj  senzora,  koji  se  mogu  vrlo  djelotvorno  iskoristiti  u  različitim  vrstama  aplikacija  (najčešće  igrama).  Zbog  toga  je  razvijeno  nekoliko  posebnih  komponenti  za  relativno  jednostavnu  podršku  takvoj  vrsti  hardvera.  Sve  komponente  su  nevidljive  tijekom  izvođenja,  ali  moraju biti uključene u aplikaciju da bi se mogle iskoristiti njihove mogućnosti.  Komponenta AccelerometerSensor zadužena  je  za  interakciju  softvera  sa  senzorom  za  mjerenje  pomicanja uređaja po sve tri osi koordinatnog sustava. Od tuda dolaze nazivi najvažnijih svojstava:  XAccel,  YAccel,  Zaccel.  Pomoću  svojstva  Available  programer  može  provjeriti  jesu  li  navedeni  senzor  uopće  dostupni  u  uređaju,  a  svojstvom  Enabled  upravljati  dozvolom  korištenja  senzora.  Događajem AccelerationChanged može se precizno reagirati na pomicanje uređaja po bilo kojoj od  navedene tri osi (parametara događaja), dok je nešto „grublji događaj“ Shaking namijenjen mnogo  jednostavnijem zadatku – običnoj provjeri „drmanja“ uređajem. Drugi događaj se najčešće može  upotrijebiti za efektan prekid izvođenja različitih operacija u aktivnoj aplikaciji.  Druga nevidljiva kontrola iz iste skupine je LocationSensor, a namijenjena je dobijanju geografske  pozicije  mobilnog  uređaja,  ako  je  u  njega  ugrađen  odgovarajući  GPS  prijemnik  (svojstvo  HasLongitudeLatitude).  Softverski  je  podržano  mjerenje  nadmorske  visine  (svojstvo  HasAltitude),  ako i takva mogućnost postoji u hardveru. Ostalim dostupnim svojstvima može se dobiti vrijednost  svake od navedenih tri dimenzija, dok su događaji LocationChanged te StatusChanged zaduženi za  reakciju aplikacije na promjene pozicije uređaja u prostoru, odnosno na promjene načina mjerenja  pozicije (izravno dobijeni GPS podaci ili podaci dobijeni od mrežnog operatora). 

Zadnja  komponenta  iz  grupe OrientationSensor zadužena  je  za  provjeru  orijentacije  uređaja  u  prostoru (svojstva Roll, Pitch i Yaw te događaj OrientationChanged). Ova sofverska komponenta se  u kombinaciji s pripadajućim senzorom koristi u različitim aplikacijama za promjenu načina prikaza  podataka ovisno o promjeni orijentacije uređaja (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)  zadužene  su  za  jednostavnije  raspoređivanje  ostalih  komponenti  po  zaslonu  uređaja.  Kao  što  im  i  nazivi  govore,  svaka  od  komponenti  je  zadužena  za  jednu  vrstu  rasporeda osnovnih kontrola. Osim za početno raspoređivanje kontrola sve tri komponente mogu  se  također  iskoristiti  za  njihovo  jednostavnije  premještanje  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 predviđene su za upravljanje različitih dijelovima  poznatog  Lego  kompleta  za  učenje  robotike  pomoću  nekog  od  Android  uređaja.  Iskreno,  nismo  imali priliku ni zadovoljstvo isprobati kako sve to skupa djeluje u praksi, pa se zato za sada nećemo  previše ni baviti ovim dijelom razvojnog alata. Nadamo se da ćemo u ne tako dalekoj budućnosti  ipak biti u prilici isprobati simbozu Lego i Google proizvoda. 

Other stuff komponente 

  LEGO MINDSTORMS komponente: Zadužene su za povezivanje s Lego „očvrsjem“.  Šaroliko društvo softverskih komponenti iz ove grupe nikako se po svojoj namjeni ne može dovesti  u izravnu vezu, zbog čega je cijela grupa dobila naziv koji označava takvu raznolikost.  Jedna  od  najvažnijih  komponenti  iz  grupe  je  komponenta ActivityStater.  Zadužena  je  za  pokretanje  nekoliko  različitih  aktivnosti  na  uređaju:  drugih  aplikacija  napravljenih  u  istom  alatu  ako takve postoje u uređaju (čime se može izbjeći dosta ozbiljno ograničenje o korištenju jednog  zaslona ekrana po aplikaciji), aplikacije zadužene za upravljanje kamerom (ako je kamera ugrađena  u  mobilni  uređaj),  pretraživanje  web  sadržaja,  postavljanje  preglednika  na  točno  određenu  web  adresu, odnosno postavljenje točno određene lokacije na karti. Zbog toga komponenta podržava  različite  načine  vlastitog  pozivanja.  Evo  primjera  iz  prateće  dokumentacije  zaduženog  za  pretraživanje 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 zadužena je za jednostavno čitanje običnih jednodimenzionalnih, ali  i  sve  popularnijih  dvodimenzionalnih  bar  kodova  (korištenjem  metode  DoScan,  svojstva  Result  i  događaj  AfterScan).  Da  je  takva  komponenta  jednostavno  neizostavna  u  modernim  softverskim  rješenjima,  autor  teksta  može  posvjedočiti  iz  prve  ruke.  Na  nedavno  završenoj  Microsoftovoj 

konferenciji  Windays  11  u  Rovinju,  osim  očekivanih  mjesta  za  takvu  vrstu  označavanja,  dvodimenzionalni  bar  kodovi  su  se  mogli  primijetiti  i  na  majicama  nekih  sudionika.  Naoružani  Android  uređajem  te  odgovarajućom  aplikacijom  više  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 sličnog naziva BluetoothServer i BluetoothClient zadužene su za podršku obiju  strana  koje  sudjeluju  u  Bluetooth  komunikaciji   (servera  i  klijenta).  Popis  dostupnih  metoda,  svojstava i događaja 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 možemo detaljnije pozabaviti njihovim korištenjem. Kako je potpisnik ovih redova  u  bliskoj  prošlosti  imao  prilike  raditi  na  Bluetooth  orijentiranom  projektu  namijenjenom  starim  dobrim Java MIDP uređajima, osobno može potvrditi da je korištenje Google tehnologije na istom  području  bitno  jednostavnije.  Budući  da  sami  razvojni  inženjeri  tvrde  da  se  na  ovom  segmentu  razvojnog alata još uvijek intenzivno radi, ipak treba malo sačekati sa završnom ocjenom.  Komponenta Notifier omogućava  prikaz  različitih  vrsti  obavijesti  korisniku  aplikacije  odnosno  trajno  bilježenje  takvih  informacija  u  svrhu  kasnije  analize.  Za  to  je  pripremljeno  nekoliko  metoda   (ShowMessageDialog,  ShowChooseDialog,  ShowTextDialog,  ShowAlert  i  LogError)  čije  korištenje rezultira različitim načinom prikaza informacija korisniku odnosno njihovom bilježenju.  Na  raspolaganju  su  također  dva  događaja:  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) zamišljene su kao podrška  za izradu govorno orijentiranog korisničkog sučelja u vlastitim Android aplikacijama. Prva kontrola  namijenjena  je  razumijevanju  izgovorenog,  dok  je  druga  zadužena  za  suprotan  proces  – 

izgovaranje  napisanog  teksta.  Koliko  to  sve  skupa  radi  ili  ne  radi  dobro  s  različitim  govornim  jezicima  možete  isprobati  sami.  Obje  komponente  su  vrlo  jednostavne  za  korištenje,  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  korištena  u  serijalu  o  naprednom  programiranju  Windows  aplikacija,  objavljenom  u  više  prethodnih brojeva vašeg 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 inženjeri, pa su kao takve podložne različitim promjenama dok ne stignu u  fazu dovršenog proizvoda. Trenutno su u tu grupu svrstane slijedeće komponente:  FusionTablesControl – korištenje kartografskih prikaza u kombinaciji s FusionTables tehologijom.  GameClient –  povezivanje  aplikacija  (najčešće  igara)  s  odgovarajućim  serverima  za  „udružene  NEzločinačke poduhvate“.  SoundRecorder – bilježenje i pohranjivanje zvučnih zapisa.  TinyWebDB – komunikacija s web servisima zbog dvosmjerne razmjene podataka.  Voting – osnova za buduće glasačke listiće u „Android demokraciji budućnosti“. 

Kako  su  sve  nabrojane  komponente  iz  ove  grupe  u  razvoju,  za  sada  se  nećemo  previše  ni  baviti  njima.  Ipak  moramo  priznati  da  nas  strašno  zanima  vrlo  novi  svijet  u  kojem  ćemo  praktično  trenutno moći odlučivati o bitnim stvarima u zemlji, a ne čekati da to radimo od izbora do izbora.  Nažalost, ipak bi se mogli okladiti na prilično velike iznose kako će takvu tehnologiju prije prihvatiti  različiti „reality“ spektakli nego državna uprava. Živi bili pa vidjeli.  Ovime  je  završeno  predstavljanje  najvažnijih  segmenata  Googleovog  razvojnog  alata  za  neprogramere.  Preostalo  je  da  pomoću  njega  probamo  napraviti  jednu  složeniju  aplikaciju  kao  demonstraciju kako različite komponente surađuju u praksi. 

  15. Izrada složenijih aplikacija    Nakon  što  smo  u  prošlih  nekoliko  nastavaka  predstavili  najvažnije  dijelove  Googleovog  alata  za  razvoj  aplikacija  namijenjenog  korisnicima  neprogramerima,  odnosno  malo  manje  vještim  programerima,  došao  je  trenutak  da  pokažemo  kako  se  ti  dijelovi  zaista  koriste  u  vlastitim  aplikacijama.  Za  razliku  od  prve  demo  aplikacije,  kad  smo  vrlo  detaljno  riječju  i  slikom  opisivali  kako  se  izvode  sve  operacije  potrebne  da  se  dobije  dovršena  aplikacija,  u  današnjem  nastavku  ćemo samo naznačiti glavne smjernice u pripremi aplikacije, a na vama je da probate sami dovesti  projekt  u  funkcionalno  stanje.  Tako  ćemo  odmah  pripremiti  i  svojevrsnu  vježbanju  u  korištenju  alata.  Iako se danas mobilni uređaji koriste za izvođenje više desetaka različitih operacija – od planiranja  vlastitog vremena, preko slušanja muzike i gledanja filmova pa sve do igranja različitih vrsta igara,  mogućnost  izvođenja  starog,  dobrog  telefonskog  poziva  (ili  bar  odgovaranja  na  njega)  još  uvijek  ostaje jedna od najbitnijih namjena većine mobilnih telefona. Zato ćemo u prvom primjeru nešto  složenije  aplikacije  demonstrirati  što  možemo  napraviti  u  Googlevom  razvojnom  alatu  po  tom  pitanju, ako ne želimo koristiti već ugrađene mogućnosti u sam uređaj.  Pretpostavka za uspješno izvođenje slijedeće aplikacije na konkretnom Android uređaju je da taj  uređaj  podržava  izvođenje  telefonskih  poziva,  a  ne  samo  različite  internet  orijentirane  načine  vlastitog  korištenja  (pregled  web  stranica,  razmjena  email  poruka  i  slično).  Također,  u  spremište  kontakata u uređaju 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,  može  se  dogoditi  da  na  nekim  uređajima  primjer  ipak  ne  djeluje  kako  se  očekuje.  Razloge  treba  tražiti u tome što u trenutnoj fazi razvoja alat App Inventor for Android još uvijek nije ni testiran ni  optimiziran  za  sve  dostupne  uređaje  na  tržištu.  Googleovi  razvojni  inženjeri  obećavaju  kako  će  takve  „porođajne  muke“  biti  riješene  u  bliskoj  budućnosti  kad  razvojni  alat  više  ne  bude  u  fazi  svojevrsnog testiranja.  Za uspostavu telefonskog poziva iz Android uređaja, 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 korišten 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  početku 

potrebne samo dvije: komponenta PhoneCall iz grupe Social te komponenta Button iz grupe Basic.  U nastavku teksta ćemo slične konstrukcije skraćeno pisati Social ‐> PhoneCall, odnosno  Basic ‐>  Button. 

  Social  ‐>  Phone  Call:  Temeljna  komponenta  za  izvođenje  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  slučaju  jednostavnijih  projekta  takvi  nazivi  se  mogu  izravno  koristiti  za  dovršetak  projekta,  ali  dobra praksa iskusnijih programera predlaže njihovo preimenovanje u daleko razumljivije nazive,  kako  bi  se  kasnije  olakšalo  snalaženje  u  projektu.  Što  se  u  nekom  projektu  koristi  više  različitih  komponenti (to vrijedi i za sve druge razvojne alate), to je važnije imati smislenije nazive, da bi se  programer što brže i jednostavnije mogao snaći u naknadnoj analizi i izmjeni programskog koda.  Dobro, kod alata App Inventor zapravo ni ne možemo govoriti baš o „pisanju programskog koda“,  jer  je  prije  riječ  o  nećemu  nalik  slaganju  komada  slagalice  sastavljene  od  dostupnih  događaja  i  metoda  korištenih  komponeti,  ali  nema  nikakvog  razloga  da  ignoriramo  pravilo  o  imenovanju  komponenti.  Preimenovanje  komponente  postavljene  na  osnovni  zaslon  projekta  izvodi  se  njezinim  označavanjem, te klikom na gumb  u razvojnoj okolini alata.  Za potrebe ovog projekta  komponentu  PhoneCall1  preimenovali  smo  u TelefonskiPoziv,  a  komponetu  Button1  u UspostaviPoziv. Još jednom ponavljamo – budući da bi rad na ovom projektu trebao ujedno biti  vaša samostalna vježba korištenja Googleovog razvojnog alata, nazive komponenti možete izabrati  prema  vlastitim  sklonostima.  Za  komponentu  TelefonskiPoziv  može  se  izmijeniti  i  početna  vrijednost svojstva PhoneNumber na željeni broj pozivatelja (ako se pozivi najčešće upućuju na taj  broj),  dok  komponenti  UspostaviPoziv  treba  izmijeniti  svojstvo Text,  kako  bi  zamjena  za  podrazumijevanu vrijednost Text for Button1preciznije pokazivala namjenu gumba. 

U  ovom  trenutku  je  dovršeno  „crtanje“  korisničkog  sučelja,  a  sad  preostaje  još  samo  to  da  se  „napiše   odgovarajući  programski  kod“,  odnosno  dovrši  slagalica  u  inovativnom  Googleovom  sučelju  za  tu  namjenu  (o  čijem  korištenju  je  bilo  više  riječi  u  prvom  nastavku  serijala).  Sasvim  konkretno – u ovom slučaju potrebno je napraviti povezivanje bloka Click iz kontrole UpostaviPoziv  s  blokomMakePhoneCall iz  kontrole  TelefonskiPoziv.  Na  taj  način  dovršena  je  prva  verzija  aplikacije koja omogućava uspostavu telefonskog poziva iz Android uređaja s upisanim odredišnim  brojem nakon što korisnik pritisne kontrolu (gumb) UspostaviPoziv. Djelovanje programa možete  (ili ipak ne možete) provjeriti sami na vlastitom komadu Android hardvera, već prema tome kako  je on trenutno podržan od strane Googleovih razvojnih inženjera.  Na  trenutnom  stupnju  razvoja  naše  nove  aplikacije  trebalo  bi  biti  moguće  uspostaviti  telefonski  poziv,  ali  aplikacija  još  uvijek  „nema  pojma“  o  podacima  zapisanim  u  bazu  kontakata  u  okviru  samog  uređaja,  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  učestalost biranja dostupnih brojeva iz baze kontakata. Zato aplikaciju treba dodatno  proširiti tako da postane „svjesna“ ranije pripremljenih telefonskih brojeva. 

  Dovršeno  sučelje  aplikacije  za  telefoniranje:  Omogućava  korištenje  podataka  iz  spremišta  kontakata u samom uređaju.  U drugoj verziji aplikacije ćemo na osnovni zaslon aplikacije dodati još jednu novu kontrolu: Social  ‐> PhoneNumberPicker, a onda joj izmijeniti predloženi naziv u IzaberiBroj, odnosno tekst koji se  prikazuje  na  kontroli  s  početne  vrijednosti Text  for  PhoneNumberPicker1 za  hrvatsku  verziju  aplikacije primjereniji oblik Izaberi broj. Kontrola tipa PhoneNumberPicker predstavlja svojevrsnu  verziju običnog gumba, s tom razlikom da pritisak na kontrolu automatski izaziva prikaz podataka  iz postojeće baze kontakata u uređaju. 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 odgovarajuća „slagalica“ za upravljanje izvođenjem 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  odgovarajućeg  parametra  (izabranog  telefonskog  broja)  između  te  dvije  kontrole,  što  se  izvodi  dodatnim  vezanjem  bloka PhoneNumber kontrole  IzaberiBroj  s  prije  navedenim  blokom  MakePhoneCall.  Ovim  korakom,  ako  je  sve  pravilno  izvedeno,  trebala  bi  biti  dovršena  druga  faza  u  razvoju  aplikacije.  Sada je aplikacija spremna za izvođenje telefonskih poziva na temelju prije spremljenih podataka u  bazu kontakata.  U  smislu  poboljšanja  grafičkog  izgleda  aplikacije  moguće  je  u  aplikaciju  dodati  još  poneki  detalj.  Premda se u trenutnoj verziji broj iz baze kontakata zaista može izabrati kao temelj za telefonski  poziv,  korisnik  aplikacije  još  uvijek  ne  može  vidjeti  o  kojem  je  telefonskom  broju  riječ.  Da  ne  spominjemo  nemogućnost  prikaza  slike  vlasnika  telefonskog  broja,  ako  takva  postoji  u  uređaju.  Unapređenje  korisničkog  sučelja  aplikacije  može  se  postići  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,  također  svojstvom  gumba  UspostaviPoziv.  Navedenim  operacijama  je  aplikacija  poboljšana  u  vizualnom  smislu  pa  osim  zahtijevane funkcionalnosti sada posjeduje i odgovarajuće korisničko sučelje.  Trenutna verzija aplikacija se i dalje može nadograđivati, pa evo nekoliko ideja koje možete 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 sučelju, da bi to zaista mogli napraviti. Ova  točka ne bi trebala biti prezahtijevna za realizaciju.  2. Podaci o uspostavljenim pozivima mogli bi se sačuvati za kasniju analizu. Kako je u ovom  slučaju riječ o malo zahtijevnijem postupku, o njemu će više riječi biti neki drugi put.  Na  kraju,  ambiciozniji  čitatelji  mogu  probati  sami  napraviti  sličan  projekt  ispočetka  tako  da  se  umjesto  uspostave  telefonskog  poziva  izvodi  slanje  dobre,  stare  SMS  poruke.  U  tom  slučaju  temeljnu kontrolu za rad aplikacije (Social ‐> PhoneCall), treba zamijeniti nečim drugim, ali vam to  sada nećemo otkriti, nego vam ostavljamo da na temelju prethodnih nastavaka serijala i vlastitog  eksperimentiranja  sami  pronađe  o  čemu  je  riječ.  U  svakom  slučaju  preporučamo  vam  da  sami  probate „odraditi“ cijeli posao oko današnje aplikacije, kako bi mogli lakše pratiti slijedeći projekt,  gdje ćemo još manje detaljizirati oko biranja kontrola i njihovog korištenja nego što je to bi slučaj  danas. Budući da ćemo raditi na mnogo složenijem projektu jednostavno moramo pretpostaviti da  su vam dobro poznate osnovne stvari oko korištenja Googleovog alata za neprogramere. 

       

16. Korištenje kartografskih servisa    U  današnjem  završnom  nastavku  svojevrsnog  podserijala  o  korištenju  Googleovog  alata  za  brzo  prototipiranje aplikacija, pokazat ćemo kako se u okviru tog alata koriste kartografske mogućnosti  Googleovih  servisa,  jedne  od  najčešće  korištenih  tehnologija  u  aplikacijama  na  mobilnim  uređajima. 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 najvećih ograničenja Googleovog razvojnog alata za neprogramere u tome što  se  unutar  jedne  aplikacije  može  koristiti  samo  jedan  raspored  kontrola.  Upravo  sposobnošću  pozivanja  jedne  aplikacije  iz  druge  može  se  zaobići  spomenuto  ograničenje.  Način  korištenja  kartografskih  servisa  na  kojem  se  temelji  današnji  tekst  prikazan  je  u  Googeovom  primjeru  pripremljenom od strane profesora Davida Wolbera sa sveučilišta u San Franciscu.  Prije  nego  što  nastavimo  s  detaljnijim  objašnjavanjem  primjera  istaknimo  na  ovom  mjestu  još  jednu bitnu mogućnost operativnog sustava Android u pogledu izrade rješenja koje se sastoji od  većeg  broja  sastavnih  dijelova.  Dok  za  pozivanje  drugog  dijela  aplikacije  iz  početnog  dijela  treba  koristiti komponentu ActivityStarter, povratak unatrag se izvodi potpuno automatski. Dovoljno je  samo izabrati standardnu operaciju operativnog sustava za tu namjenu, to jest odgovarajuću tipku  na samom uređaju. 

  Prvi dio aplikacije (sučelje): 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  početne slike programa, izbor triju različitih odredišta za prikaz na karti, te na kraju komponente za  pokretanje  dodatne  kartografski  orijetirane  aplikacije.  Prve  dvije  kontrole  ne  bi  trebale  biti 

posebno teške za korištenje, tako da ih nećemo ni posebno opisivati. Uostalom, kontrolu za prikaz  slika koristili smo već u prvom, najtrivijalnijem primjeru korištenja alata.  Nešto više vremena posvetit ćemo korištenju komponente ActivityStarter, zato što ona zahtijeva  oblik znanja kakav je uobičajen u krugovima pravih Android programera, ali nije baš uobičajen za  korisnike  neprogramere.  Drugim  riječima,  druga  komponenta  cjelokupnog  rješenja  mora  se  pozvati iz prve prema točnom definiranom protokolu, što bi u ovom slučaju imalo otprilike slijedeći  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):  Najvažniji  dio  povezan  je  aktivnostima  kontrole  ActivityStarter.  Programski blokovi povezani s aplikacijom podijeljeni su u dva dijela. Prvi dio je zajedno s pratećim  deklaracijama vrijednostima zadužen za pripremu početnog izgleda aplikacije (vidi prateću 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 izvođenje programskog bloka ListPicker1.AfterPicking.  Na ovom mjestu dolazimo do male dodatne komplikacija pa je treba objasniti nešto detaljnije. Da  bi se pomoću komponente ActivityStarter mogla uspješno pokrenuti druga komponenta za prikaz  nekog mjesta na mapi, potrebno je komponenti prenijeti adresu u točno propisanom formatu, a to 

u ovom slučaju znači popunjavanje svojstva ActivityStater.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 zadužen  za  rukovanje  nizovima  znakova  (make  text).  U  slučaju  odabira  druge  od  dostupnih  vrijednosti  dobije se konačna vrijednost: geo:0,0?q=’Musee du Louvre’. 

  Izvođenje aplikacije: Osnovni oblik izvođenja aplikacije u Android emulatoru.  Sad  je  konačno  sve  spremno  za  pozivanje  drugog  dijela  aplikacije,  pa  prvi  dio  aplikacije  zaista  predaje  kontrolu  izvođenja  drugom  dijelu  na  ranije  opisani  način.  Po  želji  se  (to  smo  isto  već  spomenuli)  možete  vratiti  na  prvi  dio  korištenjem  standardne  operacije  u  operativnom  sustavu  Android.  „Sirovi“  oblik  kartografskog  prikaza  kakav  je  u  ovom  trenutku  prisutan  u  aplikaciji  može  se  dalje  nadograđivati tako da se modulu zaduženom za prikaz objekta mnogo preciznije zada način prikaza  nekog mjesta prema sintaksi propisanoj od strane Googlea. Na primjer, za znatno atraktivniji način  prikaza svih triju lokacija mogla bi se navesti „malo složenije 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+Eiffel,+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.002499,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.349 111&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=74fLTqeYdgkPYj6KKLlqgQ&cbp=12,63.75,,0,‐ 35.58  U slučaju da želite provjeriti sami kako sve to skupa lijepo djeluje u praksi, a nemaze ni vremena ni  volje da ispočetka razvijate cijelu aplikaciju, možete krenuti linijom manjeg otpora te usmjeriti svoj  preglednik na adresu http://appinventor.googlelabs.com/learn/tutorials/maptour/maptour.html 

Kontinuirani razvoj alata 

  Napredno  izvođenje  aplikacije:  U  prikaz  su  uključene  dodatne  opcije  za  prikaz  slika  na  zadanoj  lokaciji.  U razdoblju od prvog spominjanja razvojnog alata App Inventor for Android u ovom serijalu, pa do  današnjeg nastavka, Googleovi razvojni inženjeri marljivo su radili na njegovim unapređenjima (a  rade i dalje). Budući 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 slijedeći put pokrene nakon njegovog ažuriranja na Googleovom serveru.  Osim ispravke uočenih pogrešaka prijavljenih od strane korisnika, izgleda da se najintenzivnije radi  na daljnjim doradama komponenti u okviru kolekcije Other Stuff. Komponenta Web zamišljena je  tako da osigurava dodatne mogućnosti 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  moguće  pozivati  određene  skupine  API  funkcija  izravno  preko  Web  komponente.  Na  primjer,  korištenjem  poziva  funkcija  iz  Yahoo  Finance  API  biblioteke prilično je jednostavno u Android aplikaciju dodati prikaz različitih poslovnih informacija  o čijoj pripremi i pouzdanosti brine Yahoo.  Iako  to  nema  izravne  veze  s  temom  današnjeg  teksta,  za  eventualno  zainteresirane  ipak  spomenimo kako se sve potrebne informacije o korištenju Yahoo Finance API tehnologije nalaze na  adresi:http://www.gummy‐stuff.org/Yahoo‐data.htm 

  Web komponenta u akciji: Izravno korištenje Yahoo Finance API tehnologije.  Za  sada  toliko  o  ovoj  temi.  Nadamo  se  da  vas  je  sve  do  sada  napisano  potaklo  da  počnete  razmišljati o razvoju vlastitih Android aplikacija, čak i ako niste programer, ili ako to nikada niste ni  mislili  postati.  Kad  savladate  razvojni  alat  za  neprogramere  možda  ćete  poželjeti  da  se  u  budućnosti počnete baviti i „pravim“ Google Android programiranjem. Na njega ćemo se ponovo  vratiti u slijedećem nastavku, kako bi pokazali još nekoliko naprednijih tehnika korištenja osnovnog  SDK alata. 

   

17. Što je novo u 3.x izdanjima    Da čovjek jednostavno ne povjeruje kako vrijeme brzo leti – od početka serijala o programiranju  korištenjem  Googleovog  razvojnog  alata  Android  SDK,  već  je  prošlo  više  od  godinu  dana,  a  u  međuvremenu  se  je  mnogo  toga  dobrog  dogodilo  sa  samim  alatom  u  smislu  proširenja  njegovih  mogućnosti. Za to je prije svega zaslužna prava eksplozija pojave novih modela tablet računala, 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“, napišimo nekoliko dodatnih riječi 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  dugoročnije korištenje, važno je znati što vam očekuje u budućnosti.  Prvo,  i  trenutno  najvažnije,  kao  novu  web  adresa  za  online  korištenje  alata  App  Inventor  for  Android  trebati  će  ubuduće  koristiti www.appinventorbeta.com umjesto  dosadašnje  adrese appinventor.googlelabs.com.  U  duhu  vođenja  brige  za  postojeće  korisnike  vlastitih  proizvoda,  uobičajenom  kod  velikih  IT  poduzeća,  sve  postojeće  aplikacije  registriranih  korisnika  sačuvane  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  korisničkom  sučelju  optimizirane  za  moderne  tablet  uređaje. 

Drugo,  te  jednako  važno  za  buduće  korištenje  alata,  Google  prestaje  s  izravnim  radom  na  održavanju i razvoju alata App Inventor for Android. To na sreću ne znači da će alat nestati, nego  da  on  prelazi  u  „open  source“  kategoriju.  Za  budući  status  alata  brigu  će  voditi  novoosnovani Center for Mobile Learning u okviru MIT Media Laba, te biti pod stalnim nadzorom  tri  profesora  s  istog  sveučilišta:  Hal  Abelson,  Eric  Klopfer i Mitchel  Resnik.  Prva  osoba  iz  nabrojene trojke zaslužna je za predlaganje  i pokretanje čitavog projekta 2008 godine zajedno s  poduzećem  Google,  iz  laboratorija  drugog  profesora  potekla  je  prva  verzija  razvojnog  alata,  i  to  upravo  na  temelju ideje  zadnjeg  imena  s  popisa.  Dovršetak  cijelog  postupka  očekuje  se  do  kraja  godine, a postojeći korisnici alata će redovito dobijati informacije o svim promjenama. 

Novosti u „osnovnom“ Android sustavu  Nakon razjašnjavanja trenutne i buduće situacije s alatom za brzo prototipiranje Android aplikacija,  vratimo se sada na osnovni razvojni alat Android SDK. Od trenutka početka pisanja serijala, kojeg  upravo  čitate,  razvojni  alat  je  promijenio  svoju  prvu  brojčanu  oznaku  verzije  s  2  na  3,  što  uvijek  znači da je došlo do bitnih promjena u nekom softverskom paketu. Kao što smo to već spomenuli  na samom početku ovog teksta, ključni okidač za takve promjene je sveopća „zaluđenost“ tablet  računalima, kako od strane proizvođača, tako i od strane korisnika mobilnih uređaja. Budući da se  po  dijelu  svojih  hardverskih  karakteristika  takvi  uređaji  razlikuju  od  mobilnih  telefona,  Android  sustav doživio je bitne promjene što simbolizira nova početna oznaka verzije.  Pogledajmo  prvo  što  se  najvažnijeg  dogodilo  sa  stanovišta  krajnjeg  korisnika.  Najvažnije  su,  naravno, promjene na dimenzijama i rezoluciji zaslona, jer su ove vrijednosti u pravilu dosta veće  nego kod mobilnih telefona. Povećanje zaslona pretpostavka je za dodatnu zabavu u korisničkom  sučelju, kako u pogledu redizajna postojećih dijelova, tako i u pogledu dodavanja potpuno novih  dijelova  sučelja  poput  sistemske  ili  akcijske  trake.  Kad  govorimo  o  promjenama  u  korisničkom  sučelju onda se to odnosi na dio vidljiv na zaslonu, ali i na sistemske, grafički orijentirane module u  pozadin,i koji su također morali doživjeti brojne promjene.  Na većem zaslonu uređaja mogla se između ostalog redizajnirati softverska tipkovnica namijenjena  unosu znakova. Tipkovnica je jednostavno postala udobnija te brža za korištenje nego prije, jer se  do  dijela  tipki  više  ne  mora  dolaziti  zaobilazno.  Još  jedna  bitna  stvar  povezana  s  korisničkim  sučeljem  je  poboljšana  mogućnost  upravljanja  operacijama  označavanja,  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 ugrađenom kamerom.  Prva od prije spomenutih traka, smještena 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 može sakriti u  slučaju da neka aplikacija treba iskoristiti cijeli dostupni prostor zaslona. Još jedan važan zadatak  sistemske trake je upravljanje višezadatkovnim radom preko popisa nedavno korištenih aplikacija  (Recent  Apps).   Druga  traka  (akcijska)  nalazi  se  na  vrhu  zaslona,  a  izgled  i  djelovanje  ovise  joj  o  kontekstu  izvođenja  aplikacije,  što  znači  da  promjenom  njezinog  izgleda  upravlja  aplikacija,  a  ne  sam Android sustav.  Od  ostalih  novosti  svakako  treba  spomenuti  nove  mogućnosti  povezivanja  tablet  računala  s  vanjskim  uređajima  pomoću  Media/Picture  Transfer  Protocola,  odnosno  povezivanje  prave  tipkovnice  s  uređajem  kako  bi  se  još  više  olakšalo  upisivanje  teksta.  Na  kraju  tu  je  i  nekoliko  poboljšanja standardnih aplikacija – preglednik, elektronička pošta, kamera, galerija i imenik. U još  novijim verzijama nasljednicama s oznaka 3.1 i 3.2 uvedena su dodatna unapređenja u korisničkom  sučelju  te  povezivanju  s  vanjskim  uređajima  (npr.  različiti  dodaci  za  igru)  i  Wi‐Fi,  dok  je  sam  Android sustav optimiziran za brojne tablet uređaje, koji su se na tržištu pojavili u međuvremenu.  U  ovom  nabrajanju  ne  smijemo  nikako  zaboraviti  na  još  jednu  promjenu,  budući  da  ona  nije  vidljiva na prvi pogled, ali pridonosi ukupnom zadovoljstvu korištenja Android platforme. Osim što  u verziji 3.x Android podržava istovremeno korištenje većeg broja aplikacija, sada se te aplikacije  mogu  izvoditi  i  na  većem  broju  procesora  odnosno  jezgri,  ako  je  takva  hardverska  konfiguracija  ugrađena u mobilni uređaj. Android uređaji tako će uskoro moći rješavati najsloženije probleme, a  da ne spominjemo kako će dobro na njima izgledati različite igre. U međuvremenu su se na tržištu  zaista pojavili višejezgreni uređaji, tako da ovo više nije samo teoretska mogućnost sustava.  Sad kad smo ukratko naveli što je sve novo u sustavu sa stanovišta krajnjeg korisnika, pogledajmo  što to zapravo znači za programere, ako žele pisati optimizirane aplikacije za nove verzije Andrioda  s  početnom  verzijom  3.  Svaka  nova  verzija  Androida  sa  sobom  donosi  izmijenjeno  programsko  sučelje  s  određenim  brojem  novih  poziva  API  funkcija,  odnosno  izmjene  u  načinu  korištenja  postojećih  funkcija.  Budući  da  su  se  u  verziji  3.0  (i  novijima)  pojavili  potpuno  novi  dijelovi  korisničkog sučelja, kao što je akcijska traka ili sistemska traka, najvažnije API promjene povezane  su  upravo  s  tim  dijelovima.  Drugim  riječima,  dobili  smo  sasvim  dovoljno  građe  za  još  nekoliko  nastavaka serijala u kojima bi se demonstrirale najnovije mogućnosti platforme.  Navedimo  sada  primjer  dijela  programskog  koda  namijenje  korištenju  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  složenijem  primjeru kojeg počinjemo izrađivati slijedeći 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;  }  }  }   

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF