Professional Documents
Culture Documents
Ebook Android PDF
Ebook Android PDF
1/227
Odtwarzanie Video..................................................................................................................278
Nagrywanie video...................................................................................................................281
Grafika 2D...............................................................................................................................286
Bluetooth czyli niebieskie pogaduszki.................................................................................293
2/227
Instalacja i konfiguracja
Instalacja
Do rozpoczcia przygody z programowaniem dla platformy Android bd nam potrzebne dwie
rzeczy: Java Developer Kit, oraz zestaw Android SDK. JDK to po prostu Java z narzdziami dla
programistw (np. kompilator Javy). Android SDK zawiera kompilator programw na platform
Android, narzdzia do tworzenia i zarzdzania wirtualnymi urzdzeniami (na ktrych moemy
testowa nasze programy), a take rodowisko programistyczne Eclipse. Eclipse jako taki jest
bardzo popularnym IDE wrd programistw Javy, tutaj dostajemy jego nieco zmodyfikowan pod
programowanie na Androida wersj. Nic nie stoi na przeszkodzie abymy uywali innych
rodowisk, ale wykorzystanie takiej spreparowanej, gotowej wersji Eclipse bdzie najprostszym
rozwizaniem.
W pierwszej kolejnoci pobieramy i instalujemy JDK. Moemy je pobra ze strony
http://www.oracle.com/technetwork/java/javase/downloads/index.html
Wybieramy Java Platform(JDK), pierwsz od lewej. Druga rni si od pierwszej dodatkowym
narzdziem NetBeans ktry nie bdzie nam tutaj potrzebny.
3/227
Po klikniciu przechodzimy do ekranu wyboru wersji. Wybieramy wersj dla naszego systemu
operacyjnego.
4/227
W katalogu eclipse znajduje si IDE z ktrego bdziemy korzysta, sdk to narzdzia takie jak
kompilator. Cao warto umieci w jakim katalogu ktrego nie bdziemy pniej nigdzie
przenosi, poniewa bdziemy za moment dodawa podkatalogi katalogu sdk do zmiennej
rodowiskowej PATH. Zmiana pooenia tego katalogu wizaaby si z koniecznoci ponownej
modyfikacji zmiennej rodowiskowej.
5/227
Aby ustawi zmienn rodowiskow w systemie Windows, klikamy prawym przyciskiem myszy na
ikon Mj Komputer, wybieramy Waciwoci. Przechodzimy do zakadki zaawansowane i
klikamy przycisk Zmienne rodowiskowe. Zaznaczamy zmienn Path spord zmiennych
systemowych i klikamy edytuj. Do zmiennej dopisujemy cieki do podkatalogw tools,
platform-tools oraz build-tools katalogu jdk rozdzielajc cieki rednikami. Zatwierdzamy zmiany.
6/227
7/227
8/227
Gdy zaczniemy tworzy nieco bardziej zaawansowane programy, moe okaza si e domylne
ustawienia pamici dla Eclipse s niewystarczajce i rodowisko zacznie chodzi bardzo wolno,
wiesza si. Warto wic ju na starcie zadba o to, by Eclipse mia wystarczajc ilo pamici.
Aby to skonfigurowa, edytujemy plik eclipse.ini znajdujcy si w katalogu Eclipse. Modifikujemy
parametry pamiciowe np. tak:
9/227
10/227
11/227
Po zatwierdzeniu powiniene zobaczy taki widok. Takich urzdze moemy stworzy dowoln
ilo i np. testowa program na rnych wielkociach ekranu.
12/227
13/227
14/227
Przyjrzyjmy si jeszcze zawartoci katalogu res. Cokolwiek wrzucisz do tego katalogu, stanie si do
zasobem widocznym i dostpnym z dowolnego miejsca aplikacji. To wanie tutaj powinny trafi
wszystkie obrazki, filmiki etc. Katalogi drawable-xxxxx s przeznaczone na obrazki. Jest ich kilka
bo moemy mie kilka wersji tego samego obrazka dla rnych rozdzielczoci. Nazwy s dosy
intuicyjne do katalogu drawable-ldpi wrzucamy obrazki przeznaczone dla maych rozdzielczoci
- low dot per inch. Do drawable-hdpi wrzucamy obrazki przeznaczone dla duych rozdzielczoci high dot per inch. W katalogu layout mamy pliki xml okrelajce wygld poszczeglnych
aktywnoci. W katalogu menu mamy pliki okrelajce wygld menu na rnych ekranach.
W katalgou values mamy np. plik strings.xml. Tutaj okrelamy wszelkie napisy ktre pojawiaj si
w aplikacji. Napisy takie mona oczywicie ustawia i w kodzie javy, jednak jeli bdziemy je
umieszcza w tym pliku, bdzie nam atwiej pniej zarzdza napisami majc je w jednym
miejscu. Przechowywanie napisw w osobnym pliku XML ma szczeglne znaczenie dla wygody
pniejszej internacjonalizacji programu.
15/227
16/227
W tym miejscu musimy nada nazwy aplikacji, projektowi oraz pakietowi w ktrym bd
znajdowa si nasze klasy. Nazwa projektu najlepiej by bya taka jak nazwa aplikacji (cho nie jest
to konieczne). Jeli posiadasz domen internetow, to najlepiej bdzie odwrci fraz i na kocu
doda nazw nowo tworzonej aplikacji. Przykadowo jeli mam domen jsystems.pl i tworz
aplikacj KebabFinder to tworz pakiet pl.jsystems.kebabfinder. Taka jest powszechna praktyka i
zapewnia unikalno nazw. Nie dojdzie do sytuacji e bd dwie klasy KlasaGlowna znajdujce si
w pakietach o takiej samej nazwie com.example, cho bd pochodzi od rnych dostawcw i
robi rne rzeczy.
17/227
Przechodzimy dalej, a pojawi nam si ekran wyboru ikony aplikacji. Domylnie ikon aplikacji
bdzie logo Androida. Moemy je zmieni na jaki wasny obraz (wybieramy go wtedy z dysku),
jaki obrazek z Clip Arta, albo logo tekstowe. Ja nacisnem Clipart, nastpnie choose i
wybraem znak kciuka. Dalej zmieniem domylny bkitny kolor logo na czerwony klikajc na
Foreground Color.
18/227
19/227
Po przejciu do kolejnego ekranu wybieramy nazw klasy aktywnoci gwnej, oraz nazw pliku
xml w ktrym okrelony bdzie wygld aktywnoci gwnej. Aktywno mona to rozumie w
sporym uproszczeniu jako ekran dane okno w aplikacji. Aktywnoci aplikacja moe mie wiele,
uytkownik moe porusza si midzy aktywnociami ( midzy ekranami uruchom np. swoj
aplikacj i przyjrzyj si procedurze ustawiania celu a zrozumiesz co mam na myli). Kada
aplikacja musi za to mie jak aktywno (ekran) ktra pojawi si jako pierwsza po uruchomieniu
programu. Z tak aktywnoci wie si klasa j obsugujca, a nazw tej klasy okrelamy w polu
Activity Name. W tej klasie bdziemy pniej okrela jak dany ekran ma si zachowywa.
Kolejne pole layout Name okrela nazw pliku XML w ktrym bdzie zapisany wygld tego
ekranu. W tym pliku bdzie zapisane rozmieszczenie elementw oraz ich wasnoci.
20/227
Na razie bez szczegw tak tylko informacyjnie: metoda onCreate jest uruchamiana kiedy dany
ekran zostaje wywietlony, metoda onCreateOptionsMenu kiedy uytkownik nacinie przycisk
menu.
21/227
22/227
Aby uruchomi aplikacj, klikamy prawym przyciskiem myszy na katalogu projektu w polu
Package Explorer, dalej Run As-->Android Application. Powinno nam si pojawi takie
okno:
23/227
Moemy tutaj wybra uruchomienie z uyciem wirtualnego lub realnego urzdzenia. Na ten
moment mam stworzone wirtualne urzdzenia, ale adne nie jest uruchomione. Odpalimy wic
aplikacj jednoczenie uruchamiajc wirtualne urzdzenie. Zaznaczam Launch a new Android
Virtual Device , zaznaczam wybrane urzdzenie i wciskam Ok.
Virtualne urzdzenie moe uruchamia si nawet 2-3 minuty, wszystko zaley od sprztu ktrym
dysponujemy. Po uruchomieniu na urzdzeniu wirtualnym:
24/227
Tym razem uruchomimy program na realnym urzdzeniu. Podobnie jak i wczeniej klikamy PPM
na projekcie, wybieramy Run > Run as Anroid Application. Pojawi si okno jak wczeniej. W
sekcji Choose a running Android device widzimy dwa urzdzenia. Jedno to wczeniej
uruchomione urzdzenie wirtualne, drugie to realne urzdzenie Samsung ACE3. Aby mc std
wrzuca aplikacje na takie urzdzenie, musimy je wczeniej przygotowa wczajc na nim opcje
programistyczne. Aby to zrobi, wchodzimy w Ustawienia , dalej szukamy na dole opcji opcje
programisty w ktre wchodzimy i aktywujemy. Bez tego nie bdzie moliwoci debuggowania
aplikacji, czyli nie wdroymy jej z Eclipsa na dany telefon. Po wczeniu opcji, podczamy telefon
przewodem do komputera. Przy kolejnym uruchomieniu aplikacji nasz telefon powinien by ju
tutaj widoczny. Zauwayem ju e niektre urzdzenia w ogle nie chc rozmawia z Eclipsem w
ten sposb, choby wszystko byo powczane i poczone jak naley. Miaem tak np. z telefonem
Prestigio. Zanim wic zaczniesz grzeba w opcjach i si irytowa, po prostu sprawd z innym
urzdzeniem.
25/227
26/227
Elementy wizualne
Przegld podstawowych komponentw graficznych
Tutaj zajmiemy si najczciej uywanymi, podstawowymi komponentami graficznymi. Na ekranie
przykleiem kilka takich elementw i poniej kady z nich opisuj.
TextView
Pierwszy komponent od gry. Suy do wywietlania tekstu. Uytkownik aplikacji nie moe
zmodyfikowa jego zawartoci. Na palecie komponentw mamy rne jego wariacje w tym
LargeText, MediumText i SmallText. W rzeczywistoci te trzy niby rne elementy to ta sama
klasa, ale z rnie ustawionymi parametrami wielkoci czcionki. Dostpny jest w palecie w panelu
Form Widgets.
Button
Drugi element od gry. Przycisk. Moemy zaprogramowa w Javie sposb jego zachowania po
przyciniciu. Dostpny jest w palecie w panelu Form Widgets.
27/227
EditText
Pole edycyjne w ktre uytkownik aplikacji moe wprowadza tekst. Dostpny jest w palecie w
panelu TextFields. Znajdziemy tam rwnie kilka wariacji tego komponentu, umoliwiajcych np.
wprowadzanie wycznie liczb, albo tylko dat. Wszystkie one s obiektami klasy EditText, jednak z
rnie ustawionymi parametrami wywietlania i wprowadzania danych.
ImageView
Element trzeci od dou. Suy do wywietlania obrazkw. Dostpny jest w palecie w panelu
Images & Media.
ImageButton
Widoczny jest pod ImageView. Jest czym porodku midzy Buttonem a ImageView. Moemy na
nim wywietli obrazek, a jednoczenie oprogramowa jego zachowanie po klikniciu. Dostpny
jest w palecie w panelu Images & Media.
CheckBox
Umoliwia zaznaczenie lub odznaczenie jakiej opcji (np. akceptacja regulaminu). Dostpny jest w
palecie w panelu Form Widgets.
28/227
29/227
Gdy zajrzymy do pliku layoutu, zobaczymy e zostao wygenerowane troch dodatkowego kodu
zwizanego z tymi nowymi komponentami:
30/227
31/227
32/227
Tekst jaki ma zosta wywietlony na komponencie moemy ustawi przy pomocy parametru
android:text w pliku layoutu, tak jak to wida na przykadzie powyej, lub poprzez metod setText
klasy TextView, jak to wida poniej:
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText("Napisik tylko do odczytu...");
Button
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Przycisk" />
Tekst jaki ma zosta wywietlony na komponencie moemy ustawi przy pomocy parametru
android:text w pliku layoutu, tak jak to wida na przykadzie powyej, lub poprzez metod setText
klasy Button, jak to wida poniej:
Button b=(Button) findViewById(R.id.button1);
b.setText("Napis na guziku");
Obsuga zdarzenia kliknicia na komponentach (nie tylko na przycisku) zostaa opisana w osobnej
publikacji to do spory temat.
33/227
EditText
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pole do wprowadzania danych" >
Tekst domylny jaki ma zosta wywietlony na komponencie moemy ustawi przy pomocy
parametru android:text w pliku layoutu, tak jak to wida na przykadzie powyej, lub poprzez
metod setText klasy EditText, jak to wida poniej:
EditText et=(EditText)findViewById(R.id.editText1);
et.setText("Domylny tekst");
Tekst wprowadzony przez uytkownika moemy odebra przy pomocy metody getText klasy
EditText:
EditText et=(EditText)findViewById(R.id.editText1);
String coWpisano=et.getText()+"";
Poniewa metoda getText zwraca obiekt klasy Editable (a nie jak bymy si mogli spodziewa String), dodaem fragment + wymuszajcy niejawn konwersj na String. Bez tego aplikacja si
nie kompiluje.
ImageView
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/star_on" />
ciek obrazka ktry ma zosta wywietlony ustawiamy przy uyciu parametru android:src w
pliku layoutu. Obrazek ktry ma zosta wywietlony wrzucamy do dowolnego z katalogw
drawable-xxxx bdcych podkatalogami katalogu res, a nastpnie odnosimy si poprzez wskanik
zbudowany na tej zasadzie: @android:drawable/nazwa_pliku_bez_rozszerzenia
34/227
ImageButton
<ImageButton
android:id="@+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/sym_action_email" />
ciek obrazka ktry ma zosta wywietlony ustawiamy przy uyciu parametru android:src w
pliku layoutu. Obrazek ktry ma zosta wywietlony wrzucamy do dowolnego z katalogw
drawable-xxxx bdcych podkatalogami katalogu res, a nastpnie odnosimy si poprzez wskanik
zbudowany na tej zasadzie: @android:drawable/nazwa_pliku_bez_rozszerzenia
CheckBox
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox" />
Tekst ktry ma zosta wywietlony obok pola zaznaczania okrelamy przy uyciu parametru
android:text w pliku layoutu lub przy uyciu metody setText klasy CheckBox, tak jak to wida
poniej:
CheckBox cb=(CheckBox) findViewById(R.id.checkBox1);
cb.setText("Przeczytaem i akceptuj regulamin");
Odczyt stanu zaznaczenia moemy przeprowadzi przy uyciu metody isChecked klasy CheckBox,
tak jak to wida poniej:
CheckBox cb=(CheckBox) findViewById(R.id.checkBox1);
if(cb.isChecked()){
//zaznaczone
}else{
//nie zaznaczone
}
35/227
Teraz musimy zrobi niemieckojzyczn wersj programu, albo choby zmieni wszystkie nazwy
na pisane ma liter....
36/227
Dopuki teksty te okrelam na sztywno w pliku layoutu, tak jak to wida poniej (linie 15,25,34),
doputy bd musia przy kadej tego typu zmianie modyfikowa plik layoutu kadej aktywnoci
ktrej zmiana ma dotyczy.
37/227
38/227
Dodajmy tam kilka elementw. Od teraz teksty ktre pojawiaj si nam na formularzu bd
definiowane tutaj. Do kadej frazy przypisana jest nazwa np. do frazy Imi: przypisana jest
nazwa name:
39/227
Teraz w elemencie android:text zamiast pisa na sztywno tekst ktry ma si pojawi, pisz
odwoanie po nazwie do wpisw w pliku strings.xml (linie 15,25,34):
Moemy takie wskaniki zrobi we wszystkich plikach layoutw. Dziki takiemu zabiegowi,
zmiana tekstu na wszystkich guzikach sucych do zatwierdzania formularza, czy nawet
dorobienie alternatywnej wersji jzykowej aplikacji wymaga bdzie zmian w jednym tylko
miejscu i bez wielokrotnej zmiany tego samego tekstu w rnych plikach layoutw.
40/227
Szablony kolorw
Jeli zechcemy czsto uywa w naszej aplikacji jakiego koloru, lub np. zrobi dwukolorow
aplikacj, moemy wszdzie podawa kodowo kolor np. #FF0033, albo stworzy szablon i
odwolywac si do koloru na zasadzie kolor_tla. Informacja o kodzie koloru dla kolor_tla
znajduje si w osobnym pliku xml. Dziki takiemu rozwizaniu moemy szybko modyfikowa
kolory w caej aplikacji, np. jeli zechcemy zrobi skrk witeczn dla naszego programu :)
Zaczynamy od utworzenia pliku xml w katalogu values bdcym podkatalogiem katalogu res.
Klikamy na nim PPM new new Android XML file. Wyskakuje nam takie okienko. Podajemy
nazw pliku i zatwierdzamy.
41/227
42/227
43/227
Wyszo paskudnie, chocia wierz e gdzie na wiecie s ludzie ktrzy maj dom urzdzony w
takich kolorach. Na szczcie w przypadku aplikacji na Androida (w przeciwiestwie do domu)
mona to atwo i szybko zmieni.
44/227
Style komponentw
Przypumy e mam tak sytuacj, mam trzy napisy na ekranie i dla wszystkich chc okreli taki
sam kolor czcionki, wielko czcionki, ewentualnie inne parametry.
Mgbym to robi osobno dla kadego komponentu ustawiajc parametry w pliku layoutu danej
aktywnoci. To wicej pracy ni to warte, a ponadto gdybym zechcia co zmieni, musiabym
zmienia dla kadego komponentu osobno. Kady kto napisa cho jedn podstron w HTML
powinien doskonale rozumie w czym rzecz. Podobnie jak w HTML, tak i tutaj moemy
zdefiniowa style i z ich uyciem stosowa okrelone wasnoci dla wielu komponentw naraz.
Filozofia jest podobna do stosowanych przy tworzeniu stron internetowych plikw css.
45/227
Zaczynam od stworzenia pliku XML ze stylem. Klikam PPM na katalogu values bdcym
podkatalogiem katalogu res. Wybieram new-->Android XML File. Pojawia mi si takie okno:
46/227
Podaj nazw pliku w ktrym opisz styl komponentw. Nazwaem go styl_napisow. Teraz w pliku
wprowadzam kilka zmian. Dodaj dwa rne style napisw. Zawarto mojego pliku ze stylami:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="wielki_napis">
<item name="android:textSize">50dp</item>
<item name="android:textColor">#0000FF</item>
</style>
<style name="maly_napis">
<item name="android:textSize">20dp</item>
<item name="android:textColor">#FF0000</item>
</style>
</resources>
Jak widac okrelam wielko i kolor czcionek. S dwa style dla duego niebieskiego napisu, oraz
mniejszego czerwonego. Mona tutaj oczywicie okreli znacznie wicej rzeczy np. szeroko i
wysoko komponentu, napis na nim, a nawet metod ktra obsuguje kliknicie komponentu. W
pliku layoutu dla danej aktywnoci dodaj do komponentw nowy parametr: style, oraz wskazuj
nazw stylu sprzed momentem stworzonego pliku:
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="25dp"
android:layout_marginTop="35dp"
android:text="Napis numer 1"
style="@style/wielki_napis"
/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:layout_marginTop="22dp"
android:text="Napis numer 2"
style="@style/maly_napis"
/>
47/227
Efekt po uruchomieniu:
Style moemy stosowa dla wszelakich komponentw, nie tylko dla napisw.
48/227
To ekranu aplikacji
Zaczniemy od ustawienia koloru ta, to jest zdecydowanie najprostsze. Stworzyem nowy projekt.
Cao sprowadza si do ustawienia parametru android:background (linia 9) w XMLowym pliku
layoutu.
Jeli chcesz wybra jaki kolor, moesz znale zestawienie kolorw dla HTML (np. tutaj:
http://www.kurshtml.edu.pl/html/wykaz_kolorow,kolory.html) Ustawiem przypadkowy kod koloru
FF0044 i wyszo mi co takiego(fuj):
49/227
Tym razem zamiast podawa kod koloru, podaj w pliku layoutu w parametrze android:background
wskanik do obrazka (patrzymy na lini nr 9):
50/227
Efekt:
51/227
Piese nam si troch rozcign. W zalenoci od rozmiaru i proporcji ekranu bdziemy mie
wikszego albo mniejszego, chudszego albo grubszego piesea. To nie zawsze musi dobrze
wyglda. Moe lepiej byoby by obrazek ta si powtarza? Aby uzyska taki efekt, musimy
stworzy plik XML ktry bdzie opisywa sposb prezentacji obrazka. W tym celu klikamy PPM na
katalogu drawable-hdpi i wybieramy New-->Android XML File. Pojawi nam si takie okno:
52/227
53/227
54/227
W niej wskazywany jest plik zawierajcy opis zawartoci menu. Powyszy (domylny) wpis
wskazuje na plik main.xml znajdujcy si w katalogu menu bdcym podkatalogiem katalogu res:
55/227
Moemy go przerobi pod wasne potrzeby, lub stworzy nowy i przerobi metod
onCreateOptionsMenu tak by wskazywaa nowo stworzony. Domylnie jego zawarto wyglda
tak:
Mamy jedn opcj w menu, z napisem okrelonym w pliku strings.xml znajdujcym si w katalogu
res --> values pod nazw action_settings. Przygldamy si mu:
Widzimy, e napis na tej opcji w menu to Settings. Teraz zmienimy plik main.xml, by
wprowadzi wasne opcje menu. Nic nie stoi te na przeszkodzie bysmy stworzyli osobny plik,
musimy jedynie pamita o zmianie ustawie w metodzie onCreateOptionsMenu aktywnoci. Do
pliku strings.xml dodaj jeden wpis:
56/227
Kady element <item> to kolejna opcja w menu. Zrobiem trzy elementy z napisami wpradzonymi
bezporednio w tym pliku, a jeden z napisem pobieranym z pliku strings.xml Napis na opcji okresla
parametr android:title. Parametr android:orderInCategory okrela kolejno wywietlania w menu
od gry. Opcja android:id to identyfikator danej opcji w menu. Musimy zadba o to by byy one
rne dla kadego elementu menu, inaczej nie bdziemy pniej w stanie odrni ktra opcja
zostaa wybrana. Na ten moment menu po uruchomieniu wyglda tak:
57/227
Jeli tak wolisz, nie musisz definiowa zawartoci menu w pliku XML. Moesz to zrobi
bezporednio w kodzie Javy:
Metoda add dla obiektu klasy Menu (czyli naszego menu) wywoywana tutaj ma 4 parametry.
Wedug kolejnoci: Numer grupy, numer elementu, kolejnoc wywietlania, napis. Kod w dziaaniu:
58/227
Wracam jednak do starej metody z plikiem XML. Teraz dodamy obsug kliknicia. Dorzucam
metod onOptionsItemSelected ktra jest automatycznie wywoywana za kadym razem gdy
uytkownik kliknie w menu. Przez parametr tej metody przekazywany jest obiekt elementu menu
ktry zosta kliknity. Mog pobra jego identyfikator, jednak nie bdzie to identyfikator typu
opcja1 , opcja2 czyli takie jak zdefiniowaem w pliku main.xml, a identyfikator liczbowy, ktry
dopiero mog porwna z identyfikatorami liczbowymi moich opcji menu. Tak to niestety trzeba na
okoo robi:
59/227
60/227
61/227
62/227
</TableLayout>
Kolejne elementy <TableRow> okrelaj kolejne wiersze w tabeli. Kolumn bdzie tyle, ile bdzie
elementw w wierszu w ktrym jest najwicej elementw dokadnie jak w HTML.
63/227
Domylnie wywietlana jest formatka do montowania elementw metod drag & drop. Aby przej
do edycji rcznej pliku kliknij zakadk activity_main.xml znajdujc si u dou.
Po wklejeniu kodu moesz wrci do ekranu drag & drop i powiniene zobaczy taki widok:
64/227
Linear layout ukad liniowy, obiekty uoone pod sob lub obok siebie
Ten rodzaj layoutu dziaa w oparciu o zasad, e elementy znajduj si kolejno pod sob lub obok
siebie. Podobnie jak poprzednio, stwrz nowy projekt i zawarto pliku layoutu zamie na ten kod:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Element nr 1" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Element nr 2" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Element nr 3" />
</LinearLayout>
Okrelilimy tutaj 3 pola wywietlajce tekst. Zwr przy okazji uwag na element:
android:orientation="horizontal"
65/227
W ramach eksperymentu dodaem przy tych ustawieniach jeszcze dwa elementy TextView. Jak
wida, nie wyglda to najlepiej. Do takiego efektu moe doj np. na telefonach o mniejszych
ekranach lub rozdzielczoci:
66/227
Ta zmiana sprawi, e elementy nie bd ze sob ssiadoway obok siebie, a jeden pod drugim.
Efekt:
67/227
68/227
Jak wida, pooenie elementu klasy TextView jest wskazane jako odlegoci od grnego i lewego
marginesu, a pooenie elementu Button jako odlegoci wzgldne od elementu TextView. Takie
podejcie jest zrozumiae przy przeciganiu elementw, ale takie rozmieszczanie przy uyciu
kodowania rcznego nie byoby specjalnie wygodne. Warto zna ten typ layoutu jedynie ze wzgldu
na moliwo nanoszenia rcznych poprawek do automatycznie generowanego kodu. Chodzi o
sytuacje gdy przecigamy graficznie komponenty, ale nie moemy ustawi elementw tak jak
bymy sobie tego yczyli, bo nam si wszystko rozjeda.
69/227
70/227
Po uruchomieniu aplikacji:
Z jednej strony, rozkad elementw nam si nie rozjedzie, ale z drugiej ustawienie wsprzdnych
elementu obowizuje zarwno przy pionowym jak i poziomym pooeniu ekranu. Jest te
niezalene od wielkoci i rozdzielczoci ekranu. Moe si wic okaza e na niektrych telefonach,
albo po obrceniu ekranu, cz komponentw znalaza si poza widocznym obszarem.
71/227
Parametry typu marginTop czy tekst s jasne, ale mamy turaj layout_height i layout_width
okrelone nie jak si mona by byo spodziewa w pikselach, a jako wrap_content. Takie
ustawienie jest domylne i oznacza ono, e element ma by tak szeroki i wysoki by zmieci
znajdujcy si w nim napis (lub obrazek w przypadku elementu imageView, czy inn zawarto w
przypadku inych komponentw). Efekt wizualnie wyglda tak:
72/227
Ponownie wprowadzam zmian w konfiguracji. Tym razem ustawiam fill_parent rwnie dla
wysokoci komponentu:
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:layout_marginTop="32dp"
android:text="Button" />
73/227
Umieciem te tam element tekstowy do ktrego wrzuc troch tekstu, tak by byo wida efekt
przesuwania ekranu. W klasie aktywnoci dodaj kawaek kodu ktry do elementu tekstowego
zdefiniowanego przed momentem wstawia kolejne liczby w kolejnych liniach:
74/227
75/227
Czas na programowanie!
Wykorzystanie Log.d w debugowaniu
W normalnej Javie jeli zechcielibymy sprawdzi co si dzieje w programie i gdzie si
przewraca, najpewniej uylibymy metody typu
System.out.println(Trololo, jestem po obliczeniach);
:)
W Androidzie nie ma konsoli systemowej (javovej), mamy za to moliwo wyrzucania
komunikatw na konsol LogCat w rwnie prosty sposb. Wystarczy takie wywoanie:
Log.d("debuggowanie programu", "Jestem komunikatem");
To co podamy do metody d jako pierwszy parametr trafi do kolumng Tag, to co podamy jako
drugi parametr trafi do kolumny Text. Metoda ta dziaa zarwno przy uruchamianiu programu na
wirtualnym urzdzeniu, jak i fizycznym sprzcie podpitym do komputera.
76/227
77/227
Metoda onCreate jest wywoywana wtedy, kiedy aktywno jest uruchamiana po raz pierwszy. Z
tego powodu to wanie j wykorzystuje si najczciej i to wanie w niej ustawiamy wygld
ekranu oraz ustawienia pocztkowe.
Metoda onStop jest wywoywana kiedy aplikacja jest zamykana. Moesz tutaj wprowadzi kod
ktry zapisze stan aplikacji np. do bazy danych.
Metoda onPause jest wywoywana np. kiedy obracamy ekran, a take przed metod onStop w
przypadku zamknicia aplikacji.
Metoda onResume jest wywoywana rwnie kiedy obracamy ekran, lub przy powrocie do
dziaania po wczeniejszym zapazowaniu.
78/227
Peen diagram przechodzenia aplikacji przez rne stany (pochodzi z dokumentacji Androida):
79/227
Komunikaty Toast
Komunikaty Toast su do krtkotrwaego wywietlania mao wanych komunikatw.
Komunikat pojawia si na kilka sekund i znika, uytkownik moe nawet tego nie zauway, wic
nie powiniene w ten sposb wywietla np. komunikatw o bdach. Doskonale si za to nadaje to
wywietlania np. podpowiedzi.
80/227
81/227
82/227
Dalej w klasie aktywnoci wykorzystuj metod setHint klasy EditText. Zawarto linii nr 14
suy jedynie podpiciu referencji do obiektu (musz si jako do niego odnie). Samo ustawienie
w zwizku z umieszczeniem go w metodzie onCreate bdzie dziaao ju od uruchomienia.
Efekt:
83/227
84/227
85/227
Alternatywnie cho na podobnej zasadzie moemy utworzy obiekt listenera w momencie jego
tworzenia linia 19. Mniej kodu, ale czytelno na tym traci. Efekt dziaania identyczny jak
poprzednio.
Trzecia alternatywna metoda jest chyba najmniej intuicyjna, ale jak si zrozumie zasad dziaania to
kod przy wikszej iloci guzikw do obsugi bdzie najbardziej przejrzysty i bardzo wygodny w
rozwijaniu. Tym razem nie definiuj adnego listenera! Wszystko co ma si zdarzy po klikniciu
przycisku jest opisane w metodzie obslugaKlikniecia. Wazne by metoda ta przyjmowala jako
parametr obiekt klasy View (po tej klasie dziedzicz wszystkie komponenty takie jak guzik i to
wanie pod postaci tego parametru jest przekazywany obiekt komponentu do metody) i nic nie
zwracaa. Pozornie metoda jako taka nie jest w aden sposb zwizana z obsug kliknicia na
przycisk:
86/227
Pojawi nam si tutaj (linia 19) nowy element: android:onClick. Zamiast zwizywa na poziomie
kodu javowego metod obslugaKlikniecia z specjalnie do tego tworzonym listenerem, wskazujemy
nazw metody przy uyciu parametru przycisku w pliku layoutu. Takie rozwizanie ma ten plus, e
pisze si znacznie mniej kodu, a sam kod przy wikszej liczbie obsugiwanych przyciskw jest
czytelniejszy. Z drugiej strony, jeli nie bdziemy pamita o takim rozwizaniu, moemy za jaki
czas zachodzi w gow jak to zostao zrobione :)
Pamitajmy e obsuga kliknicia nie dotyczy tylko przyciskw, ale kadego komponentu
dziedziczcego po View w tym napisy i pola edycyjne.
87/227
88/227
Nadaj nazwy klasie tej aktywnoci oraz plikowi XML w ktrym bdzie opisany Layout.
89/227
90/227
91/227
Linie 24-31 to podpicie wywoania metody reakcja() pod nacinicie guzika. W samej metodzie
reakcja jest napisane co si ma w takiej sytuacji zadzia. Jak wida tworz nowy obiekt klasy Intent
(linia 14) i w kolejnej linii uruchamiam intencje metod startActivity (dziedziczon po klasie
Activity). Poniewa intencj ktr wywouj jest inna aktywno, musz przekaza jej kontekst,
oraz wskaza klas aktywnoci ktra ma zosta wywoana. Nie zapominamy oczywicie by po
stworzeniu intencji j wywoa :) Druga aktywno ta ktr wywouj to zwyky najprostszy
ekran z napisem Hello World!.
92/227
93/227
Rozbudujmy nieco nasz aplikacj. Do wywoania innego ekranu dodam teraz przekazanie
zmiennej. Wykorzystuj do tego metod intencji putExtra. Musimy pamita by wywoywa j
przed startActivity(Intent i). W tym przypadku przekazuj tekst : siema jestem zmienn! pod
postaci zmiennej o nazwie zmienna. Tekst ten zostanie przekazany do wanie wywoywanej
aktywnoci i wywietlony na konsoli ( o wyswietlenie tego tekstu zadbam ju na poziomie tej
nowej aktywnoci):
Aby odebra przekazany obiekt, tworz po stronie wywoywanej aktywnoci obiekt klasy Bundle z
ktrego pobieram zbir przekazanych obiektw przy uyciu metody getExtras(). Z wizki tej
musz teraz wybra obiekt ktry mnie interesuje (linia 16). Odebrany tej tekst wywietlam teraz na
konsoli LogCata:
94/227
Przyjrzyjmy si teraz innemu przykadowi aktywnoci. Tym razem bdzie to wywoanie strony
internetowej. Podaj do systemu intencj bdc daniem otwarcia strony internetowej:
Platforma Android sprawdza jaki program odpowiada za obsug takich intencji i przekazuje mu j.
Poniewa chcemy nawiza poczenie z internetem, musimy zadba o dodanie stosownych
uprawnie do pliku manifestu:
95/227
Efekt:
96/227
W tym przykadzie poka w jaki sposb moemy otworzy zewntrzn (domyln) przegldark z
poziomu aplikacji. Zaczynam jak zawsze od najprostszego przykadu. Stworzyem nowy projekt i
przykleiem guzik z napisem Gugiel!. Po naciniciu przycisku powinna zosta uruchomiona
przegldarka z uruchomionym adresem http://google.pl
97/227
98/227
Ekran po uruchomieniu:
99/227
Troszk przerobimy teraz nasz aplikacj. Uytkownik sam wpisze adres strony ktra ma zosta
wywoana. Dodaj do widoku element EditText i zmieniam tekst na guziku:
Musi za tym i maa przerbka w kodzie. Interesuj nas linie 23 i 24. W linii 23 dodaem uchwyt
do okienka edycyjnego. W linii 24 konkatenuj adres url na podstawie pocztku http:// (bo o tym
pewnie kady uytkownik zapomni, a bez tego nie zadziaa) oraz tekstu wpisanego w oknie
edycyjnym. Pozostaa cz programu pozostaje bez zmian.
100/227
Po uruchomieniu:
101/227
Jeszcze jedna ciekawostka, aczkolwiek bardziej w charakterze bajeru. Jeli odnajdziemy w pliku
okrelajcym layout element odpowiedzialny za nasz EditText i dopiszemy
android:inputType=textUri, to po klikniciu na okienko do wprowadzania tekstu wyskoczy nam
klawiatura ze specjalnymi guzikami do wprowadzania adresw URL np. www :)
Tych inputType'w jest znacznie wicej rodzajw, midzy innymi do wprowadzania adresw email,
liczb etc .
102/227
103/227
104/227
Przy tworzeniu projektu, tworzymy rwnie od razu pierwsz aktywno. Bdzie to po prostu
pierwszy ekran jaki si pojawi po uruchomieniu aplikacji. Decydujemy o jego pokroju zostawiamy domylne Blank Activity:
105/227
Podajemy nazw klasy bdcej pierwsz aktywnoci (ekranem) w polu Activity Name. Do
naszej klasy bdzie te potrzebny plik XML w ktrym to okrelimy jak maj by rozmieszczone
elementy w danej aktywnoci (guziki, okienka etc). Nazw tego pliku okrelamy w polu Layout
Name:
106/227
Gdy projekt zostanie utworzony, zostanie otwarta klasa gwnej aktywnoci. Bdzie zawiera dwie
metody. Pierwsza onCreate to metoda ktra jest uruchamiana w momencie startu aktywnoci.
Druga onCreateOptionsMenu to metoda uruchamiana kiedy kto wybierze przycisk menu. T
drug usuwamy, nie jest nam na razie potrzebna.
107/227
108/227
109/227
Przechodz teraz do edycji pliku XML okrelajcego layout naszej gwnej aktywnoci. Bdziemy
edytowa rcznie, wic tym razem nie wybieramy Graphical Layout a activity_main.xml (lub
jak tam nazwae swj plik :) ).
Bdzie tam ju troch tekstu, ale nie jest nam potrzebny wic go w caoci kasujemy. Teraz
doprowadzamy zawarto pliku do takiej mniej wicej formy:
Table Layout to tabelaryczny ukad elementw na ekranie aktywnoci , co jak w HTML. Kolejne
TableRow to po prostu kolejne wiersze w tabeli. Elementy zawarte w elemencie TableRow
bd ze sob ssiadowa w ramach danego poziomu w tabeli. Mamy tutaj dwa elementy:
ImageView, oraz TextView. Pierwszy suy do wywietlania obrazkw, drugi do wywietlania (ale
nie wprowadzania) tekstu. W obu mamy parametr android:id. Nadajemy nim unikaln nazw
elementowi w ramach danej aktywnoci. Warto tego parametru musi si zaczyna od @+id/ po
ktrych nastpuje nasz identyfikator. Ten identyfikator jest niezbdny do rozrniania elementw i
jednoznacznego wskazywania jednego z nich. W obu te wystpuj parametry layout_width i
layout_height. Okrelaj one szeroko i wysoko elementu. Jednostka DP to piksele niezalene
od rozdzielczoci ekranu.
Programowanie aplikacji na platform Android v 1.0. A.Klusiewicz www.jsystems.pl
110/227
W elemencie ImageView jest jeszcze parametr android:src. Poprzez niego podajemy jaki obrazek
ma zosta wywietlony. Jeli chodzi o obrazek zawarty w projecie (a nie znajdujcy si np. na
zdalnym serwerze czy karcie pamici) to zaczynamy warto od @drawable/ po ktrym nastpuje
nazwa obrazka wrzuconego w jednym z poprzednich krokw do katalogu drawable-hdpi. Nie
podajemy rozszerzenia (tutaj .png) w nazwie pliku.
W elemencie TextView mamy dodatkowo element android:text przy uyciu ktrego ustawiamy
tekst jaki ma by wywietlany na elemencie. Zwizany z nim jest jeszcze element
android:textSize, ktry okrela wielko czcionki. Uyem tutaj te parametrw
android:layout_marginLeft, oraz android:layout_marginTop. Okrelaj one margines lewy ,
oraz grny.
Wracamy do widoku projektowania graficznego. Nasza aplikacja powinna w tej chwili wyglda
mniej wicej tak:
111/227
112/227
113/227
Przysza pora na dodanie nowej aktywnoci tj. ekranu na ktry aplikacja powinna przej po
klikniciu na napis pole kwadratu. Klikam prawym przyciskiem myszy na pakiecie w ktrym
znajduje si moja pierwsza aktywno i wybieram NEW--> OTHER:
114/227
Zauwa e w metodzie onCreate jest wywoanie metody setContentView, ktra suy do wizania
Programowanie aplikacji na platform Android v 1.0. A.Klusiewicz www.jsystems.pl
115/227
aktywnoci z opisem wygldu zawartym w pliku XML. Kada aktywno domylnie bdzie miaa
swj plik xml i po stworzeniu bdzie wywoanie jej wasnego pliku, ale moesz do zmieni
wskazujc w parametrze inny layout. Tutaj mamy R.layout.activity_pole_kwadratu, poniewa taki
wanie plik zosta utworzony podczas generowania nowej aktywnoci:
116/227
Na ten moment ta aktywno bdzie po prostu wywietlaa napis Hello World!. My w tej
aktywnoci dodamy par elementw, bdzie to formularz do obliczania pola kwadratu.
Przechodzimy do graficznej formy edycji layoutu:
Napis ktry ju tam si znajduje nieco zmodyfikujemy. Klikamy na prawym przyciskiem myszy i
wybieramy Edit Text:
117/227
Wczeniej tekst wpisywalimy niejako bezporednio, teraz przyjmiemy nieco inn konwencj. W
projekcie obecny jest plik strings.xml:
Znajduj si w nim identyfikatory, oraz przypisane do nich teksty. Chcc wywietli jaki tekst na
elemencie, bdziemy si odwoywa poprzez identyfikator do tekstu zawartego w tym pliku.
Po co nam to wszystko? Dziki temu mamy wszystkie informacje tektstowe w jednym miejscu,
duo atwiej jest je dziki temu zmienia. Ponadto znacznie atwiej bdzie pniej robi rne
wersje jzykowe naszego programu, bo wystarczy potem tylko podmieni ten jeden plik.
\
Programowanie aplikacji na platform Android v 1.0. A.Klusiewicz www.jsystems.pl
118/227
119/227
120/227
W polu String wpisujemy tekst ktry ma zosta dodany do pliku strings.xml. Oraz wywietlony
na komponencie. W polu New R.string podajemy identyfikator tekstu, pod ktry zostanie
wpisany tekst do pliku.
121/227
Dobrze. Mamy teraz ekran pocztkowy z list elementw do wyboru, oraz zalek nowego ekranu
ktry docelowo bdzie suy obliczaniu pola kwadratu. Trzeba teraz te elementy poczy. Po
klikniciu napisu pole kwadratu na naszej aplikacji powinna pojawi si aktywno do obliczania
pola kwadratu. Przyszed czas na dodanie reakcji na kliknicie napisu.
122/227
Zmieniem nieco zawarto klasy mojej gwnej aktywnoci. Dodaem zmienn t1 ktra bdzie
reprezentowaa komponent TextView z napisem Pole kwadratu. W linii 19 do tej zmiennej
przypinam realny komponent. Robi to przy uyciu wbudowanej metody findViewById. Ma j
kada klasa dziedziczca po Activity. Ta metoda suy do zwracania referencji komponentu z
aktywnoci. Do zmiennej t1 zostaje przypisany element o identyfikatorze textView1 (czyli nasz
napis pole kwadratu z ekranu gwnego:
Obsug zdarzenia kliknicia realizujemy poprzez podstawienie listenera dla obiektu t1. Listener to
taki proces nasuchu ktry czeka na jakie zdarzenie. Tworzymy nasz listener jako obiekt klasy
OnClickListener i jednoczenie defuniujemy dla niego reakcj na kliknicie (metoda onClick).
Tymczasowo reakcja na kliknicie komponentu ma polega na zmianie napisu Pole kwadratu na
napis AA!!!!. Stworzony listener ustawiamy dla obiektu t1 poprzez metod tego obiektu
setOnClickListener.
123/227
Uruchamiam projekt i sprawdzam dziaanie. Reakcja na kliknicie jest taka jaka by powinna. Nasz
program jest nadwraliw beks :)
Skoro ju dziaa obsuga kliknicia, to teraz jako reakcj wepniemy uruchomienie innej aktywnoci
w miejsce zmiany tekstu.
124/227
Wykomentowaem zmian tekstu. Dodaem obiekt klasy Context do ktrego w linii 28 przypisuj
kontekst aplikacji. W linii 29 tworz now intencj. Intencje to komunikaty czce ze sob rne
komponenty.W tym przypadku nasza intencja bdzie suya wywoaniu innej aktywnoci. W tej
samej linii podaj te informacj, aktywno jakiej klasy ma zosta wywoana. W linii 30 odpalam
t aktywno.
125/227
Sprawdzam dziaanie caoci. Tym razem po klikniciu napisu Pole kwadratu nie zmienia si
tekst na komponencie, a zostaje wywietlony ten ekran:
Skoro wywoania dziaaj, trzeba przerobi t aktywno tak, aby faktycznie suya obliczaniu pola
kwadratu. Przechodz wic do pliku layoutu tej aktywnoci:
126/227
127/227
Pojawiy si tu nowe rzeczy. Komponent klasy Button, komponent klasy LargeText, oraz
komponent klasy EditText. Button to po prostu przycisk. LargeText to element wywietlajcy tekst,
ale o powikszonej czcionce. EditText to komponent w ktrym moemy wywietli jaki tekst, ale
uytkownik programu bdzie mg go zmieni.
128/227
W analogiczny sposb jak dla kliknicia napisu Pole kwadratu oprogramowaem tutaj kliknicie
przycisku z napisem Oblicz. Zdefiniowaem w liniach 14-16 obiekty ktre bd reprezentowa
uywane przeze mnie komponenty. W liniach 23-25 przypisuj do tych obiektw referencje do
komponentw. W liniach 27-36 mam oprogramowan reakcj na kliknicie przycisku. Dziaa to
analogicznie jak wczeniejszy przykad. Z nowoci jest tutaj tylko rodzaj reakcji. W liniach 31-33
jest opisane co dokadnie ma si zdarzy. Generalnie ustawiam tekst na komponencie wynik (to ten
komponent klasy LargeText ktry ma domylnie ustawione trzy mylniki. Ustawiany tekst to
kwadrat wartoci podanej poprzez obiekt bok czyli obiekt klasy EditText, do ktrego uytkownik
wprowadzi dugo boku kwadratu. Po drodze pojawiaj si te rzutowania z tekstu na liczb i
odwrotnie :)
129/227
Program po uruchomieniu:
130/227
Jako wiczenie pozwalajce naby nieco praktyki i oswoi si z now technologi, proponuj
dokoczy opisywany w tym rozdziale projekt.
131/227
Wielowtkowo w Androidzie
Wykorzystanie klas Thread i AsyncTask
Jak bardzo potrafi irytowa zawieszanie si aplikacji wie kady z nas. Teraz wyobra sobie, e
Twoja aplikacja na Androida ma do wykonania jakie czasochonne czynnoci, wystarczy e bdzie
musiaa pobra jakie dane czy obraz z internetu. Jeli zrobisz to w ramach gwnej wtku
programu, UI przestanie odpowiada, a uytkownik Twojego programu bdzie yczy Ci wanie
tego, czego zapewne Ty yczysz czasem programistom Internet Explorera :) Aby si o tym
przekona, wystarczy przyklei na ekranie przycisk, a jako jego reakcj oprogramowa zdarzenie
oczekiwania. Przyklej guzik:
132/227
W zasadzie interesuj nas tylko linie 24-32. Reszta to otoczka. Jak widzimy, w chwili nacinicia
przycisku wywoywana jest instrukcja Thread.sleep(10000). To sprawi e aplikacja zaczeka 10
sekund. Sprbuj to uruchomi na dowolnym urzdzeniu i np. wywoa menu pogramu (tym
dedykowanym guzikiem do menu). Zobaczysz e nic si nie stanie, aplikacja po prostu si
zawiesia.
Trzeba wic wydzieli osobny wtek i puci go w tle do realizowania czasochonnych zada.
Mona zrobi to tradycyjnie po javowemu:
Moesz uruchomi tak przerobiony program, a przekonasz si e wtek dziaajcy w tle nie blokuje
innych elementw interfejsu. Jest oczywicie pewne ale. Jeli sprbujesz sign z poziomu
kodu do jakichkolwiek komponentw wizualnych z poziomu takiego wtku, dostaniesz taki
wyjtek:
133/227
Chcemy eby uytownik widzia, e program co wykonuje, a nie po prostu zwis. Taki ProgressBar
domylnie jest widoczny i wykonuje si animacja. My zrobimy tak, eby na poczku nie by
widoczny, pokaemy go gdy pucimy wtek i schowamy gdy go zakoczymy.
134/227
Wykorzystanie wczeniej wspomnianej klast AsyncTask polega na stworzeniu klasy ktra po niej
dziedziczy i zaimplementowaniu paru metod. Do klasy naszej aktywnoci dodaj wewntrzn klas
OsobnyWtek dziedziczc po AsyncTask. Nic nie stoi na przeszkodzie by bya to w ogle osobna
klasa. Pojawio si tutaj te co nowego element <Void,Void,Void> oraz dziwna parametryzacja
metod doInBackground i onPostExecute. Zwizane jest to z pojciem klas generycznych, oglnych.
Tym zagadnieniem nie bdziemy si tutaj zajmowa, nie jest zwizane bezporednio z tematem
wielowtkowoci w Androidzie. Obiekty klasy OsobnyWatek bd stanowiy osobne wtki w
ramach aplikacji. Zauwa e mamy tutaj trzy metody przesaniajce takie metody z klasy po ktrej
dziedziczymy. Metoda onPreExecute jest automatycznie wywoywana przy starcie wtku.
Wywietlam tutaj nasz ProgressBar. Kko staje si widoczne i zaczyna pracowa. Daj te
komunikat na konsol. W tej metodzie, oraz w metodzie onPostExecute moemy bez obaw
odwoywa si do komponentw graficznych w naszej aktywnoci. Nie robimy tego za to w
metodzie doInBackground. To co ma si dzia w ramach wtku te dugotrwae czynnoci piszemy
wanie w metodzie doInBackground. Tutaj wyrzucam na konsol informacj, oraz wstawiam 10
sekundowe oczekiwanie. Metoda onPostExecute jest wywoywana automatycznie w chwili
zakoczenia wtku. Wywietlam tutaj informacj o zakoczeniu i chowam ProgressBar.
135/227
136/227
137/227
138/227
Konstruktor jako taki przyjmuje tylko jeden parametr kontekst, ktry zreszt przekazuje nastpnie
do konstruktora klasy po ktrej dziedziczy. Kontakty.db to nazwa pliku bazy danych ktry
zostanie utworzony. Jedynka w konstruktorze to wersja bazy danych. Moemy t warto
zwiksza przy kolejnych zmianach w strukturze bazy.
Podczas pierwszego skorzystania z obiektu naszej klasy ZarzadcaBazy, SQLiteOpenHelper
zauway brak pliku bazy (tutaj kontakty.db) i go utworzy a nastpnie wywoa metod onCreate. W
mojej metodzie onCreate, posugujc si metod execSQL obiektu klasy SQLiteDatabase tworz
tabel w ktrej bd przechowywa dane. Nic nadzwyczajnego zwyky SQL. Metoda onUpgrade
zostanie wywoana jeli bdziemy si odnosi do przestarzaej wersji bazy danych (silnik bazy
bdzie to wiedzia na podstawie numeru wersji ktr podajemy jako parametr konstruktora).
Moemy tutaj np. zaimplementowa wywoanie jakich polece rozbudowujcych czy
zmieniajcych struktury bazy.
139/227
W razie problemw wyrzuci wyjtek typu SQLExcepion, ale moemy go wyapa obejmujc to
wywoanie blokiem try catch.
Do klasy ZarzadcaBazy dodalem tez metod dajWszystkie. Sluzy ona pobieraniu danych z bazy.
W linii 43 zdeklarowaem kolumny jakie chc odczyta, oraz ich kolejno. Nie musz odczytywa
wszystkich kolumn, ani te nie musz wyciga ich w takiej kolejnoci w jakiej s w tabeli. W linii
44 pobieram uchwyt do bazy. Tym razem wywouj jednak metod getReadableDatabase, poniewa
nie bd w bazie nic modyfikowa, a jedynie czyta. Zasadniczo pobranie danych jest realizowane
metod query w linii 45. Podaj tutaj nazw tabeli z ktrej bd czyta dane, oraz jako parametr
list kolumn ktre bd pobiera. Pozostae parametry (ktre s tutaj nullami) su do stsowania
warunkw WHERE, Having, grupowania, sortowania etc.
Przyszed czas na dorobienie warstwy prezentacji. Przyklejam wic na swojej gwnej aktywnoci
komponent klasy TextView:
W ramach tego przykadu, do tabeli telefony dodam z uyciem dotychczas stworzonych funkcji 3
nowe kontakty, a nastpnie je wywietl.
140/227
W metodzie onCreate aktywnoci gwnej zasadniczy najwaniejszy dla nas element mieci si w
liniach 18-28. Linia 18 to stworzenie obiektu zarzdcy bazy danych a wic tej klasy ktra jest
odpowiedzialna za czenie si z baz i operacje na niej. Konstruktor tej klasy wymaga podania
konktekstu. Tutaj jako kontekt wskazuj this, a wic biec aktywno. Z uyciem metody
dodajKontakt zawartej w owej klasie, dodaj trzy nowe kontakty. W dalszej kolejnoci chc je
pobra z bazy i wywietli na ekranie. Korzystam z metody dajWszystkie, ktra jednak zwraca
obiekt klasy Cursor. Przetwarzanie takiego kursora nie jest najwygodniejsze wic za chwil
zajmiemy si przerobieniem wszystkiego w taki sposb by metoda dajWszystkie zwracaa list
obiektw np. klasy Kontakt. Krok po kroku. Na razie mamy spartaskie warunki.
W ptli while (linia 23) widzimy metod moveToNext(), wykorzystanie tej metody pozwala nam na
przesuwanie si po wyniku zapytania po linii w d tak dugo jak dugo s jeszcze jakie dane do
przeczytania. W liniach 24-27 do definiowanych w ptli zmiennych przypisuj zawarto kolumn z
kolejnych wierszy wg pozycji tej kolumny od lewej std wywoania typu getInt(0), getString(3)
chodzi o numer kolumny od lewej strony wg kolejnoci jak wymienilimy w metodzie
dajWszystkie klasy ZarzadcaBazy. Zauwa e posuguj si te rnymi metodami w zalenoci od
spodziewanego typu danych zwracanych z zapytania mam na myli metody getString i getInt.
Pilnuj tego, poniewa jeli sprbujesz zrobi getInt lub np. getLong a w wyniku dostaniesz cig
tekstowy , program wyrzuci wyjtek. W linii 28 zwyczajnie konkatenuj uzyskane informacje i
wywietlam je w kompononecie klasy TextView ktry przykleiem tam przed momentem. Aby nie
posklejao mi si to w jeden dugi pozawijany cig przed kadym kolejnym kontaktem doklejam
\n czyli znak nowej linii.
141/227
Efekt :
142/227
Poka teraz ciekaw waciwo na bazie pewnego przykadu. Zawarto tej bazy danych bdzie
trwaa pomidzy kolejnymi uruchomieniami programu. Jeli wic teraz uruchomi jeszcze raz ten
program, a co za tym idzie po raz kolejny dodam trzy te same nowe kontakty, powinienem teraz
zobaczy zdublowane rekordy. Jedyne co powinno je odrnia to identyfikatory rekordw tj.
zawarto kolumny nr bdcej kluczem gwnym tabeli telefony a majcej wasno
autoincrement. Dokonuj wic drobnej kosmetycznej zmiany w kodzie:
W linii 28 dodaj jedynie wywietlanie kolumny nr adnych innych zmian nie nanosz. Efekt jest
wic taki jak przewidywalimy:
Aby program by w jakikolwiek sposb uyteczny, oraz aby kod by przejrzysty, trzeba bdzie
dokona kilku kolejnych zmian:
Stworzy klas Kontakt i posugiwa si obiektami tej klasy a nie list elementw typu
String.
143/227
Przy okazji widzimy e nasze 3 kontakty zostay dodane po raz kolejny ;) Z tym te musimy co
zrobi. In plus e mamy rne numery identyfikacyjne.
144/227
Oczywicie baz podpinamy w trybie do zapisu, co widzimy w linii 50. W linii 51 definiuj list
elementw argumentw dla warunkw where. Musi to by lista argumentw klasy String. Myl e
najlepiej bdzie to wyjani na przykadzie. Przyjrzyjmy si linii 52. Pierwszy warunek to nazwa
tabeli z ktrej chcemy kasowa wiersze. Drugi to warunki ktre maj trafi po klauzuli where.
Samego where ju tutaj nie wymieniamy. Zamiast wartoci liczbowych czy tekstowych ktre
miayby si pojawi w warunkach, stawiamy znak zapytania. Gdybymy mili wicej ni jeden
parametr, to ten cig tekstowy mgby wyglda np. tak: department_id=? and manager_id=? and
salary>?. System oczekiwaby w takiej sytuacji podania mu trzech wartoci ktre trafi pod nasze
znaki zapytania. List tyche wanie wartoci podaj w postaci kolekcji String zdefiniowanej w
linii 51 poprzez trzeci parametr metody delete. W moim przypadku lista skada si z caego
jednego elementu ktry na dodatek w sposb mao elegancki, aczkolwiek popularny rzutuj na typ
String. Czyli podsumowujc:
Argument nr 1 to nazwa tabeli z ktrej kasujemy
Argument 2 to warunki dla klauzuli where
Argument 3 to lista wartoci ktre maj trafi do parametrw warunkw where okrelonych jako
argument nr 2 metody delete :)
Przetestujmy teraz dziaanie naszej nowej metody.
145/227
146/227
147/227
Przerabiam teraz gwn aktywno tak, aby przed wywietleniem wywoa metod aktualizujc i
zmieni numer telefonu Dziadka Mroza:
Efekt:
148/227
Oczywicie programistyczni puryci podnios zarzut, e jakto tak z palca podawa wszystkie
wartoci wcznei z tymi nie zmienianymi, e te dane powinny by pobrane z bazy , zwrcone
przez jak metod w postaci obiektu, a nastpnie po zmianie wartoci wybranego pola przekazane
jako obiekt do metody aktualizujcej w bazie. I jak najbardziej bd mili racj :) Z tym, e aby to
osign potrzebujemy najpierw przerobi to na troszk bardziej obiektow form, oraz stworzy
metod zwracajc wybrany wiersz wg identyfikatora :). Zacznijmy wic od zdefiniowania klasy
ktra bdzie reprezentowa pojedynczy wiersz. Staraem si tak definiowa eby pola w klasie
odpowiaday nazwom kolumn w tabeli:
Jest taka dobra praktyka programistyczna, by pola w klasach typu POJO nie byy publiczne, a
prywatne, natomiast dostp do nich uzyskiwa poprzez tak zwane gettery i settery. Dziki temu
mamy wiksz kontrol nad zawartoci tych pl. W rodowisku Eclipse jest nawet specjalna
funkcja do automatycznego generowania tego typu metod. Wybieramy z menu dostpnego pod
prawym przyciskiem myszki:
149/227
150/227
151/227
Linie 74-77 to znane ju z wczeniejszych przypadkw czytanie danych, tym razem jednak nie
przypisuj ich do zmiennych, a przy uyciu setterw uzupeniam obiekt klasy kontakt. W linii 79
uzupeniony ju (miejmy nadziej moglimy przecie poszukiwa kontaktu po numerze ktry w
tabeli nie wystpuje) obiekt klasy kontakt zwracam z metody. Caa metoda:
Efekt:
Przerobi teraz pozostae metody z klasy ZarzadcaBazy, tak by cao bya jako tako obiektowa :)
Programowanie aplikacji na platform Android v 1.0. A.Klusiewicz www.jsystems.pl
152/227
Metoda zwraca obiekt klasy Cursor, ktrego przetwarzanie nie naley do najwygodniejszych. T
metod przerobi te tak, by zwracaa list (klasy LinkedList) obiektw.
153/227
Po paru poprawkach metoda dajWszystkie dziaa tak jak sobie tego yczylimy. Sposb pobierania
danych jest taki sam, jedynie dodaem w liniach 67-73 przetwarzanie kursora i adowanie danych
do przygotowanej wczeniej (w linii 63) listy kontaktw.
Przetwarzanie takiej listy jest pniej duo wygodniejsze. Poniej wykorzystanie nowej wersji
metody dajWszystkie w gwnej aktywnoci:
154/227
Przy okazji pojawia si nam tutaj nowa metoda: d klasy Log. Wywouje si j w taki sposb:
Log.d(tag,text); a efekt wyglda tak:
Parametry wg kolejnoci :
1. Nazwa tabeli z ktrej czytamy
2. Kolumny ktre czytamy
3. Warunki where
4. Wartoci do warunkw where
5. Kolumna/kolumny po ktrych grupuj
6. Warunek do klauzuli having
7. Sposb sortowania
155/227
Tutaj ju kady moe uzna czy chce tak posta wykorzystywa czy nie. Moim zdaniem to rednio
wygodne i mao intuicyjne. Poza tym, co jeli chciabym stosowa zczenia midzy tabelami,
podzapytania etc? Zamiast takiej nieco abstrakcyjnej formy wywoywania zapyta z uyciem
metody query, moemy wykorzysta metod rawQuery. Do naszego zarzdcy bazy dopisaem
metod wycigajc kontakty o nazwisku ktre przekazuj jako parametr.
156/227
Do tego komponentu trzeba bdzie doda layout dla pojedynczych elementw listy (jest to
niezbdne na pniejszych etapach), na razie tworz pusty plik XML w katalogu layout.
157/227
Nic specjalnego. Plik opisuje po prostu w jaki sposb ma wyglda pojedynczy element listy. Tutaj
bdzie to po prostu napis, ale rwnie dobrze moemy tutaj zastosowa choby TableLayout i uoy
sobie bardziej skomplikowane struktury (np. obrazek i obok tekst).
Przysza pora na kod:
158/227
Najwaniejsze elementy znajduj si w liniach 23-28. W linii 23 do listy elementw typu String
przypisuj list plikw z wskazanego katalogu. Klasa File to zwyka javowa File, nie adna
Androidowa interpretacja. W Javie kady katalog te jest plikiem, std taki moe nieco dziwny
zapis. Katalog ktrego zawarto pobieram to . , czyli katalog root systemu. Rwnie dobrze moe
to by dowolny inny katalog, podajemy go jako parametr konstruktora klasy File. W liniii 24 tworz
obiekt klasy ArrayList. Bd musia do adaptera (czyli elementu dziki ktremu uzupeniam
zawarto komponentu klasy ListView) poda list wanie takiego typu. W linii 26 robi
konwersj z dotychczas uywanej listy stringw na obiekt klasy ArrayList. Linia 27 to
inicjalizacja wczeniej wspomnianego adaptera. Mamy trzy parametry, pierwszy to kontekst, drugi
do wskanik do zawartoci pliku XML charakteryzujcego wygld pojedynczego elementu listy,
trzeci to lista typu ArrayList zawierajca dane do wywietlenia.
Efekt:
159/227
Zmieniem katalog ktrego zawarto wywietlam na /sdcard , czyli zawarto karty SD. Wynik
wyglda tak:
160/227
Wprowadziem kilka zmian w kodzie. W linii 27 zmieniem troszk wywoanie konstruktora klasy
File, tak by korzysta ze zmiennej typu String o nazwie katalog, a nie podanej bezporednio cieki.
Zrobiem tak, poniewa nieco dalej znowu korzystam ze cieki do pliku i nie chc powiela tego
samego kodu. Od linii 29 do 37 iteruj po elementach listy stringw zawierajcych nazwy plikw i
katalogw. W zalenoci od wasnoci pliku/katalogu do jego nazwy doklejam rne informacje.
Dalsza cz kodu pozostaje bez zmian. Linia 31 to doklejenie do nazwy litery R, jeli plik/katalog
moemy odczytywa. Linia 32 to dodanie do nazwy litery W jeli mamy moliwo pisania do
pliku. Linie 33-35 su dodaniu daty do nazwy pliku/katalogu. Korzystam tutaj z obiektu klasy
java.util.Date, poniewa warto zwracana przez metod lastModified() wyraona jest jako int. W
linii 36 powikszam warto iteratora ktrego uywam do poruszania si po licie.
W pliku XML elementy_listy_glownej.xml opisujcym wygld pojedynczego elementu listy
rwnie dokonaem maej zmiany (czysta kosmetyka). Zmniejszyem wielko czcionki z 15 na 11,
poniewa wiksza ilo informacji powodowaaby zawijanie linii, a tak mamy wszystkie informacje
dotyczce pliku/katalogu w jednej linijcie :)
161/227
Efekt:
162/227
163/227
164/227
Lokalizacja i mapy
Wykorzystanie GPS
Jeli nasz telefon / urzdzenie z ktrego korzystamy posiada czujniki GPS, moemy wykorzysta je
do sprawdzania naszej pozycji programowo. Moemy rwnie skorzysta z darmowych map
projektu OpenStreetMap (http://openstreetmap.org) i np. stworzy wasn nawigacj.
Zaczniemy od utworzenia nowego projektu i wyedytowania pliku AndroidManifest.xml tego
projektu. Musimy doda prob o uprawnienia do korzystania z czujnikw GPS. Bez takiej
autoryzacji ze strony uytkownika, nasz program nie bdzie dziaa. Dodajemy linie:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Mamy ju moliwo korzystania z czujnikw GPS. Czas przej do waciwej wersji kodu.
Zaczniemy jak zawsze od wersji najprostszej tj. po uruchomieniu programu ma si na ekranie
wywietli nasze pooenie tzn. dugo i szeroko geograficzna.
165/227
Przechodzimy teraz do naszej gwnej aktywnoci. Przyklejam na ekranie trzy elementy klasy
TextView. Na dugo i szeroko geograficzn, oraz na nazw wybranego dostawcy (wyjani si to
nieco pniej).
166/227
Obiekt kr klasy Criteria (linia 29) suy do wyszukiwania najlepszego dostawcy informacji o
pooeniu GPS. Mog np. poprzez te kryteria okreli e interesuj mnie wycznie bezpatni
dostawcy ( metoda setCostAllowed klasy Criteria), czy poziom zapotrzebowania energetycznego
wymaganego dla danego sposobu okrelania lokalizacji (setPowerRequirement). Chcc zastosowa
ktry z wymienionych warunkw, po utworzeniu obiektu klasy Criteria, uruchamiamy dla tego
obiektu wybrane metody. Sam obiekt klasy Criteria jako element warunkujcy wybr dostawcy
stosujemy pniej przy pobieraniu nazwy najlepszego dostawcy. W linii 30 inicjalizuj obiekt przy
uzyciu usugi zwracanej przez metod getSystemService (metoda dziedziczona po klasie Activity).
Z uyciem tej metody moemy podpina si do najprzerniejszych usug systemowych : np.
korzysta z rnych czujnikw (temperatury, cinienia etc), korzysta z usug lokalizacyjnych,
pobiera dane z internetu, drukowa, korzysta z portu USB i wiele innych. Poniewa bdziemy
korzysta z usug lokalizacyjnych, jako parametr metody getSystemService podaj
LOCATION_SERVICE. Linia 31 to pobranie nazwy najlepszego dostawcy informacji o pooeniu
(moe to by np. GPS, pooenie okrelone wg triangulacji, lub sie WIFI). Zwrcony moe by
tylko dostawca dla ktrego wywoujca aktywno ma niezbdne pozwolenia (chodzi o wpisy w
AndroidManifest.xml). Jeli kilku dostawcw spenia zaoone kryteria, to zwrcona zostanie
nazwa tego ktry charakteryzuje si najwysz dokadnoci pooenia. Przykadowo, jeli moemy
okreli nasze pooenie na podstawie GPS, lub na podstawie triangulacji, przy czym GPS okreli
to z dokadnoci do 10 metrw a triangulacja z dokadnoci do 1 kilometra, to zostanie zwrcona
nazwa dostawcy gps. Pierwszy parametr metody getBestProvider to nasze kryteria, drugi okrela
czy zwracani maj by tylko aktywni dostawcy ( w tym przypadku oczywicie tylko tacy nas
interesuj).
167/227
Obiekt klasy Location bdzie reprezentowa nasz lokalizacj w przestrzeni, bdziemy z niego
pniej pobiera np. nasz dugo i szeroko geograficzn. Najpierw jednak musimy okreli
nasze pooenie :) Robimy to w linii 32 przy uyciu metody getLastKnownLocation obiektu klasy
LocationManager. Jako parametr podajemy nazw wybranego dostawcy informacji o pooeniu.
Linie 34-36 to po prostu wywietlenie uzyskanych danych. Warte uwagi mog tutaj by metody
getLongitude i getLatitude zwracajce dugo i szeroko geograficzn. Zwracaj liczby typu
double, z dosy du dokadnoci. Bdc na obrzeach Warszawy dostaem swoje pooenie z
dokadnoci do 7 miejsca po przecinku stopnia geograficznego. Do tego prostego programu warto
byoby ewentualnie dorobi obsug sytuacji w ktrej nie byoby w danym pooeniu adnego
dostawcy, lub nie mona byoby okreli pooenia. Nie bdziemy si tym tutaj jednak zajmowa
poniewa obsuga nulla zwracanego z metody (tutaj z metod getBestProvider i
getLastKnownLocation) to podstawy Javy. Chcc testowa rzeczy zwizane z GPS, najlepiej robi
to na realnym urzdzeniu a nie adnych emulatorach. Niby na emulatorach jest moliwo
ustawienia fikcyjnego pooenia GPS, ale te nie zawsze to dziaa. U mnie po uruchomieniu
programu na telefonie wywietlio si:
najlepszy dostawca: network
szeroko geograficzna: 52.2996591
dugo geograficzna: 20.9930961
Program dziaa, jednak jeli zmienimy pooenie, nasz program tego nie odnotuje. Warto byoby
wzbogaci program o funkcjonalno ktra by uwzgldniaa zmiany naszego pooenia. Zaczn od
dodania do ekranu elementu na ktrym bdzie pojawiaa si historia lokalizacji. Przykleiem
komponent klasy SmallText.
168/227
eby historia troszk si odrniaa, zmieniem tekstu w tym nowym komponencie poprzez edycj
pliku layoutu i dopisani linijki : android:textColor=#300FD
W linii 18 widzimy nowe pole t4. To jest obiekt reprezentujcy komponent do wywietlania
historii. W liniach 25-28 widzimy now metod odswiez. Poniewa bd musia odwiea swoje
pooenie przynajmniej dwukrotnie tj. przy uruchomieniu aplikacji i przy zmianie lokalizacji,
postanowiem kod odpowiedzialny za odwieanie oddelegowa do osobnej metody.
169/227
W linii 37 widzimy podpicie do obiektu t4 referencji do naszego nowego komponentu (tego napisu
ktry bdzie robi za histori). Nic nadzwyczajnego, ale musimy o tym pamita. W linii 41
zamiast wywoywa osobno szukanie najlepszego dostawcy i pobieranie pooenia mamy
wywoanie metody ktra wanie to robi i aktualizuje nasze obiekty. Linia 42 zawiera ustawienie
wasnoci odwieania. Konfigurujemy tutaj co jaki czas i przy jakiej zmianie pooenia system ma
odwiea lokalizacj (czyli jak czsto ma by automatycznie wywoywana metoda
onLocationChanged ktr bdziemy za chwil implementowa - w liniach 50-57). Pierwszy
parametr to nazwa dostawcy z ktrego korzystamy, drugi to czas w milisekundach co ile ma by
odwieana lokalizacja, trzeci to co jaki dystans (wyraony w metrach), a czwarty to obiekt
implementujcy interfejs LocationListener (tutaj akurat dotyczy to obiektu w ktrym si
znajdujemy). Linie 43-46 to ustawienie domylnych napisw, czyli tego co ma si pojawi zaraz po
uruchomieniu programu. Tutaj tak jak wczeniej wywietlamy dostawc i wsprzdne. W linii 46
ustawiam pierwsz i na razie jedyn lini historii.
170/227
Poniej mamy cztery metody ktre musiaem zaimplementowa z racji implementacji interfejsu
LocationListener. Trzy tymczasowo zostawiam w spokoju. Interesuje mnie teraz tylko metoda
onLocationChanged. Jest ona wywoywana co interwa czasowy lub dystans okrelone (linia 42) w
metodzie requestLocationUpdates. W ramach mojej implementacji metody onLocationChanged
odwieam pooenie wywoujc metod odswiez, a nastpnie w liniach 52-54 wywietlam na
komponentach aktualne pooenie. W linii 55 dodaj do historii kolejn lini.
171/227
Byem ciekaw na ile sprawnie t o dziaa, wic wgraem program na telefon i poszedem sprawdzi
czy nie ma mnie za rogiem. Oto wyniki:
172/227
173/227
Wybieramy te dwie nowo dodane biblioteki i zatwierdzamy. Czas wstawi obiekt mapy do naszego
layoutu. Dodajemy widoczny na poniszej ilustracji element org.osmdroid.views.MapView:
174/227
Poniewa aplikacja bdzie musiaa pobiera dane (mapy) z internetu, musimy zadba o
odpowiednie pozwolenia. Do pliku manifestu dodajemy wic ponisze linie:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
tu za tagiem </application>
To s wystarczajce uprawnienia niezbdne do dziaania map OpenStreetMaps. My w naszym
przykadzie wykorzystamy nasz realn pozycj z GPS i wywietlimy fragment mapy z okolic
naszej pozycji. Z tego powodu trzeba bdzie doda jeszcze dodatkowe uprawnienia:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
W przypadku gdybymy nie korzystali z pozycji GPS, tych ostatnich uprawnie nie dodajemy.
Oglnie w suemie cao powinna wyglda mniej wicej tak:
175/227
Kod z linii 42-45 jest zwizany z pobraniem pozycji GPS, omawiaem w jednym z poprzednich
rozdziaw dokadnie sposb dziaania takiego kodu i nie bd si tutaj tym zajmowa. Nas
interesuj zasadniczo linie 35-40 i 46-50. Linia 35 to element nie zwizany z sam map jako tak,
suy do podpicia referencji do komponentu mapy. W linii 36 wskazujemy rdo z ktrego
pobieramy mapy. Linie 37 i 38 okrelaj zachowanie mapy. Metoda setBuildInZoomControls (linia
37) ustawia, czy ma by moliwo przybliania i oddalania na mapie (jeli podamy true, bd
dostpne przyciski + i na mapie). Metoda setMultiTouchControls (linia 38) ustawia moliwo
stosowania gestw dotykowych na ekranie jak np. zblianie i oddalanie widoku dwoma palcami.
W linii 40 okrelamy domylne przyblienie mapy. W linii 46 tworzymy obiekt klasy GeoPoint
reprezentujcy nasze pooenie. W linii 49 centrujemy map na punkcie wskazanym przez obiekt
klasy GeoPoint ustawiony w linii 46. Wywoanie metody invalidate w linii 50 to odwieenie
widoku.
176/227
177/227
W metodzie onCreate aktywnoci gwnej dodaj par linii kodu. Kod ktry ma realizowa zadanie
znajduje si wanie w tej metodzie, poniewa chc aby wyniki wywietliy si od razu po
uruchomieniu programu. Linie 21,22 to podpicie referencji do komponentu TextView i
wyczyszczenie jego zawartoci (napisu). Klasa SensorManager do ktrej obiektu odwouj si w
linii 25 (sama deklaracja obiektu jest w linii 14) daje nam dostp do czujnikw wbudowanych w
urzdzenie. Pobranie instancji tej klasy nastpuje poprzez wywoanie metody getSystemService z
parametrem SENSOR_SERVICE. Aby odczyta nazwy czujnikw ktre s dostpne w urzdzeniu,
wykorzystuj metod getSensorList klasy SensorManager ( linia 26 ). Metoda ta zwraca dostpne
(czyli znajdujce si na danym urzdzeniu) czujniki wskazanego typu. Tutaj podaj jako typ
Sensor.TYPE_ALL, dziki czemu w efekcie dostaj czujniki wszystkich typw. Mgbym w tym
miejscu wstawi np. Sensor.TYPE_GYROSCOPE i dostabym list wszystkich dostpnych w
urzdzeniu yroskopw. Linie 27-29 to ju iteracja po zwrconych obiektach i dodawanie
kolejnych linii z nazwami kolejnych czujnikw do kompontentu tekstowego.
178/227
179/227
180/227
Do przyklejonych elementw musimy podpi referencje aby z nich korzysta, tutaj niczego
zaskakujcego nie ma. Pojawia si za to implementacja interfejsu SensorEventListener. O co tu
chodzi? Nasz czujnik bdzie co chwila podawa nowe odczyty, aby wywietla te zmiany musimy
zaimplementowa ten interfejs. W zwizku z tym, bdziemy musieli przesoni metody
onSensorChanged i onAccuracyChanged. O tym za momencik.
181/227
Zanim zaczniemy korzysta z naszego czujnika, musimy zarejestrowa wybran klas (musi ona
implementowa interfejs SensorEventListener) jako odbiornik dla czujnika. Ja to zrobiem w
metodzie onCreate mojej aktywnoci, poniewa ta jest uruchamiana w momencie startu programu.
Jako odbiornik zarejestrowaem aktywno, poniewa to w niej chc reagowa na zmiany odczytw
(a zadbaem o to by ta aktywno implementowaa interfejs SensorEventListener).
182/227
183/227
Do programu warto byoby doda jeszcze obsug sytuacji gdyby urzdzenie nie posiadao
czujnika, nie kady telefon jest w niego wyposaony.
184/227
<uses-permission android:name="android.permission.SEND_SMS"/>
185/227
Obiekt klasy SmsManager jest elementem wysyajcym smsy. Zmienna odbiorca to numer telefonu
na ktry chcemy wysa wiadomo. Lista elementw fragmenty, zdefiniowana jako pusta to
pojemnik do ktrego wrzucona zostanie wiadomo SMS podzielona na fragmenty. Zmienna
wiadomosc suy do tymczasowego przechowania wiadomoci o dugoci wikszej ni 160 znakw.
W metodzie onCreate , w linii 28 odbieram instancj klasy SmsManager. W linii 29 wykorzystuj
metod divideMessage ktrej podaj dug wiadomo, a ta zwraca nam j ju podzielon na
fragmenty do pojemnika fragmenty. Samo wysanie wiadomoci to wywoanie metody
sendMultipartTextMessage, ktrej podaj numer telefonu odbiorcy i wiadomo podzielon na
fragmenty. Po drodze (w linii 30) wywietlam ilo elementw jakie wyjd z naszej wiadomoci.
186/227
Wiadomo przychodzi jako cao. Pamitamy oczywicie o woeniu karty SIM do urzdzenia z
ktrego chcemy wysya smsy, poniewa wbrew pozorom nie jest to metoda na darmowe wysyanie
smsw ;)
187/227
Odbieranie SMSw
Jeli chcemy napisa aplikacj ktra bdzie reagowaa na nadejcie SMS, musimy j zarejestrowa
jako taki odbiornik i w ten sposb zdeklarowa e potrafi obsugiwa takie akcje. W tym
celu,gdzie pomidzy tagami <Application> w pliku manifestu musimy wstawi taki fragment:
<receiver android:name=".OdbiornikSMS" android:enabled="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
Oczywicie w pierwszej linii podajemy nazw swojej klasy ktra ma sesemesy odbiera.
Wstawiajc taki kawaek kodu do naszego pliku manifestu, deklarujemy e nasz program potrafi
obsugiwa pewne operacje np. w tym przypadku android.provider.Telephony.SMS_RECEIVED,
ale rwnie dobrze moe to by odbieranie nadchodzcych pocze czy obsuga wywoa otwarcia
strony internetowej.
Skoro deklarujemy, e jestemy w stanie obsugiwa odbieranie sms, to musimy jeszcze mie do
tego uprawnienia ;) Pamitamy wic o dodaniu takiej linii do pliku manifestu:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
188/227
189/227
Multimedia
Odwarzanie dwiku
Zaczniemy od najprostszego przykadu. Program zaraz po uruchomieniu odtworzy plik MP3 ktry
bdzie znajdowa si w ramach samego programu.
Zaczynamy od stworzenia projektu, oraz utworzenia podkatalogu o nazwie raw w katalogu res
projektu. Nastpnie do podkatalogu raw wrzucamy utwr muzyczny w ktrym z formatw: wav,
aac, mp3, wma, amr, ogg, midi
Wszystko co wrzucimy do podkatalogu res, jest automagicznie rejestrowane jako zasb dostpny z
poziomu kodu.
190/227
Kluczowe s tutaj linie 19-21. artowaem :) Interesuj nas linie 16 i 17. W linii 16 tworzymy
obiekt klasy MediaPlayer ktra jako taka suy do odtwarzania multimediw. Podczas tworzenia
przekazujemy jako argumenty metody create : kontekts i zasb. Jak wida nie podajemy
rozszerzenia pliku.
Linia 17 to uruchomienie odtwarzania zasobu kty wskazalimy w linii 16.
W sytuacji gdyby plik muzyczny ktry chcemy odtwarza znajdowa si poza aplikacj, np. na
karcie SD nasz kod wyglda by musia tak:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(/sdcard/rammstein/raise_raise.mp3);
mp.prepare();
mp.start();
191/227
192/227
193/227
194/227
Zapomniaem dziubka zrobi, to bym sobie na fejsbuczka wstawi sit foci ;) . Po zrobieniu
zdjcia, dolny panel powinien nam si zamieni na taki:
Mog tutaj anulowa operacj, powtrzy robienie zdjcia, lub zatwierdzi. Zatwierdzamy, a po
powrocie z tej aktywnoci nasz ekran wyglda tak:
Za wyjtkiem moe zdjcia, na swoim zobaczysz pewnie co adniejszego :p Przy uyciu tej
metody moemy niestety robi tylko takie mae zdjcia. Za chwil zrobimy to troszk inaczej i
dostaniemy penowymiarowe zdjcie.
195/227
Stworzyem now aplikacj. Aby zrobi penowymiarowe zdjcie, Android bdzie musia zapisa je
w pliku. Podobnie jak wczeniej dodaj prob o uprawnienia do kamery pliku manifestu, teraz
jednak musz te uzyska pozwolenie na korzystanie z karty pamici, lub jakiego innego folderu.
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Android udostpnia publicznie dostpny katalog (dostpny dla wszystkich aplikacji). Aby si do
niego dobra moemy zastosowa np. tak konstrukcj:
File katalog =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
Daem jeden guzik ktry uruchomi intencj, oraz jeden TextView na ktrym znajdzie si cieka do
zrobionej fotografii.
W aktywnoci, w metodzie onCreate podpinam referencj do komponentw i jako obsug
nacinicia przycisku wywouj metod obslugaGuzika().
196/227
Wyjaniam rzeczy ktrych nie omawiaem wczeniej. W linii 50 tworz plik ktry wykorzystam za
chwil do zapisania fotografii na dysku. Linie 51-54 su jedynie nazwaniu pliku tak, by nazwa
zawieraa dat i czas zrobienia zdjcia. Jeli chcesz, moesz je nazwa po prostu fotka. Linia 57
to pobranie referencji do kyatalogu przeznaczonego na obrazki. W linii 59 tworz plik w ktrym
znajdzie si zdjcie. W linii 63 do intencji podaj dodatkowy parametr tj. ciek do pliku w
ktrym ma si znale zdjcie. Po zakoczeniu cyklu intencji wywietlam na textView ciek do
utworzonego pliku.
197/227
Efekt:
Moe nam nie odpowiada to, e musimy dodatkowo klika na androidowej aktywnoci do robienia
zdj. Chcielibymy by przykadowo program sam robi zdjcie w reakcji na jakie zdarzenie np.
pobudzenie czujnika ruchu. Konieczno dodatkowego kliknicia przez czowieka w takim
wypadku nie wchodzi w gr. Jest moliwo automatyczniego robienia zdj, bez wywoywania
dodatkowej systemowej aktywnoci, ale wymaga to wicej pracy.
198/227
Zaoenie jest takie, e zaraz po klikniciu przycisku zostanie wykonana fotografia i wywietlona
na imageView. Musz te zadba o wymagane pozwolenie:
<uses-permission android:name="android.permission.CAMERA"/>
199/227
200/227
Linie 53-61 to podpicie wywoania mojej metody onC pod kliknicie przycisku. W liniach 64-67
znajdziemy metod, ktra powoduje wykonanie zdjcia przez kamer. Istotnym z punktu widzenia
funkcjonalnoci jest tutaj wywoanie metody takePicture dla obiektu klasy Camera dla ktrego
wczeniej (linia 49) podpinalimy identyfikator fizycznego urzdzenia. Linie 70 81 to metoda
zwracajca identyfikator tylnej kamery. Wywoywalimy j wczeniej (linia 45) w celu odnalezienia
identyfikatora kamery. Zasada dziaania jest prosta. Jest ptla, ktrej zawarto jest wykonywana
tyle razy, ile jest kamer w systemie. Przy kadym obrocie sprawdzam czy wanie sprawdzana
kamera to ta odpowiadajca identyfikatorowi tylnej kamery
(CameraInfo.CAMERA_FACING_BACK w linii 75). Gdybymy zechcieli robi zdjcia z uyciem
kamery przedniej, moemy wykorzyta identyfikator CAMERA_FACING_FRONT. Przejdmy do
dalszej czci kodu:
Linie 85-90 to odblokowanie kamery w przypadku np. minimalizacji programu, tak by inne
programy rwnie mogy korzysta z tego urzdzenia. Przesaniam tutaj domyln metod onPause
klasy Activity. Linie 94-97 to implementacja metody onPictureTaken (konieczno wymaga z faktu
e implementujemy interfejs PictureCallBack. Ta metoda jest automatycznie wywoywana w
momencie zrobienia zdjcia. Przy uyciu metody decodeByteArray klasy BitmapFactory (linia 95)
konwertuj obraz w postaci tablicy elementw typu byte do bitmapy. Linia 96 to wywietlenie fotki
na komponencie klasy ImageView. Co z tego wszystkiego jest najwaniejsze? Najwaniejsze
elementy:
Wywoanie metody takePicture obiektu klasy Camera wtedy kiedy chcemy zrobi zdjcie
(linia 65)
201/227
202/227
Odtwarzanie Video
Odtwarza moemy formaty MP4 (MPEG-4), AVC, 3GP. Mamy gotowy komponent ktry
wystarczy przyklei gdzie na aktywnoci. Sam plik video moe znajdowa si ju w aplikacji, ale
moe si te znajdowa np. na karcie SD. W tym przykadzie uruchomi plik video znajdujcy si
w aplikacji. W katalogu res aplikacji dodaj podkatalog raw. Do niego wrzucam plik video.
Wklejony przeze mnie filmik to 2 i p minuty video z taczcymi i piewajcymi parabolami. Nie
wrzucaj zbyt duego pliku video, poniewa przy kadej aktualizacji kodu i ponownym
uruchamianiu programu , cao bdzie uploadowana na emulator lub telefon. Gdyby plik by duy,
trwaoby to niemiosiernie dugo.
203/227
204/227
W linii 18 wida wykomentowany alternatywny sposb. Podaj tutaj ciek do pliku wideo
znajdujcego si poza aplikacj, z uyciem metody setVideoPath. Tutaj dla odmiany moemy poda
ciek jako zwykego Stringa.
Po uruchomieniu aplikacji wszystko dziaa w spodziewany sposb. Jedyna drobna uwaga filmik
nie dopasowuje si do ustawionej wielkoci komponentu VideoView, a wywietla si w swoich
oryginalnych proporcjach. W zwizku z powyszym w orientacji pionowej u mnie (Samsung ACE
3 ) przy propocji ekranu 480:800, wideo zajmuje jak 1/3 ekranu.
205/227
Nagrywanie video
Podczas nagrywania, potrzebny nam bdzie podgld na nagrywany obraz. W tym celu w pliku
layoutu aktywnoci wstawiam komponent SurfaceView. Bdzie robi za mini ekran kamery.
Wielko i szeroko tego podgldu ustawiem na na tyle mae aby zmiecio si na wikszoci
ekranw telefonw z Androidem (parametry layout_width i layout_height). Nie daj fill_parent,
poniewa chc obok jeszcze umieci guzik sucy do rozpoczynania i przerywania nagrywania.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<SurfaceView
android:id="@+id/videoview"
android:layout_width="360px"
android:layout_height="240px"/>
<Button
android:id="@+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nagrywaj"
/>
</LinearLayout>
</LinearLayout>
Trzeba te zadba o niezbdne uprawnienia aplikacji. Moja kamera bdzie rejestrowaa nie tylko
obraz, ale i dwik std te uprawnienia do nagrywania audio. Sam plik z nagraniem zostanie
zapisany na zewntrznej karcie pamici std uprawnienie WRITE_EXTERNAL_STORAGE.
Jeli zamierzasz zapisywa nagrany film w pamici wbudowanej, tego uprawnienia nie
potrzebujesz.
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Przejdmy teraz do kodu ktry bdzie cao obsugiwa. Aby nasza aktywno moga otrzymywa
informacje o tym e powierzchnia podgldu zostaa przygotowana (a bdzie trzeba j przygotowa
przed rozpoczciem nagrywania), nasza aktywno musi implementowa interfejs
SurfaceHolder.CallBack. W zwizku z implementacj tego interfejsu musimy te posiada
zaimplementowan metod onSurfaceChanged (ale nie bdziemy jej tutaj rozwija). W linii 20
definiuj obiekt ktrego uyj do obsugi przycisku (dalej podpinam pod niego referencj do
buttona zdefiniowanego w layoucie). W linii 21 tworz obiekt klasy MediaRecorder. To klasa
suca do rejestracji obrazu i dwiku. W linii 22 tworz obiekt klasy SurfaceHolder. Z uyciem
obiektu tej klasy moemy np. konfigurowa wielko i format nagrania, ale oglnie suy do
Programowanie aplikacji na platform Android v 1.0. A.Klusiewicz www.jsystems.pl
206/227
W linii 23 tworz obiekt ktry bdzie reprezentowa ekran podgldu nagrania. Na ekranie bd
mia te guzik, pocztkowo bdzie na nim napis Nagrywaj. Kiedy nacisn go pierwszy raz, ma
si rozpocz nagrywanie a napis na nim ma si zmieni na Koniec. Kiedy klikn po raz drugi,
ma zosta przerwane nagranie i zapisany plik. Potrzebuj wic zmiennej (linia 24), tutaj typu
boolean ktrej stan bdzie informowa o tym czy trwa nagranie czy nie. Zdefiniowana w linii 25
zmienna sciezkaPliku ma wskazywa nazw i ciek do pliku z nagraniem ktry ma zosta
utworzony. Linie 27-43 to metoda ktra ma obsugiwa naciscinia przycisku. Za pierwszym
klikniciem wykonywany jest kod z linii 39-41, rozpoczyna si nagrywanie a napis na przycisku
zmienia si na Koniec. Przy drugim klikniciu, wykonywany jest kod z linii 28-38. Przerywane
jest nagrywanie, a dodatkowo sprawdziam czy utworzy si plik z nagraniem. Jeli zostanie
faktycznie stworzony, dostan na konsoli LogCata informacj o tym.
207/227
Suy ona ustawieniu rde dwiku i obrazu, jakoci obrazu, maksymalnego czasu nagrania i
maksymalnej wielkoci pliku.
208/227
Przy uruchomieniu aktywnoci, tworzony jest te podgld nagrania. Musimy go przy tej okazji
przygotowa. W metodzie surfaceCreated (wymaganej w zwizku z implementacj interfejsu
Callback) wywouj wic wasna metod prepareMediaRecorder, ktrej jedynym zadaniem jest
wykonanie wyej wspomnianej czynnoci.
209/227
210/227
Grafika 2D
Aby wykonywa jakiekolwiek rysunki, bdziemy potrzebowali ptna na ktrym bdziemy
rysowa. Takie ptno bdzie obiektem klasy Canvas. Tworz zwyczajny projekt, a z ekranu
gwnego usuwam domylnie pojawiajcy si tam kompontent textView1. Zasadniczo nasze ptno
przykryje cao ekranu wcznie z tym komponentem, wic kasowanie go nie jest konieczne.
Obiekt klasy Canvas pocztkowo bdzie pusty. Moemy rysowa obiekty korzystajc z
wyznaczania kolejnych linii wg wsprzdnych, ale moemy te skorzysta z gotowych w klasie
Canvas metod ktre narysuj dla nas wybrane figury geometryczne typu prostokt czy okrg. Aby
stworzy i wykorzystywa nasze ptno, nasza aktywno musi posiada wewntrzn klas
dziedziczc po klasie View dla ktrej przesaniamy metod onDraw przyjmujcej jako parametr
obiekt klasy canvas z ktrego bdziemy korzysta. Myl e posuymy si tutaj obrazem.
Pierwsze co robi, to do aktywnoci na ktrej chc rysowa dodaj klas wewntrzn CanvasView
(nazwa dowolna), dziedziczc po klasie View (android.view.View). Musimy doda do niej
konstruktor przyjmujcy jako parametr kontekst. W zasadzie z kontekstem nic szczeglnego tutaj
nie robimy, jedynie przekazujemy je do super klasy, niemniej taki konstruktor po prostu musi si
tutaj pojawi (wymogi implementacyjne klasy View). Nas bardziej interesuje metoda onDraw, bo
to w niej wanie opisujemy wszystko co ma zosta narysowane na dzie dobry na naszym
ptnie.
211/227
Jak na razie, nic szczeglnego si nie dzieje. Musimy sprawi, by zamiast domylnego layoutu
(tego okrelanego w pliku XML), na ekranie pojawio si nasze ptno.
212/227
Zmiany tej dokonaem podmieniajc parametr dla metody setContentView w metodzie onCreate
naszej aktywnoci. Widzimy to na powyszej ilustracji w linii 26. W linii 25 pozostawiem (dla
przykadu) wykomentowane domylne ustawienie.
Skoro ju wszystko mamy popodpinane, zajmiemy si teraz samym rysowaniem. Dodaem trzy
linie do metody onDraw. W linii 19 definiuj obiekt klasy Paint. Jest to pdzel ktrym bdziemy
rysowa rne ksztaty. Moemy dla niego ustawia rne parametry np. kolor ale o tym za
chwil. Linie 20 i 21 to wywoanie metody drawLine , sucej rysowaniu linii. Przyjmuje ona 5
parametrw. Wg. Kolejnoci: X pocztkowe, Y pocztkowe, X kocowe, Y kocowe, obiekt klasy
paint ktrym rysujemy (nasz pdzel). Narysowaem wic po prostu dwie linie zczone na kocach:
213/227
Efekt:
Pobawimy si teraz kolorami pdzla. Do zmiany jego koloru, suy metoda setARGB klasy Paint
(ktrej nasz pdzel jest obiektem). Przyjmuje ona cztery parametry. Pierwszy to stopie
przeroczystoci linii / figury. 0 to cakowita przeroczysto czyli w praktyce niewidoczno,
255 to cakowita nieprzezroczysto. Kolejne trzy parametry to RGB - stopie nasycenia trzech
kolorw wg kolejnoci : Red, Green,Blue. Przyjmowane wartoci to 0-255. Przed narysowaniem
pierwszej linii ustawiam kolor pdzla na czerwie (255 dla RED, reszta 0), nastpnie rysuj lini.
Ponownie zmieniam kolor pdzla, tym razem na zielony (255 dla GREEN, reszta 0) i znowu rysuj
lini:
Efekt:
214/227
Wzbogaciem kod o kolejne kilka linii. Zmieniem kolor pdzla na niebieski i dorysowaem kolejn
lini. Doszo nam wywoanie metody setStrokeWidth dla pdzla (linia 25). Ustawia ona grubo
linii pdzla:
Efekt:
215/227
Stworzyem nowy projekt, wszystko na identycznej zasadzie jak w poprzednim przykadzie. Rni
si tylko zawartoci metody onDraw:
Metoda setARGB jest ju znana z poprzednich przykadw, jednak tutaj pobawiem si troszk
przezroczystoci. Z nowych rzeczy mamy tutaj dwukrotne wywoanie metody drawRect klasy
Canvas. Metoda ta suy rysowaniu prostoktw. Pierwsze dwa argumenty to wsprzdne (x,y)
jednego z rogw, kolejne dwa to wsprzdne(x,y) rogu przeciwlegego. W tym przypadku wedug
kolejnoci lewy grny i prawy dolny. Ostatni argument to obiekt klasy Paint, czyli pdzel ktrym
bdziemy rysowa. Tutaj narysowaem dwa prostokty jeden nieprzezroczysty fioletowy ((?)
sorry, mczyni nie rozrniaj kolorw zbyt szczegowo) , drugi czciowo przezroczysty w
kolorze szybki przyciemnianych okularw (?). Drugi ma ustawion czciow przezroczysto. W
przypadku rysowania pierwszego prostokta przezroczysto dla pdzla ustawiem na 0, w drugim
na 100. Efekt wyglda tak:
216/227
Rysowanie kek nie sprawia rwnie wielu problemw. Stworzyem kolejny projekt, tym razem
metoda onDraw wyglda tak:
Generalnie do rysowania k suy metoda drawCircle ktra przyjmuje cztery parametry. Pierwsze
dwa to X i Y rodka koa, trzeci to promie, a czwarty to pdzel ktrego parametry ustawiamy na
identycznych zasadach co wczeniej. Zaprzgnem tutaj ptle do wyrysowania mi kilku k, ktre
czsciowo na siebie nachodz. W zasadzie cay kod to rysowane w ronych miejscach koa, ze
zmian waciwoci pdzla. Efekt wyglda tak :
217/227
Pierwsze uprawnienie daje nam moliwo korzystania z Bluetooth, drugie jego wczania i
wyczania (a musimy mie tak moliwo w razie gdyby w urzdzeniu BT byo wyczone).
Napiszemy aplikacj ktra bdzie w stanie :
Rozgosi fakt swojego istnienia, tak by inne urzdzenia skanujc w poszukiwaniu sprztu z
BlueTooth mogy nas zobaczy. Jeli urzdzenia nie s ze sob sparowane, urzdzenie nie
siejce informacji o swoim istnieniu nie bdzie widoczne.
Nasza aplikacja bdzie moga dziaa zarwno jako client, jak i jako serwer. Zalee to bdzie od
tego, ktry przycisk naciniemy. Aby mc testowa aplikacj najlepiej bdzie by wyposay si w
dwa fizyczne urzdzenia wyposaone w BlueTooth. Przyklejam par guzikw, ktre bd
uruchamia wczeniej omwione funkcje. Na komponencie TextView na ktrym aktualne
wywietlam napis TextView w momencie uruchomienia aplikacji pokae si adres mac naszego
urzdzenia. Na TextView na ktrym pocztkowo wywietla si bdzie napis Poczenie nie
nawizane, wywietli si pniej tryb dziaania aplikacji jako serwer lub jako client. W polu
edycyjnym bdziemy wpisywa mac adres urzdzenia ktre bdzie pracowao jako serwer.
Wstawiem tutaj adres swojego telefonu, eby pniej nie musie kadorazowo go podawa.
218/227
219/227
Wyjanienia mog wymaga jedynie linie 67-69 i 75-78. W zalenoci od tego czy aplikacja na
danym urzdzeniu bdzie pracowa jako serwer czy client, wywoywane s wtki realizujce
zadania danej strony. Oparem to na wtkach, poniewa np. oczekiwanie na poczenie , czy proces
czenia s operacjami ktre blokowayby wtek gwnej aktywnoci. W ten sposb wtki pracuj
sobie asynchronicznie, a aplikacja nie blokuje si. Obiekt ba z linii 76 reprezentuje fizyczny
adapter Bluetooth urzdzenia. Linia 77 to pobranie mac adresu wpisanego w pole edycyjne. Bdzie
nam ten adres potrzebny, po przekazujemy go przez parametr konstruktora do wtku clienta. Musi
on wiedzie jaki jest adres urzdzenia z ktrym ma si czy. W liniach 68 i 75 w zalenoci od
trybu dziaania aplikacji, wywietlam na stosownym polu na ekranie, jak rol spenia aplikacja
(czy jest serwerem czy clientem).
220/227
Przejdmy dalej. Linie 85,86 to wywietlenie mac adresu urzdzenia na ekranie oraz konsoli. W
dalszej czci metody onCreate aktywnoci (linie 87-91) obsuguj sytuacj gdyby okazao si, e
BlueTooth na urzdzeniu jest wyczony. Aktywno BT weryfikuj metod isEnabled() klasy
BluetoothAdapter (linia 87). Jeli okae si e jest wyczony, wywietlam komunikat z prob o
zgod na wczenie BT. Poniewa intencj z prob wywouj z uyciem startActivityForResult,
dodaem te metod onActivityResult ktra jest automatycznie wywoywana przez system kiedy
uytkownik udzieli zgody na wczenie BT (albo i nie udzieli :p). Jeli uytkownik udzieli zgody,
sam system uruchomi BT a nam pozostaje tylko zainicjalizowanie obiektu ktrego bdziemy
uywa do komunikowania si z fizycznym adapterem BT i ewentualnie wywietlenie informacji
na konsoli.
Przeszkoczymy na razie definicj obiektu klasy BroadcastReceiver (linie 102-117), wrcimy do niej
za chwil, a na razie przyjrzymy si metodom na kocu klasy.
Metoda dajSieWykryc() sprawia, e nasze urzdzenie jest widoczne dla innych urzdze ktre
skanuj w poszukiwaniu kolegw :). Jeli o to nie zadbamy a urzdzenia nie bd sparowane,
nasze nie bdzie widoczne dla innych. Linie 121 i 123 s odpowiedzialne za wywietlenie zapytania
o moliwo ujawnienia si i rozpoczcie rozgaszania swojego istnienia. Linia 122 to opcjonalna
konfiguracja czasu rozgaszania. Domylnie urzdzenie rozgaszaoby przez 2 minuty, natomiast
podaem mu warto 300 (sekund) , dziki czemu bdzie widoczny przez 5 minut.
221/227
cznie dziaanie tych dwch elementw przedstawia si w ten sposb, e metoda wykryjInne()
rozpoczyna poszukiwanie innych urzdze, a gdy jaki znajdzie to zostaje automatycznie wywoana
metoda onReceive obiektu klasy BroadcastReceiver zarejestrowanego jako odbiorca takiego
zdarzenia. W sumie, na konsoli zostan wywietlone informacje o dostpnych w okolicy
urzdzeniach. Po uruchomieniu na konsoli widz znalezione urzdzenie (jeli zostan wykryte,
pojawi si ich wicej ;)) :
222/227
Jej zadaniem jest sprawdzenie listy urzdze ktre wczeniej sparowalimy i wywietlenie
informacji o nich na ekranie. Ta metoda nie sprawdza czy urzdzenia te s dostpne , a jedynie
wywietla informacje o zarejestrowanych urzdzeniach ktre s przechowywane w systemie:
223/227
W linii 15 definiuj socket przy uyciu ktrego bdzie odbywaa si komunikacja. Zagadkowe
mog si wyda linie 21 i 22. Usuga musi mie unikalny identyfikator, dziki ktremu bdzie
jednoznacznie rozpoznawana ( http://en.wikipedia.org/wiki/Universally_unique_identifier ). W tych
liniach nasz usug rejestruj pod nazw Usuga witajca pod identyfikatorem
550e8400-e29b-41d4-a716-446655440000
Ten akurat identyfikator jest cakiem przypadkowy, skopiowaem jaki przykad takiego
identyfikatora z internetu. Linie 27-54 to klasyczna implementacja procesu nasuchu, rnica
polega na tym, e nie sieciowego a na bluetooth. Wtek czeka na kontakt ze strony serwera, po
czym otwiera strumie i wysya tekst Witaj kolego!.
224/227
Strona kliencka:
Po tej stronie otwieram socket dla poczenia z serwerem (podobnie jak po stronie serwerowej nie
socket sieciowy a po bluetooth) i odczytuj co mi serwer przysa.
Uruchamiam teraz program na obu urzdzeniach, telefon robi za serwer, tablet za clienta.
225/227
Po stronie clienta:
226/227
Gdyby zechcia rozwija ten program, lub na jego bazie napisa co swojego, pamitaj e mamy
do czynienia z nieco innym ni sieciowy protokoem i usuga BT z jednej strony moe si czy
tylko z jedn inn usug.
227/227