<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;C0UFQns9fCp7ImA9WhRaFko.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445</id><updated>2012-02-19T18:06:53.564+01:00</updated><category term="PendingIntent" /><category term="galaxy" /><category term="SharedPreferences" /><category term="Notification" /><category term="InputStream" /><category term="Market" /><category term="początki" /><category term="AndroidManifest" /><category term="onTouch" /><category term="programowanie" /><category term="galaxy s II" /><category term="test" /><category term="AsyncTask" /><category term="ganymed" /><category term="sdk" /><category term="appWidgetProvider" /><category term="IBinder" /><category term="onUpdate" /><category term="i9100" /><category term="Paint" /><category term="zdjęcia" /><category term="Android" /><category term="konfiguracja" /><category term="ListView" /><category term="onDraw" /><category term="tunel" /><category term="recenzja" /><category term="onResult" /><category term="BufferReader" /><category term="Service" /><category term="TabWidget" /><category term="SSH" /><category term="Petycja" /><category term="Hello world" /><category term="NotificationManager" /><category term="Thread" /><category term="AdMob" /><category term="doInBackground" /><category term="SQLiteDatabase" /><category term="Spannable" /><category term="Java" /><category term="NetBeans" /><category term="URLConnection" /><category term="samsung" /><category term="handler" /><category term="setOnTouchListener" /><category term="sdcard" /><category term="Toast" /><category term="Timer" /><category term="onActivityResult" /><category term="iPhone" /><category term="Społeczność" /><category term="emulator" /><category term="instalacja" /><category term="FrameLayout" /><category term="openOrCreateDatabase" /><category term="TextView" /><category term="EditText" /><category term="SimpleCursorAdapter" /><category term="setOnClickListener" /><category term="Cursor" /><category term="widget" /><category term="AppWidgetManager" /><category term="intents" /><title>HelloAndroid.pl</title><subtitle type="html">Kurs programowania na platformie Google Android od zera...</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.helloandroid.pl/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ProgramowanieNa-androidablogspotpl" /><feedburner:info uri="programowaniena-androidablogspotpl" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEYMR3g-eyp7ImA9WhZXFEQ.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-2313367761240603501</id><published>2011-05-03T11:45:00.013+02:00</published><updated>2011-05-04T10:03:06.653+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-04T10:03:06.653+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="i9100" /><category scheme="http://www.blogger.com/atom/ns#" term="samsung" /><category scheme="http://www.blogger.com/atom/ns#" term="galaxy s II" /><category scheme="http://www.blogger.com/atom/ns#" term="recenzja" /><title>Recenzja: Samsung Galaxy S II i9100</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;Od 14 lutego, czyli od oficjalnej prezentacji nowego modelu Samsunga przestępowałem z nogi na nogę w oczekiwaniu na pojawienie się nowego Galaxy S II w oficjalnej sprzedaży. Samsung kazał nam sporo czasu czekać na ten moment. No ale w końcu jest. Co prawda mój nie pochodzi jeszcze z oficjalnej sprzedaży, ale myślę, że po kilku dniach użytkowania mogę już co nie co o nim powiedzieć.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-j1mZhHksX64/Tbv_PdTgb7I/AAAAAAAACE8/MMM21YVUTqQ/s1600/PICT4999.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="265" src="http://2.bp.blogspot.com/-j1mZhHksX64/Tbv_PdTgb7I/AAAAAAAACE8/MMM21YVUTqQ/s400/PICT4999.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;i&gt;Uwaga!&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;Świadomie pomijam w tekście większość szczegółów technicznych, cyferek i benchmarków, które w rzeczywistości rzadko mają  odniesienie w codziennej eksploatacji. Postaram skupić się jedynie na subiektywnych odczuciach i zboczeniach ;)&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Za punkt odniesienia (bo jakiś trzeba przyjąć), przyjąłem obecnie królującą wersję Samsunga Galaxy. Czyli model Galaxy S i9000.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.helloandroid.pl/2011/04/galeria-samsung-galaxy-s-ii.html"&gt;&lt;b&gt;Zapraszam także do obejrzenie małej foto-sesji nowego Samsunga.&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Budowa&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Telefon jest duży. Choć teoretycznie różnice na papierze w stosunku do poprzednika są niewielkie, telefon przekroczył pewną granicę, być może kolejną, na której do tej pory stał według mnie Galaxy S pierwszej generacji. Dużej różnicy w rozmiarach nie zauważymy nawet zestawiając bezpośrednio oba te telefony obok siebie. Wyraźna różnica pojawia się dopiero wówczas gdy weźmiemy telefon do ręki. Od razu dostrzeżemy nowe rozmiary, no i przede wszystkim nowy kształt. Nowa eska straciła zaokrąglone rogi, telefon stał się jeszcze bardziej płaski (wrażenie dzięki prostym ściankom bocznym i zwiększonej szerokości urządzenia), a sam telefon stracił na wadze. Składając powyższe do kupy, no cóż, musimy uczyć się Samsunga od nowa.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-SSCh-SrgdfE/Tbv_p6elfcI/AAAAAAAACG8/Nl3ms3O4pxQ/s1600/PICT5064.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-SSCh-SrgdfE/Tbv_p6elfcI/AAAAAAAACG8/Nl3ms3O4pxQ/s320/PICT5064.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Telefon wykonany jest z podobnych materiałów jak jego poprzednik. Jest plastikowy, ale to całkiem porządny plastik. Na uwagę zasługuje świetne spasowanie elementów. Nic nie piszczy, nie trzeszczy i nie wygląda aby miało to się zmienić pod dłuższej eksploatacji. Zmianie uległa za to pokrywka baterii, która od teraz nie tworzy kompletnego tyłu telefonu, a jest jedynie mała klapką o długości mniejszej od samego aparatu. Sama klapka zyskała ciekawą fakturę, dzięki której telefon wygląda trochę „dostojniej”.&lt;br /&gt;
&lt;br /&gt;
Istotną zmianą w samej konstrukcji było przeniesienie gniazda ładowania (micro usb) z górnej ścianki na dolną. Poprawę odczują szczególnie wszyscy Ci, którzy chcą skorzystać z ładowarki biurkowej (typu dock) albo telefonu jako nawigacji samochodowej. Łagodnie rzecz ujmując, obecne rozwiązanie nie należało do najbardziej szczęśliwych.&lt;br /&gt;
&lt;br /&gt;
Wracając do rozmiarów. Samsung nie zwiększył rozmiarów nowego Galaxy nadaremno. Powodem tego rozrostu jest przede wszystkim nowy, powiększony o prawie jedną trzecią cala w stosunku do poprzednika, wyświetlacz.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Wyświetlacz&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://1.bp.blogspot.com/-0VPopuY5lbI/Tbv_Wf5AzfI/AAAAAAAACFQ/X4-iwd_sbN8/s1600/PICT5011.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-0VPopuY5lbI/Tbv_Wf5AzfI/AAAAAAAACFQ/X4-iwd_sbN8/s320/PICT5011.JPG" width="320" /&gt;&lt;/a&gt;Galaxy S i9000 ze swoim Super AMOLED’em pod względem jasności i nasycenia barw nie miał konkurencji. Wyświetlacz ten robił, no i robi cały czas, wrażenie właściwie na wszystkich, którzy mieli z nim do czynienia. Ma tylko jedną wadę. Rozdzielczość. Ale tą prawdziwą. Teoretycznie rozdzielczość wyświetlacza to 800x480 pikseli. Jednak problem polega na tym, iż jego konstrukcja opiera się o matrycę typu PenTile, która do wyświetlania obrazu wykorzystuje piksele złożone z dwóch subpikseli. Większego subpiksela koloru niebieskiego lub czerwonego oraz mniejszego zielonego. Dlatego też, aby wyświetlić jeden punkt (kolor), na który składają się kolory z palety RGB potrzebne jest “zapalenie” dwóch sąsiednich pikseli. Powoduje to wrażenie ziarnistości ekranu, no i de facto obniża to realną rozdzielczość ekranu.&lt;br /&gt;
&lt;br /&gt;
W nowym Samsungu zrezygnowano z technologii PenTile wprowadzając nowy typ wyświetlaczy - Super AMOLED Plus, który do wyświetlania obrazu używa tradycyjnej konstrukcji pikseli składających z trzech subpikseli RGB. Dlatego też, przy zachowaniu dotychczasowej  rozdzielczości (800x480px), zwiększeniu wyświetlacza do rozmiaru 4.3 cala, uzyskano bardzo jasny, czysty obraz z mniejszym „ziarnem”.&lt;br /&gt;
&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Bialy duzy */
google_ad_slot = "9684121894";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/td&gt; &lt;td&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Bialy duzy */
google_ad_slot = "9684121894";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;br /&gt;
Podsumowując. Jest dobrze. Nawet bardzo dobrze. Piksele są prawie niewidoczne, a soczystość kolorów oraz jasność przebiły według mnie o głowę i9000. Po każdorazowej zabawie nowym Galaxy, wracając do starego czuje się jakbym się cofnął o epokę. Jednak wystarczy na trochę odstawić dwójkę, a znów dostrzegamy jak dobry wyświetlacz zamontowany został w pierwszym Galaxy S.&lt;br /&gt;
&lt;br /&gt;
Zwiększenie wyświetlacza pozytywnie wpłynęło na komfort użytkowania smartphona. Redagowanie maili, przeglądanie Internetu sprawia coraz większą frajdę, na którą składa się jeszcze jeden ważny, jak nie najważniejszy czynnik...&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Wydajność&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Mimo iż Galaxy S uważany był za wydajnościowego potworka, nie zawsze odzwierciedlało się to  w wydajności samego systemu, a raczej interfejsu. Minimalne zacięcia podczas przewijania ekranów, oczekiwanie na otwarcie najbardziej prozaicznych funkcji jak telefon czy skrzynka odbiorcza sms’ów, potrafiło wystarczająco zirytować, szczególnie jeśli ktoś miał do czynienia np. z iPhonem czwartej generacji. Te małe opóźnienia (najczęściej nie przekraczające sekundy, ale jednak) potrafiły sprawić, że cały czar z obcowania z Galaxy pryskał.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/-Kbuep5plgUo/Tbv_tTGaCHI/AAAAAAAACHM/hXirSX9x78A/s1600/PICT5072.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="211" src="http://4.bp.blogspot.com/-Kbuep5plgUo/Tbv_tTGaCHI/AAAAAAAACHM/hXirSX9x78A/s320/PICT5072.JPG" width="320" /&gt;&lt;/a&gt;Na szczęście wraz z nadejściem nowego Samsunga wszystko się zmieniło. Jest bardzo szybko. Interfejs działa ot tak. Natychmiastowo. Wydajność samego systemu zaskakuje. Do tej pory opóźnienia w reakcji np. w markecie brałem na karb opóźnień związanych z transmisją danych. Dopiero teraz widzę ile mojego czasu marnowało samo urządzenie. Nowy Galaxy działa teraz tak, że chce się go po prostu używać.&lt;br /&gt;
&lt;br /&gt;
Muszę tutaj przypomnieć, że mój egzemplarz nie pochodzi z produkcyjnej serii, soft pewnie też nie jest najnowszy. Co widać w wynikach w Quadrancie. Najlepszy wynik jak zdołałem osiągnąć, a raczej zdołał osiągnąć Galaxy S II to 2700 punktów. Telefony, które trafiły do sprzedaży kręcą regularnie wyniki w okolicach 3500 punktów. Tak więc, jeśli wydajność telefonu w ostatecznej wersji jeszcze wzrosła, to szapo ba.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;TouchWiz 4&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Nie wiem gdzie podziały się dwie pierwsze wersję nakładki TouchWiz, zapewne zagubiły się gdzieś w zamieszłych czasach panowania Windowsa Mobile 6.0 albo i lepiej. Pewne jest jednak to, że TouchWiz w wersji, którą możemy spotkać zarówno w Samsungach z systemem Android jak i Bada jest całkiem udanym rozwiązaniem. Nie da się też za bardzo ukryć faktu, że wzorowany jest na rozwiązaniu pochodzącym z konkurencyjnej platformy z pod znaku zgniłego.... wróć nadgryzionego jabłka, czyli  iOS. Skoro jednak tam się tak dobrze przyjęło, to i może warto dobre wzorce zaadaptować i kopiować na kolejne platformy. Z tego założenia wyszło też zapewne kierownictwo Samsunga. Czy jest to etyczne i zgodne z prawem? Hmm. Nie mi to oceniać. Idźmy dalej.&lt;br /&gt;
&lt;br /&gt;
W nowym Galaxy zadebiutowała czwarta wersja tytułowego interfejsu. Jak i w poprzedniej wersji, zasadniczą część pełnią cztery ikony umieszczone na dolnym pasku, tj. telefon, kontakty, wiadomości oraz aplikacje (oczywiście mogą znaleźć się tutaj dowolne ikony dowolnych aplikacji). Wspomniany pasek dolny stracił tło oraz linię oddzielającą go od pozostałej części ekranu. Ale są to drobne zmiany, których znaleźć można więcej, a nie stanowią one o postępie rozwoju TouchWiz’a.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/-8Qu4z4jlgkM/Tbv_qxLQETI/AAAAAAAACHA/jENDwBs0GG0/s1600/PICT5065.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-8Qu4z4jlgkM/Tbv_qxLQETI/AAAAAAAACHA/jENDwBs0GG0/s320/PICT5065.JPG" width="320" /&gt;&lt;/a&gt;To co mi się spodobało i co się zmieniło w nowym TouchWizie, to przede wszystkim widgety.&lt;br /&gt;
Od teraz widgety stały się prostokątne, co sprawia, że pasują  do całego kanciastego stylu telefonu. Lepiej też zagospodarowują miejsce na pulpicie. Widgetów znacznie przybyło, pojawiło się w końcu kilka nowych odpowiedzialnych za kalendarz, agendę, plan dnia, pogodę czy kilka nawet nieźle wyglądających zegarków. Większość z tych widgetów ma możliwość zmiany rozmiarów, tak aby móc w pełni wykorzystać przestrzeń jaką oferują nam poszczególne pulpity.&lt;br /&gt;
&lt;br /&gt;
Cieszę się, że Samsung zdecydował się zmienić styl widgetów. Niestety te, które oferował TouchWiz 3, nie urzekały wyrafinowaniem, były zbyt cukierkowe. Nie będę ukrywał, nie polubiłem się z widgetami z TW3, szczególnie po przejściu z IMHO świetnego HTC Sense, z którego korzystałem na już obecnie zabytkowym HTC Hero.&amp;nbsp;Oczywiście zdaję sobie sprawę, że większość widgetów dostarczanych jest z aplikacjami 3rd-party i nad kontrolą ich stylu za bardzo ani my ani tym bardziej Samsung wpływu nie ma, ale gdyby jednak Samsung zdecydował się rozwijać i dewelopwać kolejne widgety, z pewnością wpłynęło by to pozytywnie na spójność wyglądu oraz ład na pulpicie.&lt;br /&gt;
&lt;br /&gt;
Co jeszcze się zmieniło. Zmieniły położenie cyferki identyfikujące pulpity i to za równo na głównym pulpicie jak i na liście aplikacji. Od tej pory ich miejsce znajduje się tuż nad dolnym paskiem “4 ikon”. Zmienił się także, a właściwie został dodany nowy sposób przewijania/przeglądania pulpitów. Wystarczy przytrzymać palec na wspomnianych cyferkach i przesuwać ów palec z lewa na prawo bądź też odwrotnie, a za pomocą bardzo fajnego efektu będziemy mogli przemieszczać się z pulpitu na pulpit.&lt;br /&gt;
&lt;br /&gt;
&lt;object height="390" width="640"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/sMaZ2QrFt94?fs=1&amp;hl=pl_PL&amp;hd=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/sMaZ2QrFt94?fs=1&amp;hl=pl_PL&amp;hd=1" type="application/x-shockwave-flash" width="640" height="390" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;br /&gt;
Z godnych pochwał zmian, należy też wspomnieć o możliwości tworzenie katalogów oraz nowych stron aplikacji (zastosowania tego akurat nie do końca rozumiem). Możliwość tworzenia katalogów docenią wszyscy Ci, u których liczbę zainstalowanych aplikacji liczy się już w dziesiątkach a nawet setkach. To był dobrych ruch ze strony Koreanczyków.&lt;br /&gt;
&lt;br /&gt;
Podobnych zmian jest jeszcze kilka.. Ale czy są one rewolucyjne? Raczej nie. To po prostu kolejny krok w ewolucji nakładki z serii TouchWiz, która w połączeni z całkiem szybkim sprzętem sprawia całkiem pozytywne wrażenie.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Foto/Video&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Zmiany nie mogły ominąć i tego obszaru. Matryca aparatu zyskała kolejne 3 mln pikseli. Ma ich już w tym momencie osiem. O module kamery również nie zapomniano. Obecnie telefon dysponuje możliwością nagrywania w full hd (1080p).&lt;br /&gt;
&lt;br /&gt;
Niewątpliwie najważniejszą zmianą było dołożenie lampy błyskowej (a raczej “diody błyskowej”). Co ważne, korzystać z niej możemy nie tylko podczas wykonywania zdjęć, ale także podczas filmowania, co jest dla mnie osobiście świetną wiadomością.&lt;br /&gt;
&lt;br /&gt;
Poniżej zamieszczam kilka zdjęć i klipów  wykonanych przy pomocy Samsunga. Podkreślam, że telefon, którym dysponowałem nie ma najprawdopodobniej ostatecznej wersji softu.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-SiLKv0AQABo/Tb-5o18R47I/AAAAAAAACH4/-wPjF-EeRNg/s1600/2011-05-01+19.06.58.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="120" src="http://4.bp.blogspot.com/-SiLKv0AQABo/Tb-5o18R47I/AAAAAAAACH4/-wPjF-EeRNg/s200/2011-05-01+19.06.58.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-oA6opONCYfg/Tb-5yiR1ETI/AAAAAAAACH8/7VLVv3MYkMk/s1600/2011-05-01+19.07.13.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="120" src="http://3.bp.blogspot.com/-oA6opONCYfg/Tb-5yiR1ETI/AAAAAAAACH8/7VLVv3MYkMk/s200/2011-05-01+19.07.13.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-FW0k4RuEDSo/Tb-6Avq0zPI/AAAAAAAACIA/p-mmw4DdA2w/s1600/2011-05-01+19.09.34.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="120" src="http://4.bp.blogspot.com/-FW0k4RuEDSo/Tb-6Avq0zPI/AAAAAAAACIA/p-mmw4DdA2w/s200/2011-05-01+19.09.34.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-2fa7SsqzorQ/Tb-6OkXz5xI/AAAAAAAACIE/hfePvIBwRos/s1600/2011-05-01+19.09.41.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="120" src="http://4.bp.blogspot.com/-2fa7SsqzorQ/Tb-6OkXz5xI/AAAAAAAACIE/hfePvIBwRos/s200/2011-05-01+19.09.41.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object height="390" width="640"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/1BMU5-EZ540?fs=1&amp;hl=pl_PL&amp;hd=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/1BMU5-EZ540?fs=1&amp;hl=pl_PL&amp;hd=1" type="application/x-shockwave-flash" width="640" height="390" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Muzyka&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Pozytywnie zaskoczył mnie odtwarzacz muzyki. Przesłuchałem tę samą płytę w formacie FLAC, zarówno na pierwszej wersji  Galaxy S jak i na drugiej. Dźwięk sprawia wrażenie bardziej detalicznego oraz wyraźnego. Dodatkowo jest o wiele głośniej. Odsłuch przeprowadzony na tych samych słuchawkach.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Zasilanie&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Dwa procesory, a raczej rdzenie, wydajny układ graficzny Exynos, duży wyświetlacz, 1 GB pamięci operacyjnej to wszystko musi zostać nakarmione. Jeżeli powiem, że działa nie krócej niż poprzednik to będzie oznaczało to bardzo dobry wynik. Ostateczny wynik i tak będzie zależał od konkretnego ROM’u.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Podsumowanie&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Śmiało można powiedzieć, że ulepszenia dotknęły nowego Galaxy na wszystkich frontach. Lepszy wyświetlacz, lepszy procesor, lepszy aparat i wiele innych (ma się rozumieć - lepszych rzeczy)). Wszystko to sprawia, że rozwój serii Galaxy S idzie w dobrą stronę. Widać, że Samsung jako firma nie drepcze w miejscu.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/-Y4gQRZyBydo/Tbv_juOgB-I/AAAAAAAACGU/wdnucx0hLmc/s1600/PICT5047.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-Y4gQRZyBydo/Tbv_juOgB-I/AAAAAAAACGU/wdnucx0hLmc/s320/PICT5047.JPG" width="320" /&gt;&lt;/a&gt;Jedynie nie mogę oswoić się z jego nowymi wymiarami i nie wiem czy ich zwiększenie to był dobry ruch ze strony Samsunga. Według mnie telefon trzyma się trochę gorzej od poprzednika. Jest jednak bardzo subiektywna opinia. Wszystko zależy od osobistych preferencji, rozmiaru dłoni itp. Z drugiej strony Galaxy S pierwszej generacji był już na tyle sporym urządzaniem, że chcąc go używać było trzeba zaakceptować wymiary odbiegającej od przeciętnej dzisiejszych komórek. Dlatego myślę, że dochodzimy tutaj do sedna sprawy. Galaxy S jak i Galaxy S II należą niewątpliwie do zacnej grupy urządzeń określanych mianem smartphonów, to też kupując je oczekujemy przede wszystkim posiadania przenośnego komputera w kieszeni. Smartphone umożliwia dzisiaj praktycznie wszystko to co umożliwia pełnowymiarowy komputer. Jest tylko jedno ograniczenie. Ergonomia. Jest oczywistym, że chcielibyśmy aby te wszystkie funkcje oferowane przez telefon nie były jedynie protezami pełnowymiarowych aplikacji, a ich godnym zamiennikiem. Dlatego też, jeżeli podejdziemy w ten sposób do sprawy, to okaże się, że może warto przeboleć pozorną niewygodę korzystania z urządzenia jako zwykłej “słuchawki” wynikającą z większych rozmiarów na rzecz posiadania niewyobrażalnie multifunkcyjnego kombajnu. Jak to mówią, albo rybki albo akwarium.&lt;br /&gt;
&lt;br /&gt;
Na koniec pytanie na które pewnie wszyscy czekają. Czy warto zamieniać eske pierwszej generacji na nową. To zależy. Tak, jeśli kogoś nie zadowala wydajność obecnej wersji.&lt;br /&gt;
Myślę jednak, że nowy Galaxy pokaże pazur wówczas, kiedy do poziomu jego możliwości doszlusują nowe aplikacje i gry potrafiące wykorzystać potencjał nowego układu graficznego i procesora.. Dlatego, jeśli dla kogoś Galaxy S jest już w tej chwili za wolny to z pewnością może się zastanowić nad jego wymianą. Ulepszenia w pozostałych dziedzinach są duże, jednak racjonalnie patrząc, nie koniecznie uzasadniają wymianą telefonu na nowszy model.  Wyświetlacz jest lepszy, ale w starym Samsungu też jest bardzo dobry. Różnice widać dopiero gdy zestawi się oba aparaty obok siebie. A propos aparatu, też nie jest to chyba powód, dla którego powinniśmy czym prędzej pobiec do sklepu po nowego Samsunga. Upchnęli kolejne trzy miliony pikseli, dodali full hd, jednak fizyki nawet Samsung nie oszuka i obiektyw(ik) jest jaki jest.&lt;br /&gt;
&lt;br /&gt;
Ok. Już dość tego marudzenia. Jeszcze ktoś poważnie pomyśli, że nie warto kupować nowego Samsunga. Otóż nie. Warto. Bo sęk w tym, że gdyby telefon był usprawniony tylko na jednym z tych pól to rzeczywiście wątpliwym pomysłem byłaby wymiana obecnie posiadanego modelu (mam na myśli i9000). Biorąc jednak pod uwagę, że telefon ten został poprawiony pod każdym względem to otrzymujemy zupełnie nowy produkt, który jest wart swojej ceny.&lt;br /&gt;
&lt;br /&gt;
Acha. Chyba nie muszę dodawać, że jeśli ktoś nie jest obecnie posiadaczem obecnego modelu i9000, to nie powinien zastanawiać się minuty dłużej nad oczywistym wyborem telefonu z Androidem na pokładzie jaki może być w tej chwili tylko jeden. &lt;b&gt;Samsung Galaxy S II&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-BwDEbwvMHFo/Tbv_axQA0WI/AAAAAAAACFk/SQJH_uLrm3k/s1600/PICT5017.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-BwDEbwvMHFo/Tbv_axQA0WI/AAAAAAAACFk/SQJH_uLrm3k/s320/PICT5017.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-2313367761240603501?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ev4eeCKnJ0GrtoEmTTKU75Qi2Lk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ev4eeCKnJ0GrtoEmTTKU75Qi2Lk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ev4eeCKnJ0GrtoEmTTKU75Qi2Lk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ev4eeCKnJ0GrtoEmTTKU75Qi2Lk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/xtJFtivvJxU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/2313367761240603501/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2011/05/recenzja-samsung-galaxy-s-ii-i9100.html#comment-form" title="Komentarze (14)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2313367761240603501?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2313367761240603501?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/xtJFtivvJxU/recenzja-samsung-galaxy-s-ii-i9100.html" title="Recenzja: Samsung Galaxy S II i9100" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-j1mZhHksX64/Tbv_PdTgb7I/AAAAAAAACE8/MMM21YVUTqQ/s72-c/PICT4999.JPG" height="72" width="72" /><thr:total>14</thr:total><feedburner:origLink>http://www.helloandroid.pl/2011/05/recenzja-samsung-galaxy-s-ii-i9100.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIGQXs_eCp7ImA9WhZXFU8.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-2091888295672633988</id><published>2011-05-02T10:00:00.001+02:00</published><updated>2011-05-04T17:38:40.540+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-04T17:38:40.540+02:00</app:edited><title /><content type="html">&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Bialy duzy */
google_ad_slot = "9684121894";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/td&gt; &lt;td&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Bialy duzy */
google_ad_slot = "9684121894";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-2091888295672633988?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/v7Gm14S2v7Kw8fqyaWqk4KGXmF8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/v7Gm14S2v7Kw8fqyaWqk4KGXmF8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/v7Gm14S2v7Kw8fqyaWqk4KGXmF8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/v7Gm14S2v7Kw8fqyaWqk4KGXmF8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/QM6lxyWhYwU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/2091888295672633988/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2011/04/reklama.html#comment-form" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2091888295672633988?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2091888295672633988?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/QM6lxyWhYwU/reklama.html" title="" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.helloandroid.pl/2011/04/reklama.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEDR3w-cCp7ImA9WhZXEUs.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-4730072003363168626</id><published>2011-04-30T14:47:00.000+02:00</published><updated>2011-04-30T14:47:56.258+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-30T14:47:56.258+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="zdjęcia" /><category scheme="http://www.blogger.com/atom/ns#" term="galaxy" /><category scheme="http://www.blogger.com/atom/ns#" term="i9100" /><category scheme="http://www.blogger.com/atom/ns#" term="samsung" /><title>Galeria: Samsung Galaxy S II</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Przed właściwą recenzją zamieszczam parę fotek nowego Samsunga. Solo oraz za starszym bratem.&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=pl&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F111603046604080063064%2Falbumid%2F5601355685718972257%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCKK_m-GyisntSQ%26hl%3Dpl" height="400" pluginspage="http://www.macromedia.com/go/getflashplayer" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="600"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-4730072003363168626?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Y_l4PEVFCgDLhbWbJiN1h1_NEQ4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y_l4PEVFCgDLhbWbJiN1h1_NEQ4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Y_l4PEVFCgDLhbWbJiN1h1_NEQ4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y_l4PEVFCgDLhbWbJiN1h1_NEQ4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/SEq-gOlFiKg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/4730072003363168626/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2011/04/galeria-samsung-galaxy-s-ii.html#comment-form" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/4730072003363168626?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/4730072003363168626?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/SEq-gOlFiKg/galeria-samsung-galaxy-s-ii.html" title="Galeria: Samsung Galaxy S II" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.helloandroid.pl/2011/04/galeria-samsung-galaxy-s-ii.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMCQnk8eSp7ImA9WhZXFEQ.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-7245523479224706786</id><published>2011-04-30T00:29:00.007+02:00</published><updated>2011-05-04T09:01:03.771+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-04T09:01:03.771+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="galaxy" /><category scheme="http://www.blogger.com/atom/ns#" term="i9100" /><category scheme="http://www.blogger.com/atom/ns#" term="samsung" /><category scheme="http://www.blogger.com/atom/ns#" term="test" /><category scheme="http://www.blogger.com/atom/ns#" term="recenzja" /><title>Zapowiedź testu: Samsung Galaxy S II i9100</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Tym razem nie nowa lekcja, a nowy flagowy model Samsunga działający pod kontrolą Androida - długo wyczekiwany Samsung Galaxy S II.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-tCpN1982-m4/Tbs7VLXqk0I/AAAAAAAACEM/oMQd7b0aLks/s1600/twogalaxy.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="275" src="http://4.bp.blogspot.com/-tCpN1982-m4/Tbs7VLXqk0I/AAAAAAAACEM/oMQd7b0aLks/s400/twogalaxy.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Tak się sympatycznie złożyło, że wpadł dzisiaj w moje łapki następca można już chyba śmiało powiedzieć kultowego Galaxy S i9000. W najbliższych dniach postaram się zamieścić małą recenzję tego sprzętu.&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Na tę chwilę mogę jedno powiedzieć - &lt;span class="Apple-style-span" style="color: red;"&gt;jest MOC&lt;/span&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;!&lt;/span&gt; Warto było czekać.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.helloandroid.pl/2011/05/recenzja-samsung-galaxy-s-ii-i9100.html"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Recenzja jest już dostępna!&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-7245523479224706786?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/etS7iFkBBHSH9vN15-t0_NinR-E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/etS7iFkBBHSH9vN15-t0_NinR-E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/etS7iFkBBHSH9vN15-t0_NinR-E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/etS7iFkBBHSH9vN15-t0_NinR-E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/ugg9C7yYSO0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/7245523479224706786/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2011/04/zapowiedz-testu-samsung-galaxy-s-ii.html#comment-form" title="Komentarze (5)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/7245523479224706786?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/7245523479224706786?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/ugg9C7yYSO0/zapowiedz-testu-samsung-galaxy-s-ii.html" title="Zapowiedź testu: Samsung Galaxy S II i9100" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-tCpN1982-m4/Tbs7VLXqk0I/AAAAAAAACEM/oMQd7b0aLks/s72-c/twogalaxy.jpg" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://www.helloandroid.pl/2011/04/zapowiedz-testu-samsung-galaxy-s-ii.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQMRHs4fip7ImA9WhZQE00.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-8172197114892835103</id><published>2011-04-20T12:32:00.003+02:00</published><updated>2011-04-20T15:33:05.536+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-20T15:33:05.536+02:00</app:edited><title>Lekcja 17. Wykresy w Androidzie</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;br /&gt;
&lt;b&gt;Wykres &lt;/b&gt;– graficzna forma przedstawienia zmienności zjawiska, procesu, wielkości, zależności lub jakichkolwiek danych.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-xx-ueUsq8xc/Ta6y5sSwcaI/AAAAAAAACCo/G5g6kQBW9qQ/s1600/wykresy_main.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="151" src="http://1.bp.blogspot.com/-xx-ueUsq8xc/Ta6y5sSwcaI/AAAAAAAACCo/G5g6kQBW9qQ/s320/wykresy_main.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Okazuje się, że pomimo tego, że wykresy są często spotykane w różnego rodzaju aplikacjach dostępnych w Android Market, nie łatwo jest znaleźć sensowne rozwiązanie w postaci biblioteki automatyzującej ich tworzenie.&lt;br /&gt;
Oczywiście można zacząć od pracy u podstaw i samemu opracować odpowiednią klasę opierając się na rysowaniu po Canvas'ie. Nie ma sensu jednak wymyślać koła. Wbrew pozorom wykres to nie tylko punkty na osi połączone linią. Dobry wykres musi być przede wszystkim czytelny graficznie, skalowalny, customizowalny, potrafiący przyjąć dane w różnych formatach i przede wszystkim wydajny. Czyli całkiem sporo pracy.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Wracając do tematu gotowych rozwiązań, to szczerze mówiąc nie znalazłem żadnego w pełni mnie satysfakcjonującego, notabene które to moim zdaniem powinno być zaimplementowane w samym Androidzie przez jego twórców. Mimo wszystko postanowiłem przybliżyć Wam rozwiązania które wydały mi się w miarę sensowne.&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* baner poziom bialy */
google_ad_slot = "2922899611";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Online/Offline&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Do Android-owych wykresów można podejść na dwa sposoby. Możemy próbować generować je w samym smartphonie, ale można pobierać je także przy pomocy widgetu WebView ze stron WWW z wygenerowanymi już wykresami. Szczerze mówiąc, póki co do własnych zastosowań zdecydowałem się na to ostatnie rozwiązanie. Jeżeli nie mamy, bądź nie chcemy stawiać serwera, instalować biblitek itp. w celu wystawienia WWW, możemy skorzystać z ciekawego rozwiązania jako oferuje nam... nie kto inny jak Google. Usluga &amp;nbsp;nazywa się Google Chart Tools, a można ją znaleźć pod adresem &lt;a href="http://code.google.com/apis/chart/"&gt;http://code.google.com/apis/chart/&lt;/a&gt;.&lt;br /&gt;
&lt;blockquote&gt;Wypróbuj!&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="color: #007000; font-family: monospace; font-size: 14px; line-height: 17px;"&gt;&lt;a href="https://chart.googleapis.com/chart?cht=p3&amp;amp;chd=t:60,40&amp;amp;chs=250x100&amp;amp;chl=Hello|World"&gt;https://chart.googleapis.com/chart?cht=p3&amp;amp;chd=t:60,40&amp;amp;chs=250x100&amp;amp;chl=Hello|World&lt;/a&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;img alt="Radar chart" src="https://chart.googleapis.com/chart?cht=rs&amp;amp;chs=200x200&amp;amp;chd=t:77,66,15,0,31,48,100,77|20,36,100,2,0,100&amp;amp;chco=FF0000,FF9900&amp;amp;chls=2.0,4.0,0.0|2.0,4.0,0.0&amp;amp;chxt=x&amp;amp;chxl=0:|0|45|90|135|180|225|270|315&amp;amp;chxr=0,0.0,360.0&amp;amp;chm=B,FF000080,0,1.0,5.0|B,FF990080,1,1.0,5.0" /&gt;&lt;/div&gt;&lt;br /&gt;
Google Chart Tools umożliwia dynamiczne generowanie przeróżnych typów wykresów za pomocą webgeneratora lub też poprzez przekazywanie parametrów metodą GET w adresie interenetowym. Wygenerowany wykres osadzony na stronie WWW może być zaprezentowany za pomocą komponentu WebView. Rozwiązanie to jest całkiem ciekawe. Czasami jednak nie chcielibysmy wysyłać naszych danych na zewnętrz, bądź też nie dysponujemy dostępem do Internetu. Dlatego w dalszej części artykułu przyjrzymy się rozwiązaniom offline. Przedstawione zostaną dwa: AndroidPlot, KiChart.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;AndroidPlot&lt;/b&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;a href="http://androidplot.com/wiki/Home"&gt;http://androidplot.com/wiki/Home&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
AndroidPlot jest biblioteką napisaną podobno w czystej Javie, umożliwiającą generowanie dynamicznych oraz statycznych wykresów. Póki co 4 typów: Line charts, Scatter charts, Bar charts, Step charts. Twórcy zapowiadają następne.&lt;br /&gt;
&lt;br /&gt;
Darmowość, społeczność skupiona wokół forum czy też fakt iż projekt jest cały czas rozwijany, &amp;nbsp;to według autorów główne "za" przemawiające za wyborem AndroidPlot. Jak jest w rzeczywistości? Nie najgorzej. Wykresy nie są brzydkie, ich cztery typy póki co są wystarczające, no i przy tym nieźle konfigurowalne. No i tu dochodzimy do piety achillesowej AndroidPlot'a. Wykresy są bardzo konfigurowalne, ale jest to według mnie tak skomplikowane, że mam wrażenie iż czasami sami twórcy nie wiedzą jak rozwiązać problemy forumowiczów zgromadzonych wokół projektu.&lt;br /&gt;
Jeżeli jednak przeskoczycie te trudności, okaże się, że AndroidPlot może być całkiem atrakcyjnym rozwiązaniem.&lt;br /&gt;
&lt;br /&gt;
W następnych kilku akapitach zaprezentowana została prosta aplikacja, wykorzystująca wykres liniowy dostępny w bibliotece AndroidPlot. Jest to zmodyfikowany przykład dostępny na stronach twórców projektu.&lt;br /&gt;
&lt;br /&gt;
MainActivity.class&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package helloandroid.pl;

import android.app.Activity;
import android.graphics.*;
import android.os.Bundle;
import com.androidplot.Plot;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.series.XYSeries;
import com.androidplot.xy.*;
import java.text.*;
import java.util.Arrays;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
      
      private XYPlot mySimpleXYPlot;
      
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        mySimpleXYPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
        Number[] numSightings = {5, 8, 9, 2, 5};
        Number[] years = {
                2001,  // 2001
                2002, // 2002
                2003, // 2003
                2004, // 2004
                2005  // 2005
        };
       
        //tworzymy serie
        XYSeries series2 = new SimpleXYSeries(
                Arrays.asList(years),
                Arrays.asList(numSightings),
                "helloandroid");
      
        //kolor tla siatki wykresu (czyli pole miedzy osia X a Y
        mySimpleXYPlot.getGraphWidget().getGridBackgroundPaint().setColor(Color.BLACK);
 
        //mozemy takze ustawic przezroczystosc na tym polu
        mySimpleXYPlot.getGraphWidget().getGridBackgroundPaint().setAlpha(0);
      
        //tlo wykresu i przelegajacych etykiet (opis osi)
        mySimpleXYPlot.getGraphWidget().getBackgroundPaint().setAlpha(0);
 
        //ustawiam przezroczystosc tla formy.
        //jest obszar poza wykresem i polami opisu osi
        mySimpleXYPlot.getBackgroundPaint().setAlpha(0);
       
        //kolor osi X
        mySimpleXYPlot.getGraphWidget().getDomainOriginLinePaint().setColor(Color.BLACK);
        //kolor osi Y
        mySimpleXYPlot.getGraphWidget().getRangeOriginLinePaint().setColor(Color.BLACK);
       
        //ustawiam polozenie legendy
        //mySimpleXYPlot.getLegendWidget().setSize(new SizeMetrics(-20, SizeLayoutType.ABSOLUTE, 160, SizeLayoutType.ABSOLUTE));
        //choc jednak decyduje sie aby ja usunac
        mySimpleXYPlot.getLayoutManager().remove(mySimpleXYPlot.getLegendWidget());
       
        //odsuniecie napisow od wykresu
        mySimpleXYPlot.getGraphWidget().setPadding(0, 0, 8, 0);
       
        //Margines od brzegow zewnetrznych
        mySimpleXYPlot.setPlotMargins(10, 10, 10, 10);
        mySimpleXYPlot.setPlotPadding(10, 10, 10, 10);
    
        //typ obramowanie calej formy
        mySimpleXYPlot.setBorderStyle(Plot.BorderStyle.SQUARE, null, null);
        //kolor powyzszej
        mySimpleXYPlot.getBorderPaint().setColor(Color.BLACK);

        //antyaliassing obramowania
        mySimpleXYPlot.getBorderPaint().setAntiAlias(true);
 
       
        // setup our line fill paint to be a slightly transparent gradient:
        Paint lineFill = new Paint();
        lineFill.setAlpha(200);
        lineFill.setShader(new LinearGradient(0, 0, 0, 250, Color.WHITE, Color.RED, Shader.TileMode.MIRROR));
 
        LineAndPointFormatter formatter  = new LineAndPointFormatter(Color.rgb(0, 0,0), Color.BLUE, Color.RED);
        formatter.setFillPaint(lineFill);

        //dodajemy nasza serie + format linii
        mySimpleXYPlot.addSeries(series2, formatter);
       
        //okresla skok/krok skali domeny, w tym przypadku nastepuje co rok
        mySimpleXYPlot.setDomainStep(XYStepMode.SUBDIVIDE, years.length);
 
        // opisy osi
        mySimpleXYPlot.setDomainLabel("Oś X");       
        mySimpleXYPlot.setRangeLabel("Oś Y");
     
        //precyzja zakresu, w tym przypadku - liczby calkowite       
        mySimpleXYPlot.setRangeValueFormat(new DecimalFormat("0"));
        mySimpleXYPlot.setDomainValueFormat(new DecimalFormat("0"));

        //wlacz a przekonasz sie ;)
        mySimpleXYPlot.disableAllMarkup();
    }
}

]]&gt;
&lt;/script&gt;&lt;br /&gt;
Jak widać, same modyfikatory wyglądu przytłaczają. Dodatkowo zawierają tyle warstw, że nie wiadomo, która za co odpowiada. Najlepiej rozpoznać je metoda prób i błędów. Starałem się dodać stosowne komentarze przy poszczególnych modyfikatorach. Jak wyszło. Nie mnie oceniać ;)&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Mały konkurs dla dociekliwych czytelników! - Jak odsunąć/przesunąć napis "oś X" od skali osi X. Nagroda do ustalenia. &lt;/blockquote&gt;&lt;br /&gt;
&lt;i&gt;main.xml&lt;/i&gt;&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;
&lt;com.androidplot.xy.XYPlot
    android:id="@+id/mySimpleXYPlot"
    android:layout_width="fill_parent"
    android:layout_height="280px"
    android:layout_marginTop="0px"
    android:layout_marginLeft="0px"
    android:layout_marginRight="0px"
    title="HelloAndroid.pl"/&gt;
&lt;/LinearLayout&gt;

]]&gt;
&lt;/script&gt;&lt;br /&gt;
Rezultat powinien prezentować się mniej więcej tak:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-TzJ6zvDBO-g/Ta6pBQM4l6I/AAAAAAAACCc/_tosFV_iXrw/s1600/androidPlot_1..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://4.bp.blogspot.com/-TzJ6zvDBO-g/Ta6pBQM4l6I/AAAAAAAACCc/_tosFV_iXrw/s400/androidPlot_1..png" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;KiChart&lt;/b&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;a href="http://www.kidroid.com/kichart/"&gt;http://www.kidroid.com/kichart/&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
KiChart jest kolejną ciekawą biblioteką. Ciekawą dla mnie z powodu prostoty jest jej użycia. Jednak póki co udostępniona jest jedynie wersja trial. Autor planuje wydanie odświeżonej wersji biblioteki, łącznie z dokumentacją,  przykładami użycia. Dlatego też polecam zaglądać na stronę KiDroida. Ewentualnie warto odezwać się do niego osobiście - na pewno nie zostawi w potrzebie.&lt;br /&gt;
&lt;br /&gt;
Przykład użycia biblioteki został przedstawiony na poniższym kodzie.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package helloandroid.pl;

import com.kidroid.kichart.ChartActivity;
import com.kidroid.kichart.model.Aitem;
import com.kidroid.kichart.view.ChartView;
import com.kidroid.kichart.view.LineView;
import android.graphics.Color;
import android.os.Bundle;

public class MainActivity extends ChartActivity {
    /** Called when the activity is first created. */
      LineView lv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        String xaxis[]=new String[4];

        xaxis[0]="2006";
        xaxis[1]="2007";
        xaxis[2]="2008";
        xaxis[3]="2009";

        float line1[]=new float[4];

        line1[0]=120;
        line1[1]=240;
        line1[2]=500;
        line1[3]=100;

        float line2[]=new float[4];

        line2[0]=100;
        line2[1]=650;
        line2[2]=700;
        line2[3]=300;

        float line3[]=new float[4];

        line3[0]=50;
        line3[1]=180;
        line3[2]=360;
        line3[3]=900;

        Aitem items[]=new Aitem[3];

        items[0]= new Aitem(Color.BLUE,"Linia 1",line1);
        items[1]= new Aitem(Color.GREEN,"Linia 2",line2);
        items[2]= new Aitem(Color.RED,"Linia 3",line3);

       
        lv=new LineView(this);
       
        lv.setTitle("Budżet");
        lv.setAxisValueX(xaxis);
        lv.setItems(items);
        lv.setBackgroudColor(Color.WHITE);
 
        setContentView(lv);

        }
}

]]&gt;
&lt;/script&gt;&lt;br /&gt;
Właściwości opisane zostały przez autora w krótkim przewodniku w formie pliku pdf &lt;a href="http://www.kidroid.com/uploads/kiChart/kiChart-Help.pdf"&gt;http://www.kidroid.com/uploads/kiChart/kiChart-Help.pdf&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Rezultat działania kodu:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-JoUox-rPjDU/Ta6pz6MtaDI/AAAAAAAACCg/mBKdDNw-F8c/s1600/kichart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://4.bp.blogspot.com/-JoUox-rPjDU/Ta6pz6MtaDI/AAAAAAAACCg/mBKdDNw-F8c/s400/kichart.png" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Podsumowanie&lt;/b&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* baner poziom bialy */
google_ad_slot = "2922899611";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;Wydaje się, że na chwilę pisania tego artykułu nie ma rozwiązań idealnych. Jeżeli nasze dane nie sa wrażliwe, a aplikacja będzie miała stały dostęp do Internetu, z pewnością warto zwrócić uwagę na rozwiązania online. Przemawia za nimi łatwość użycia, dodatkowo są zazwyczaj bardziej rozwinięte. W przeciwnym wypadku pozostają nam rozwiązania offline. Niestety zwykle ich głównym ograniczeniem jest początkowe stadium rozwoju - odnosi się to szczególnie do wersji darmowych, czyli takich o których była tu mowa. Jeśli jednak szukasz rozwiązania profesjonalnego, a koszty nie grają roli, to warto przyjrzeć się multiplatformowej bibliotece aiCharts, &lt;a href="http://www.artfulbits.com/products/android/aiCharts.aspx"&gt;http://www.artfulbits.com/products/android/aiCharts.aspx&lt;/a&gt;. Niestety koszt developerskiej licencji wynosi $299, co może skutecznie wystudzić pragnienie posiadania wykresów wyglądających jak na poniższych screenie.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-kHnGFqCzcb4/Ta6qDZvwteI/AAAAAAAACCk/2J6JIf6dWUI/s1600/aicharts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://4.bp.blogspot.com/-kHnGFqCzcb4/Ta6qDZvwteI/AAAAAAAACCk/2J6JIf6dWUI/s400/aicharts.png" width="223" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-8172197114892835103?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DpK9tgVPUgZX5aHViZ6NCAhvucA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DpK9tgVPUgZX5aHViZ6NCAhvucA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DpK9tgVPUgZX5aHViZ6NCAhvucA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DpK9tgVPUgZX5aHViZ6NCAhvucA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/6t0VO9M7CoY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/8172197114892835103/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2011/04/lekcja-17-wykresy-w-androidzie.html#comment-form" title="Komentarze (7)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/8172197114892835103?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/8172197114892835103?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/6t0VO9M7CoY/lekcja-17-wykresy-w-androidzie.html" title="Lekcja 17. Wykresy w Androidzie" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-xx-ueUsq8xc/Ta6y5sSwcaI/AAAAAAAACCo/G5g6kQBW9qQ/s72-c/wykresy_main.jpg" height="72" width="72" /><thr:total>7</thr:total><feedburner:origLink>http://www.helloandroid.pl/2011/04/lekcja-17-wykresy-w-androidzie.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMESHs-eip7ImA9WhZQEkk.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-3975475395204958079</id><published>2011-04-13T17:39:00.003+02:00</published><updated>2011-04-19T21:46:49.552+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-19T21:46:49.552+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SSH" /><category scheme="http://www.blogger.com/atom/ns#" term="tunel" /><category scheme="http://www.blogger.com/atom/ns#" term="ganymed" /><title>Lekcja 16. Połączenie SSH</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/-4KUQCZt6Qgs/TaXBdwPLyQI/AAAAAAAACB8/AnV8MvY_WSs/s1600/android_ssh.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="111" src="http://2.bp.blogspot.com/-4KUQCZt6Qgs/TaXBdwPLyQI/AAAAAAAACB8/AnV8MvY_WSs/s200/android_ssh.jpg" width="200" /&gt;&lt;/a&gt;Tym razem dosyć krótka i uboga w treść lekcja. Postaram się przedstawić na przykładzie prostej klasy możliwość zastosowania zewnętrznej biblioteki Ganymed SSH2 w celu stworzenia połączenia SSH. Podejrzewam, że to trochę niszowe zastosowanie, dlatego też będzie więcej samego kodu niż opisów. Mam nadzieję, że osoby zainteresowane nie będą mieć problemu z interpretacją poniższego przykładu. Zresztą nie jest to żaden "rocket science".&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;Ganymed SSH2&lt;br /&gt;
&lt;/b&gt;&lt;a href="http://www.ganymed.ethz.ch/ssh2/"&gt;http://www.ganymed.ethz.ch/ssh2/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Dla swoich potrzeb postanowiłem wykorzystać popularną bibliotekę Ganymed SSH2 napisaną w czystej Javie, implementującą protokół SSH2, a umożliwiającą między innymi zdalne wykonywanie komend oraz dostęp do shell'a, czyli akurat to czego szukałem.&lt;br /&gt;
&lt;br /&gt;
Aby już nie przedłużać, przedstawiam kod. &lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* baner poziom bialy */
google_ad_slot = "2922899611";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;i&gt;SSHConnection.class&lt;/i&gt;&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package helloandroid.pl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.util.Log;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;

public class SSHConnection {

      public static Connection conn;
      public static boolean connectionStatus = false;
      private static final String TAG = "HelloAndroid";

      
       // Tworzy polaczenie &amp; autentykacja
       
      public static void ConnectSSH(String hostname, String username,
                  String password) {

            //Obiekt klasy Connection pochodzacej z biblioteki Ganymed SSH2
            conn = new Connection(hostname);

            try {
                  //Tworzymy polaczenie
                  conn.connect();

                  //Autentykacja na podstawie loginu i hasla
                  boolean isAuthenticated = conn.authenticateWithPassword(username,
                              password);

                  //Jezeli autentykacja sie nie powiodla - zwracamy Exception
                  if (isAuthenticated == false)
                        throw new IOException();
                  //Jezeli sie powiodla zmieniany status polaczenia na true
                  if (isAuthenticated == true)
                        setConnectionStatus(true);

            } catch (IOException e) {
                  Log.v(TAG, "Authentication failed!");
                  setConnectionStatus(false);
            }
      }

      
       // Zamyka polaczenie
       
      public static void DisconnectSSH() {      
            // Jezeli jest polaczony - zamknij polaczenie
            if (isConnectionStatus() == true) {
                  conn.close();
                  setConnectionStatus(false);
            }
      }

      
       // Zwraca status polaczenia
       
      public static boolean isConnectionStatus() {
            return connectionStatus;
      }
      
      
       // Ustawienie statusy polaczenia
       
      public static void setConnectionStatus(boolean connectionStatus) {
            SSHConnection.connectionStatus = connectionStatus;
      }

      
       // Wysylanie komendy z oczekiwaniem na odpowiedz
       
      public static String SendCommandSSH(String command) {

            String output = "";

            if (isConnectionStatus() == true) {
                  try {
                        //Jezeli mamy aktywne polaczenie, otwieramy sesje SSH
                        Session sess = conn.openSession();
                        //Wysylamy komende
                        sess.execCommand(command);
                        
                        InputStream stdOut = sess.getStdout();

                        BufferedReader r = new BufferedReader(new InputStreamReader(
                                    stdOut));
                        
                        StringBuilder total = new StringBuilder();
                        String line;
                        
                        while ((line = r.readLine()) != null) {
                              total.append(line);
                        }

                        sess.close();
                        output = total.toString();

                  } catch (IOException e) {
                        e.printStackTrace();
                  }
            }
            return output;
      }

      
       // Wyslalanie komendy bez oczekiwania na odpowiedz
       
      public static void SendCommandSSHwithoutAnswer(String command) {
            if (isConnectionStatus() == true) {
                  try {
                        Session sess = conn.openSession();
                        sess.execCommand(command);
                        sess.close();
                  } catch (IOException e) {
                        e.printStackTrace();
                  }

            }
      }
}

]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;MainActivity.class&lt;/i&gt;&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package helloandroid.pl;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        String output;
       
        if(!SSHConnection.isConnectionStatus()){
            SSHConnection.ConnectSSH("192.168.0.1", "root","password");
            SSHConnection.setConnectionStatus(true);
            
            output = SSHConnection.SendCommandSSH("pwd");
            System.out.println(output);
            
            SSHConnection.DisconnectSSH();
        }
    }
}

]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Z obowiązku wspomnę, abyście nie zapomnieli &lt;s&gt;zadeklarować klasy SSHConnection w manifeście aplikacji &lt;/s&gt;oraz pamiętali aby dodać biblioteki Ganymed do "build path" projektu.&lt;br /&gt;
&lt;br /&gt;
Nie udostępniam projektu w formie paczki bo kodu jest niewiele, a druga sprawa to to, że potrzebny jest dostęp do jakiegoś serwera umożliwiającego połączenie SSH. Dlatego też tym razem lekcja bardziej teoretyczna.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-3975475395204958079?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/x-g2cOmJxpol0M-I2UBZquO-EDQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x-g2cOmJxpol0M-I2UBZquO-EDQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/x-g2cOmJxpol0M-I2UBZquO-EDQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x-g2cOmJxpol0M-I2UBZquO-EDQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/B_QSwPCvNy8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/3975475395204958079/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2011/04/lekcja-16-poaczenie-ssh.html#comment-form" title="Komentarze (3)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3975475395204958079?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3975475395204958079?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/B_QSwPCvNy8/lekcja-16-poaczenie-ssh.html" title="Lekcja 16. Połączenie SSH" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-4KUQCZt6Qgs/TaXBdwPLyQI/AAAAAAAACB8/AnV8MvY_WSs/s72-c/android_ssh.jpg" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.helloandroid.pl/2011/04/lekcja-16-poaczenie-ssh.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YFQn47eip7ImA9WhZRF00.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-3124752833445739694</id><published>2011-04-09T21:24:00.003+02:00</published><updated>2011-04-13T17:38:33.002+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-13T17:38:33.002+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="doInBackground" /><category scheme="http://www.blogger.com/atom/ns#" term="Thread" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="handler" /><category scheme="http://www.blogger.com/atom/ns#" term="AsyncTask" /><title>Lekcja 15. AsyncTask - Zarządzanie wątkami w Androidzie</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;Android na swoje szczęście lub też nieszczęście dostarcza model pojedynczego wątku, który tworzony jest podczas uruchomienia aplikacji. Jest to tzw. &lt;b&gt;UI Thread&lt;/b&gt;, czyli wątek główny.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-hwipK4y87d0/TaCwv5z9aMI/AAAAAAAACBc/8D5IwcebUd4/s1600/319323720_440.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="167" src="http://3.bp.blogspot.com/-hwipK4y87d0/TaCwv5z9aMI/AAAAAAAACBc/8D5IwcebUd4/s400/319323720_440.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Oznacza to nie mniej nie więcej, że wszelkie procesy (czynności), które wykonywane są w naszej aplikacji realizowane są liniowo. I tak na przykład, gdy chcielibyśmy w naszej potencjalnej aplikacji połączyć się z serwerem bazodanowym i wykonać na nim szereg czasochłonnych operacji, to w czasie tego procesu, „wątek” obsługujący interfejs zostałby zawieszony w oczekiwaniu na zakończenie tej operacji. Brak reakcji interfejsu odbierany jest przez użytkowników jako „wolne działanie” lub co gorsza „wieszanie się”. Dodatkowo jeśli aplikacja nie odpowiada przez co najmniej 5 sekund, Android wyrzuca błąd o braku odpowiedzi (parafrazując słowa wróżbity Macieja: Myślę, że wiecie o czym mówię... ;)) &lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Na szczęście Google, a dokładnie twórcy Androida pomyśleli i dostarczyli nam mechanizm wątków (&lt;b&gt;Threads&lt;/b&gt;) dobrze znanych z innych języków.&lt;/div&gt;&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
public void onClick(View v) {
    Thread t = new Thread(){
    public void run(){
 // Długo wykonującą się operacja 
   }
   };
   t.start();
}
]]&gt;
&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;
Problem pojawia się w momencie gdy chcielibyśmy aby nasz nowy wątek dokonał modyfikacji w wątku interfejsu. Jednym z kilku możliwych rozwiązań jest użycie popularnych &lt;b&gt;Handlerów&lt;/b&gt;, nie o nich jednak będzie dzisiejsza lekcja. W zamian będzie coś o wiele lepszego.&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black */
google_ad_slot = "3801483932";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;AsyncTask&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Użycie handlerów uzasadnione jest w przypadku prostych aplikacji, wykorzystujących nie wielką liczbę wątków, nad którymi jesteśmy w stanie łatwo zapanować. Jednak gdy aplikacja korzysta z większej liczby wątków i to w dodatku czasochłonnych przychodzi nam z pomocą mechanizm do zarządzania wątkami zaimplementowany w klasie &lt;b&gt;AsyncTask&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Przykładowa klasa wykorzystująca możliwości AsyncTask zaprezentowana została poniżej.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
private class WymagajacyWatek extends AsyncTask&lt;String, Void, String&gt; {

 @Override
 protected String doInBackground(String... params) {
  // Tutaj jest miejsce na logike naszego wątku z długo trwającymi operacjami
  return null;
 }

 @Override
 protected void onPostExecute(String result) {
  // Tutaj mozesz zaimplenentowac czynności, które powinny zostać zrealizowane po zakoczeniu operacji
 }

 @Override
 protected void onPreExecute() {
  // Analogicznie do metody onPostExecute, implenentujesz czynnosci do zrealizowania przed uruchomieniem wątku
 }

 @Override
 protected void onProgressUpdate(Void... values) {
  // Natomiast metoda onProgressUpdate umozliwia aktualizwanie watku głównej podczas działana naszego WymagającegoWatku
  }
}

public void onClick(View v) {
 new WymagajacyWatek().execute("");
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Klasa korzystająca z AsyncTask powinna definiować:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;Trzy typy generyczne&lt;/b&gt;: Params, Progress, Result, odpowiadające paremetrom wejściowym, stopniu postępu, a także wynikowi przeprowadzonych operacji przez wątek&lt;/li&gt;
&lt;/ul&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;Cztery metody&lt;/b&gt; odpowiadające poszczególnym etapom działania wątku:&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;doInBackground &lt;/b&gt;– jedyna z obowiązkowych metod. W przypadku istnienia metody onPreExecute wykonywana jest zaraz po niej. To do tej metody przekazywane są parametry wejściowe, a także tutaj przeprowadzane są główne operacje. Za pomocą metody publishProgress(Progress...) możliwe jest przekazywanie postępów działania wątku. Każdorazowe wywołanie publishProgress powoduje wykonanie metody onProgressUpdate, dzięki której możliwe jest prezentowanie postępu w wątku głównym UI.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;onPreExecute &lt;/b&gt;– wywoływana przed doInBackground. Służy głównie do ustawienia parametrów początkowych np. wyzerowaniu widgetu progressbar, czy też zablokowania przycisku, itp.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;onProgressUpdate &lt;/b&gt;– służy do przekazywania parametrów postępu do wątku UI. Wywoływana przez przeciążenie metody publishProgress() w metodzie doInBackground()&lt;/li&gt;
&lt;li&gt;&lt;b&gt;onPostExecute &lt;/b&gt;– wywoływana po zakończeniu działań metody doInBackground. Jako parametr jest do niej przekazywany rezultat działania wątku.&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;AsyncTaskApp&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Poniżej zamieszczam kod oraz &lt;b&gt;&lt;span class="Apple-style-span" style="color: orange;"&gt;&lt;a href="http://www.przeklej.pl/plik/helloandroidasynctask-zip-00294u5756u43sp"&gt;źródło&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;przykładowej aplikacji wykorzystującej AsyncTask. Jedynym zadaniem wątku jest uaktualnianie progressbar'a.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;MainActivity.class&lt;/i&gt;&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package helloandroid.pl;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;

/*
 * HelloAndroid.pl
 */

public class MainActivity extends Activity {
 
 final private int START_PROGRESS = 0;
 final private int STOP_PROGRESS = 100;
 
 private Button button;
 private ProgressBar progressBar;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        progressBar = (ProgressBar)findViewById(R.id.progressbar_Horizontal);
        
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    new WymagajacyWatek().execute("");
  }});  
    }
    
    
    private class WymagajacyWatek extends AsyncTask&lt;String, Integer, String&gt;{

  @Override
  protected String doInBackground(String... arg0) {
   // TODO Auto-generated method stub
   int i;
   int a;
   
   for(i = 0; i &lt; 100; i++){
    publishProgress(i);
    
    a = 0;
    while(a&lt;1500){
     a++;
    }
   }
   
   return null;
  } 
  
 
  @Override
  protected void onPostExecute(String result) {
   setProgressBar(STOP_PROGRESS);
   button.setEnabled(true);
  }
 
  @Override
  protected void onPreExecute() {
   //"wyzerujemy" progress bar
   setProgressBar(START_PROGRESS);  
   //zablokujmy przycisk na czas dzialania watku
   button.setEnabled(false);
  }
 
  @Override
  protected void onProgressUpdate(Integer... progress) {
   setProgressBar(progress[0]);
  }
    }
    
    private void setProgressBar(int progress){
     progressBar.setProgress(progress);
    }
}


]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;main.xml&lt;/i&gt;&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;
&lt;Button
 android:id="@+id/button"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:layout_marginTop="5px"
 android:text="Uruchom"&gt;
&lt;/Button&gt;
&lt;ProgressBar
 android:id="@+id/progressbar_Horizontal"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    style="?android:attr/progressBarStyleHorizontal"
    android:max="100"/&gt;
&lt;textview  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    /&gt;
&lt;/LinearLayout&gt;

]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
A tak powinna wyglądać aplikacja po skompilowaniu i uruchomieniu.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-YD2Bdfsi_fM/TaCrFwRtvMI/AAAAAAAACBU/_zNta2sBVPM/s1600/asynctask_emu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="283" src="http://3.bp.blogspot.com/-YD2Bdfsi_fM/TaCrFwRtvMI/AAAAAAAACBU/_zNta2sBVPM/s400/asynctask_emu.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-3124752833445739694?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/o4oGyQTpK3ajwKoAj3HZx2fGKLc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/o4oGyQTpK3ajwKoAj3HZx2fGKLc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/o4oGyQTpK3ajwKoAj3HZx2fGKLc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/o4oGyQTpK3ajwKoAj3HZx2fGKLc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/TprbeJZyv58" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/3124752833445739694/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2011/04/lekcja-15-asynctask-zarzadzanie-watkami.html#comment-form" title="Komentarze (2)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3124752833445739694?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3124752833445739694?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/TprbeJZyv58/lekcja-15-asynctask-zarzadzanie-watkami.html" title="Lekcja 15. AsyncTask - Zarządzanie wątkami w Androidzie" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-hwipK4y87d0/TaCwv5z9aMI/AAAAAAAACBc/8D5IwcebUd4/s72-c/319323720_440.jpg" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://www.helloandroid.pl/2011/04/lekcja-15-asynctask-zarzadzanie-watkami.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8FQHc4fyp7ImA9WhZQEkk.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-4929245927218077076</id><published>2011-04-03T18:40:00.011+02:00</published><updated>2011-04-19T21:53:31.937+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-19T21:53:31.937+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="instalacja" /><category scheme="http://www.blogger.com/atom/ns#" term="początki" /><category scheme="http://www.blogger.com/atom/ns#" term="sdk" /><category scheme="http://www.blogger.com/atom/ns#" term="konfiguracja" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><title>Lekcja 14. Przygotowanie środowiska cz.2 - Eclipse</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-QwP4qGs8DJg/TZihll3lU5I/AAAAAAAACBI/ovInk6J5lmk/s1600/android.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://4.bp.blogspot.com/-QwP4qGs8DJg/TZihll3lU5I/AAAAAAAACBI/ovInk6J5lmk/s200/android.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;Jako, że od pierwszej instrukcji instalacji oraz konfiguracji środowiska do programowania pod Androida już trochę bajtów w światłowodach&amp;nbsp;upłynęło&amp;nbsp;&amp;nbsp;- postanowiłem temat&amp;nbsp;odświeżyć.&lt;br /&gt;
&lt;br /&gt;
Wiele się zmieniło, linki do źródeł się zdezaktualizowały, Android doczekał się wersji SDK o numerze 2.3.3 (pomijam tu świadomie wersje "tabletową" 3.0), a Elicpse wydaję się, że&amp;nbsp;objął&amp;nbsp;prym jako platforma IDE w świeci programistów Androida.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;1.) Instalacja Eclipse'a&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.eclipse.org/downloads/"&gt;http://www.eclipse.org/downloads/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Ściągamy wersję zaznaczoną na screenie czerwoną ramką.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-RkUT7S5pHmY/TZiSJtWhH4I/AAAAAAAACAo/DaEUmkyWg8s/s1600/eclipse.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="211" src="http://4.bp.blogspot.com/-RkUT7S5pHmY/TZiSJtWhH4I/AAAAAAAACAo/DaEUmkyWg8s/s400/eclipse.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Ściągniętą paczkę .zip rozpakowujemy, a następnie umieszczamy rozpakowany katalog w dogodnym dla nas miejscu. Instalacja Eclipse'a jest już zakończona.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2.) Instalacja JDK (Java Development Kit)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html"&gt;http://www.oracle.com/technetwork/java/javase/downloads/index.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Ściągamy wersję zaznaczoną na screenie czerwoną ramką.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-T3buJiUMuDc/TZiVAsSu4tI/AAAAAAAACAw/4qp8q3Ak2Lo/s1600/jdk.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="237" src="http://2.bp.blogspot.com/-T3buJiUMuDc/TZiVAsSu4tI/AAAAAAAACAw/4qp8q3Ak2Lo/s400/jdk.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Uruchamiamy instalator i postępujemy według instrukcji.&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black */
google_ad_slot = "3801483932";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;3.) Instalacja Android SDK&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://developer.android.com/sdk/index.html"&gt;http://developer.android.com/sdk/index.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Ściągamy wersję zaznaczoną na screenie czerwoną ramką.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-1lNKcpzTb8s/TZiTkGpi2AI/AAAAAAAACAs/PpGQ3TrUO_I/s1600/sdk.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="166" src="http://1.bp.blogspot.com/-1lNKcpzTb8s/TZiTkGpi2AI/AAAAAAAACAs/PpGQ3TrUO_I/s400/sdk.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Przystępujemy do instalacji SDK. Na samym początku możecie się natknąć na problem z przejściem do drugiego czy też trzeciego etapu instalacji. Instalator będzie&amp;nbsp;twierdził, że komputera nie ma zainstalowanej odpowiedniej wersji JDK. W tym momencie mały trick. &lt;b&gt;Należy kliknąć przycisk BACK&amp;nbsp;po czym ponownie NEXT&lt;/b&gt;, tym razem instalator powinien nas puścić do przodu... Dlaczego wystęuje taki problem ? Pytanie do wujka Googla.&lt;br /&gt;
&lt;br /&gt;
W przypadku gdy powyższy problem Was nie dotyczy, albo też udało się przy pomocy powyższego tricku przejść dalej, dochodzimy do ekranu wyboru wersji SDK do instalacji. Moja sugestia, to odznaczyć wersję wcześniejsze niż 2.1 - pożytku raczej z nich już nie będzie, a oszczędzić na dysku miejsce można.&lt;br /&gt;
&lt;br /&gt;
W tym momencie instalator zaczyna pobierać zaznaczone wersje SDK. Chwilę to potrwa. Także trochę cierpliwości.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-4dIli2poewY/TZiX9JFlFRI/AAAAAAAACA0/VwYlqGhtYX4/s1600/sdk-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="231" src="http://3.bp.blogspot.com/-4dIli2poewY/TZiX9JFlFRI/AAAAAAAACA0/VwYlqGhtYX4/s400/sdk-2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4.) Konfigurowanie Eclipse'a&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;a) Instalacja pluginu ADT &lt;/b&gt;- rozszerzającego możliwości Eclipse'a o możliwość budowy aplikacji Android.&lt;br /&gt;
&lt;br /&gt;
Udajemy się na stronę...&lt;br /&gt;
&lt;a href="http://developer.android.com/sdk/eclipse-adt.html"&gt;http://developer.android.com/sdk/eclipse-adt.html&lt;/a&gt;,&lt;br /&gt;
gdzie znajdziemy linko do plugin'u:&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;&lt;b&gt;https://dl-ssl.google.com/android/eclipse/ &lt;/b&gt;- kopiujemy link do schowka.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;Następnie z górnego paska aplikacji wybieramy opcję &lt;b&gt;Help &lt;/b&gt;-&amp;gt;&lt;b&gt; Install New Software...&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;Klikamy przycisk &lt;b&gt;Add &lt;/b&gt;i w okienko, które się pojawiło wklejamy nasz wcześniej zapamiętany adres.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-wcchlCkw51s/TZicm45mlbI/AAAAAAAACA4/H0Y-BezcF4M/s1600/plugin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="361" src="http://1.bp.blogspot.com/-wcchlCkw51s/TZicm45mlbI/AAAAAAAACA4/H0Y-BezcF4M/s400/plugin.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;Zaznaczamy checkbox przy Developer Tools...&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-cEeZ2aLgWN8/TZic6nIkjeI/AAAAAAAACA8/p2O_0YB6KZE/s1600/plugin2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="361" src="http://1.bp.blogspot.com/-cEeZ2aLgWN8/TZic6nIkjeI/AAAAAAAACA8/p2O_0YB6KZE/s400/plugin2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;Dalej postępujemy według instrukcji.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black */
google_ad_slot = "3801483932";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;&lt;b&gt;b)&lt;/b&gt; &lt;b&gt;Dodanie SDK Android do Eclipse'a&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;Ostatnio rzeczą jaką musimy zrobić jest wskazanie Eclipse'owi lokalizacji naszych wcześniej zainstalowanych SDK.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;W tym celu wchodzimy w menu &lt;b&gt;Window &lt;/b&gt;- &amp;gt; &lt;b&gt;Preferences &lt;/b&gt;i konfigurujemy ustawienia w poniższy sposób.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-LczmHJL1Iy8/TZiewBRhgdI/AAAAAAAACBA/7rntBJviwZ0/s1600/pref.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="346" src="http://2.bp.blogspot.com/-LczmHJL1Iy8/TZiewBRhgdI/AAAAAAAACBA/7rntBJviwZ0/s400/pref.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;I już. Środowisko zainstalowane i&amp;nbsp;skonfigurowane.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;*5.) &amp;nbsp;Już na prawdę ostatnim krokiem, a właściwie o podpowiedzią co do dalszych działań, jest utworzenie maszyny wirtualnej - emulatora Androida.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;W tym celu wybieramy z menu &lt;b&gt;Window &lt;/b&gt;- &amp;gt; &lt;b&gt;Android SDK and AVD Manager.&lt;/b&gt;&amp;nbsp;Klikamy &lt;b&gt;New&lt;/b&gt;. Uzupełniamy okienko.&lt;/div&gt;&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-rS8mR_x9YGo/TZigeA_r5VI/AAAAAAAACBE/qDQypHfn2mo/s1600/avd.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://4.bp.blogspot.com/-rS8mR_x9YGo/TZigeA_r5VI/AAAAAAAACBE/qDQypHfn2mo/s400/avd.png" width="265" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Teraz już naprawdę mamy przygotowane środowisko do pracy ;)&lt;/div&gt;&lt;span class="Apple-style-span" style="line-height: 16px; white-space: pre;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-4929245927218077076?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/fX_logzDG-VCr9xKXMbtwe6zZTQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fX_logzDG-VCr9xKXMbtwe6zZTQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/fX_logzDG-VCr9xKXMbtwe6zZTQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fX_logzDG-VCr9xKXMbtwe6zZTQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/7mbrEGkXtJc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/4929245927218077076/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2011/04/przygotowanie-srodowiska-cz2-eclipse.html#comment-form" title="Komentarze (13)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/4929245927218077076?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/4929245927218077076?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/7mbrEGkXtJc/przygotowanie-srodowiska-cz2-eclipse.html" title="Lekcja 14. Przygotowanie środowiska cz.2 - Eclipse" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-QwP4qGs8DJg/TZihll3lU5I/AAAAAAAACBI/ovInk6J5lmk/s72-c/android.jpg" height="72" width="72" /><thr:total>13</thr:total><feedburner:origLink>http://www.helloandroid.pl/2011/04/przygotowanie-srodowiska-cz2-eclipse.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEAQHg4fCp7ImA9WxFQEkk.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-2556557042574649552</id><published>2010-05-07T10:07:00.002+02:00</published><updated>2010-05-07T17:37:21.634+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-07T17:37:21.634+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Społeczność" /><category scheme="http://www.blogger.com/atom/ns#" term="Petycja" /><category scheme="http://www.blogger.com/atom/ns#" term="Market" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><title>We want Android Market!</title><content type="html">Nowa notka po dłuższej nieobecności. Do tego notka interwencyjna. &lt;br /&gt;
&lt;a href="http://3.bp.blogspot.com/_KGPcYjtmXgo/S-QzeYrfj-I/AAAAAAAAA0c/HnO0hdOuzH4/s1600/android_market_2.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://3.bp.blogspot.com/_KGPcYjtmXgo/S-QzeYrfj-I/AAAAAAAAA0c/HnO0hdOuzH4/s200/android_market_2.png" width="133" /&gt;&lt;/a&gt;&lt;br /&gt;
W skrócie. Koledzy z forum &lt;a href="http://android.com.pl/"&gt;android.com.pl&lt;/a&gt; zainicjowali akcję mającą na celu przekonanie Googla do otwarcia polskiej wersji Android Market na płatne aplikacje. Dotyczy to zarówno zakupu jak i możliwości ich udostępniania przez developerów.&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcesz się przyłączyć do akcji, krzyknąć w ethernetowy eter - "hej! Wójku Googlu, dlaczego nas dyskryminujesz?", to nic prostszego jak udać się na stronę &lt;span style="font-size: large;"&gt;&lt;a href="http://www.petycje.pl/5210"&gt;http://www.petycje.pl/5210&lt;/a&gt;&lt;/span&gt; i spełnić swój droidowy obowiązek.&lt;br /&gt;
&lt;br /&gt;
Postępy w sprawie możesz bacznie obserwować na stronie - &lt;a href="http://we-want-android-market.blogspot.com/"&gt;http://we-want-android-market.blogspot.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-2556557042574649552?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YuTeBuem7nU_gGPoQLzyiUjvqnI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YuTeBuem7nU_gGPoQLzyiUjvqnI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YuTeBuem7nU_gGPoQLzyiUjvqnI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YuTeBuem7nU_gGPoQLzyiUjvqnI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/zaMmWjQLRFg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/2556557042574649552/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2010/05/we-want-android-market.html#comment-form" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2556557042574649552?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2556557042574649552?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/zaMmWjQLRFg/we-want-android-market.html" title="We want Android Market!" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_KGPcYjtmXgo/S-QzeYrfj-I/AAAAAAAAA0c/HnO0hdOuzH4/s72-c/android_market_2.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.helloandroid.pl/2010/05/we-want-android-market.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EEQXY-eip7ImA9WhZQEU0.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-9164599864552080909</id><published>2010-02-15T21:58:00.005+01:00</published><updated>2011-04-18T08:53:20.852+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-18T08:53:20.852+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AdMob" /><title>Lekcja 13. Instalujemy reklamy sieci AdMob.</title><content type="html">&lt;a href="http://4.bp.blogspot.com/_KGPcYjtmXgo/S3m8rJ-UBDI/AAAAAAAAAtI/VWi4c-gk6ls/s1600-h/hero_admob.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="151" src="http://4.bp.blogspot.com/_KGPcYjtmXgo/S3m8rJ-UBDI/AAAAAAAAAtI/VWi4c-gk6ls/s200/hero_admob.JPG" width="200" /&gt;&lt;/a&gt;O sieci reklamy mobilnej AdMob zrobiło się ostatnio głośno w związku z przejęciem jej przez naszego 'ukochanego'&amp;nbsp;wujka&amp;nbsp;Google.&lt;br /&gt;
&lt;br /&gt;
Pomijając aspekt czysto biznesowy umieszczania tego typu reklam na ekranach potencjalnych odbiorców Waszych aplikacji, chciałbym w kilku akapitach przedstawić proces instalacji oraz konfiguracji AdMoba dla przykładowej&amp;nbsp;aplikacji.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black1 */
google_ad_slot = "5985861762";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Krok 1&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
Przygodę z reklamą AdMob zaczniemy od rejestracji na stronie&amp;nbsp;&lt;a href="http://www.admob.com/"&gt;http://www.admob.com/&lt;/a&gt;. Po&amp;nbsp;ukończeniu&amp;nbsp;której, klikając na przycisk 'Add Site/App' przejdziemy krótki formularz, wybierając między innymi interesującą nas platformę reklamową (w naszym przypadku oczywiście Android), nazwę aplikacji, określimy także kategorię do jakiej owa należy itp.&lt;br /&gt;
&lt;br /&gt;
Po&amp;nbsp;udzieleniu wszystkich&amp;nbsp;satysfakcjonujących&amp;nbsp;formularz&amp;nbsp;odpowiedzi, serwis udostępni nam do pobrania &lt;i&gt;AdMob Android SDK -&amp;nbsp;&lt;/i&gt;niezbędne do utworzenia reklamy, a także przykład w postaci lekko zmodyfikowanej aplikacji&amp;nbsp;LunarLander (w postaci podstawowej dostępnej na stronie&amp;nbsp;&lt;a href="http://developer.android.com/"&gt;http://developer.android.com&lt;/a&gt;). Nie zabraknie także w pobranym archiwum dokładnego tutoriala oraz dokumentacji biblioteki AdMob'a. Najważniejszą jednak zdobyczą jest tzw. &lt;i&gt;publisher ID, &lt;/i&gt;czyli identyfikator naszych reklam.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Krok 2&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Krok drugi zaczniemy od utworzenia w katalogu głównym naszej aplikacji - katalogu &lt;b&gt;libs &lt;/b&gt;(tak aby znajdował się obok katalogów src, res, bin... itd.), a następnie umieszczenia w nim pliku Jar (admob-sdk-android), znajdującego się w paczce zip ściągniętej z AdMob'a.&lt;br /&gt;
&lt;br /&gt;
Pozostaje nam dodać naszą nową bibliotekę do naszego projektu.&lt;br /&gt;
W tym celu wykonajmy poniższe kroki (opis dla Eclipse).&lt;br /&gt;
1.) Klikając prawym przyciskiem na korzeniu naszego projektu, wybieramy &lt;i&gt;Properties.&lt;/i&gt;&lt;br /&gt;
2.) Z lewego panelu wybieramy &lt;i&gt;Java Build Path.&lt;/i&gt;&lt;br /&gt;
3.) Następnie z prawego panelu wybieramy zakładkę &lt;i&gt;Libraries&lt;/i&gt;.&lt;br /&gt;
4.) Klikamy na przycisk &lt;i&gt;Add JARs...&lt;/i&gt;, poczym wskazujemy naszą bibliotekę w katalogu&lt;i&gt; libs&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Po jej dodaniu&amp;nbsp;powinniśmy&amp;nbsp;uzyskać mniej więcej taki stan:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_KGPcYjtmXgo/S3moHZeSZKI/AAAAAAAAAso/PCPSMVlvHUw/s1600-h/admob_build.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="172" src="http://3.bp.blogspot.com/_KGPcYjtmXgo/S3moHZeSZKI/AAAAAAAAAso/PCPSMVlvHUw/s400/admob_build.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Krok 3&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Uzupełniamy manifest aplikacji.&lt;br /&gt;
Dodajemy linijkę z naszym &lt;i&gt;publisher ID&lt;/i&gt;, otrzymanym po dodaniu aplikacji w serwisie.&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[

     &lt;!-- The application's publisher ID assigned by AdMob --&gt;
     &lt;meta-data android:value="YOUR_ID_HERE" android:name="ADMOB_PUBLISHER_ID" /&gt;
&lt;/application&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Następnie zezwalamy aplikacji na korzystanie z połączenia internetowego (Wifi,GSM).&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
 &lt;!-- AdMob SDK permissions --&gt;
                &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
        &lt;/manifest&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Krok 4&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Kolejnym krokiem jest stworzenie pliku zawierającego atrybuty określające naszą reklamę (&lt;i&gt;AdView&lt;/i&gt;). W tym celu przechodzimy do pliku&lt;i&gt; /res/values/attrs.xml&lt;/i&gt;, a w przypadku gdy go jeszcze nie posiadamy - tworzymy go. Wypełniamy go według poniższego wzoru:&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
  &lt;?xml version="1.0" encoding="utf-8"?&gt;
        &lt;resources&gt;
                &lt;declare-styleable name="com.admob.android.ads.AdView"&gt;
                        &lt;attr name="testing" format="boolean" /&gt;
                        &lt;attr name="backgroundColor" format="color" /&gt;
                        &lt;attr name="textColor" format="color" /&gt;
                        &lt;attr name="keywords" format="string" /&gt;
                        &lt;attr name="refreshInterval" format="integer" /&gt;
                        &lt;attr name="isGoneWithoutAd" format="boolean" /&gt;
                &lt;/declare-styleable&gt;
        &lt;/resources&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Krok 5&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Ostatnim krokiem jest umieszczenie reklamy (&lt;i&gt;AdView&lt;/i&gt;) &amp;nbsp;na Layout'cie. Zanim jednak to uczynimy, musimy stworzyć referencję do wcześniej stworzonego pliku &lt;i&gt;attrs.xml&lt;/i&gt;. W tym celu dodajemy poniższą linijkę, gdzie &lt;i&gt;yourpackage&lt;/i&gt; oznacza nazwę Twojego pakietu.&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
 xmlns:yourapp="http://schemas.android.com/apk/res/yourpackage"
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Poniżej zamieszczam przykładowy kod layoutu zawierający jedynie samą reklamę. Z rozgryzieniem parametrów nie powinno myślę być problemu.&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;linearlayout 
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:admobsdk="http://schemas.android.com/apk/res/com.admob.android.example"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"&gt;

 &lt;com.admob.android.ads.AdView  
  android:id="@+id/ad" 
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content"
  admobsdk:backgroundColor="#000000"
  admobsdk:textColor="#FFFFFF"
  admobsdk:keywords="Android application"
 /&gt;    
&lt;/LinearLayout&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black */
google_ad_slot = "3801483932";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Krok 6 - Testowanie&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Ludzie z AdMoba sugerują, aby podczas procesu jego integracji (konfiguracji itp.) korzystać tylko z trybu testowego, dzięki czemu zawsze otrzymujemy tę samę (działającą!) reklamę.&lt;br /&gt;
&lt;br /&gt;
W celu uruchomienia trybu testowego, wklejamy poniższą linijkę do tagu &lt;com.admob.android.ads.adview...&gt;&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
admobsdk:testing="true"
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Ważne tylko, aby usunąć ten atrybut przez publikacją aplikacji.&lt;br /&gt;
&lt;/com.admob.android.ads.adview...&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-9164599864552080909?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2Nh6eDhMBOJD1nrHa8nQmV7-e94/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2Nh6eDhMBOJD1nrHa8nQmV7-e94/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2Nh6eDhMBOJD1nrHa8nQmV7-e94/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2Nh6eDhMBOJD1nrHa8nQmV7-e94/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/IHP2Adr7dkI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/9164599864552080909/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2010/02/lekcja-13-instalujemy-reklamy-sieci.html#comment-form" title="Komentarze (2)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/9164599864552080909?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/9164599864552080909?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/IHP2Adr7dkI/lekcja-13-instalujemy-reklamy-sieci.html" title="Lekcja 13. Instalujemy reklamy sieci AdMob." /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_KGPcYjtmXgo/S3m8rJ-UBDI/AAAAAAAAAtI/VWi4c-gk6ls/s72-c/hero_admob.JPG" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://www.helloandroid.pl/2010/02/lekcja-13-instalujemy-reklamy-sieci.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEANRXY_eyp7ImA9WxBWF08.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-8528823730300050168</id><published>2010-02-08T21:45:00.016+01:00</published><updated>2010-02-09T14:39:54.843+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-09T14:39:54.843+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sdcard" /><category scheme="http://www.blogger.com/atom/ns#" term="emulator" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><title>μLekcja 4. Karta SD w emulatorze Androida.</title><content type="html">&lt;a href="http://1.bp.blogspot.com/_KGPcYjtmXgo/S3FkeRaY17I/AAAAAAAAArw/FtSk8VznZFc/s1600-h/4298.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://1.bp.blogspot.com/_KGPcYjtmXgo/S3FkeRaY17I/AAAAAAAAArw/FtSk8VznZFc/s200/4298.jpg" width="200" /&gt;&lt;/a&gt;Do tej pory udało mi się wytrwać bez karty SD w emulatorze Androida. Co więcej, nawet nie widziałem, że można takową zaaplikować. Było to po prostu poza moim zainteresowaniem.&lt;br /&gt;
&lt;br /&gt;
Jak to w życiu bywa, na wszystko przychodzi czas. Przyszedł i na emulację karty SD.&lt;br /&gt;
&lt;br /&gt;
Do dzieła!&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim uruchamiamy konsolę &lt;b&gt;CMD&lt;/b&gt; (Start-&amp;gt;Uruchom-&amp;gt;CMD, właściwie nie wiem po co to piszę na blogu programistycznym ;-))&lt;br /&gt;
&lt;br /&gt;
Przechodzimy do katalogu tools w Android SDK. W zalezności od tego gdzie usadowiliśmy nasze SDK na dysku wpis może/powinien wyglądać mniej więcej tak:&lt;br /&gt;
&lt;blockquote&gt;&lt;b&gt;&lt;i&gt;D:\android-sdk_r3-windows\android-sdk-windows\tools&amp;gt;&lt;/i&gt;&lt;/b&gt;&lt;/blockquote&gt;Następnie poprzez aplikację &lt;b&gt;mksdcard&lt;/b&gt;, tworzymy naszą kartę... wydając polecenie:&lt;br /&gt;
&lt;blockquote&gt;&lt;b&gt;&lt;i&gt;mkscard -l sdcard 128M d:\sdcard.img&lt;/i&gt;&lt;/b&gt;&lt;/blockquote&gt;Przy czym odpowiednio:&amp;nbsp;&lt;i&gt;sdcard &lt;/i&gt;- jest etykietą naszej karty, &lt;i&gt;128M &lt;/i&gt;jak można się domyśleć jest wartością wyrażającą jej rozmiar w megabajtach, a ścieżka na końcu &lt;i&gt;d:\sdcard.img&lt;/i&gt; - odpowiada miejscu utworzenia karty.&lt;br /&gt;
&lt;br /&gt;
W tym momencie mamy utworzony obraz karty sd, zamieszczony (w tym przypadku) w katalogu głównym dysku d.&lt;br /&gt;
&lt;br /&gt;
Ostatnią czynnością którą musimy zrobić, jest wskazanie naszej wirtualnej maszynie nowo utworzonej karty.&lt;br /&gt;
&lt;br /&gt;
Niestety, stety ale poniższe rozwiązanie dotyczy jedynie Eclipse'a, tak więc jak ktoś korzysta z NetBeans'a musi pomęczyć się sam.&lt;br /&gt;
&lt;br /&gt;
Tak więc jeśli korzystamy z Eclipse'a, klikamy na...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_KGPcYjtmXgo/S3BthY9cM4I/AAAAAAAAApo/t2JujZD91Ww/s1600-h/sd1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="122" src="http://4.bp.blogspot.com/_KGPcYjtmXgo/S3BthY9cM4I/AAAAAAAAApo/t2JujZD91Ww/s400/sd1.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
... a następnie konfigurujemy nową maszynę ze wskazaniem na obraz naszej karty.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_KGPcYjtmXgo/S3BtueTy4XI/AAAAAAAAApw/GzwlHgT2SQI/s1600-h/sd2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/_KGPcYjtmXgo/S3BtueTy4XI/AAAAAAAAApw/GzwlHgT2SQI/s400/sd2.png" width="290" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
I to wszystko, mamy wirtualną maszynę Androida z kartą SD.&lt;br /&gt;
&lt;br /&gt;
No ale zastanówmy się. Mamy kartę ale pustą, jak coś na niej umieścić?!!?&lt;br /&gt;
&lt;br /&gt;
Znów przychodzi z pomocą nam Eclipse.&lt;br /&gt;
&lt;br /&gt;
Klikamy na &lt;i&gt;DDMS&lt;/i&gt; w prawym górnym rogu okna Eclipse'a.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_KGPcYjtmXgo/S3Bwd-D5_FI/AAAAAAAAAp4/SaCNQgQHu38/s1600-h/sd3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="63" src="http://3.bp.blogspot.com/_KGPcYjtmXgo/S3Bwd-D5_FI/AAAAAAAAAp4/SaCNQgQHu38/s400/sd3.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Po przełączeniu się Eclipse'a w tryb &lt;i&gt;DDMS&lt;/i&gt;, wybieramy zakładkę &lt;i&gt;File Explorer&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_KGPcYjtmXgo/S3B1ZbcHqcI/AAAAAAAAAqY/hmPaPvtxMgU/s1600-h/sd5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="87" src="http://3.bp.blogspot.com/_KGPcYjtmXgo/S3B1ZbcHqcI/AAAAAAAAAqY/hmPaPvtxMgU/s400/sd5.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;"...i oczom ich ukazał się las"&lt;/i&gt;, a dokładnie zawartość karty sd&amp;nbsp;- parafrazując kultowy tekst z niemniej kultowego filmu.&lt;br /&gt;
&lt;br /&gt;
Kopiowanie plików na kartę odbywa się albo poprzez "przeciągnięcie" pliku do katalogu, albo klikając na ikonkę&amp;nbsp;zaznaczoną&amp;nbsp; na żółto na powyższym screenie.&lt;br /&gt;
&lt;br /&gt;
Zarządzaniem kartą możemy także zająć się z poziomu konsoli, a dokładniej przez &lt;i&gt;&lt;b&gt;adb&lt;/b&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
W tym celu, będąc w katalogu \tools wydajemy komendę &lt;i&gt;&lt;b&gt;adb shell&lt;/b&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;, po wylistowaniu zawartości naszego telefonu (komendą &lt;b&gt;ls&lt;/b&gt;) dojrzymy naszą kartę SD.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_KGPcYjtmXgo/S3B0dqIHKlI/AAAAAAAAAqQ/RJEoN8nBuAM/s1600-h/adb6.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="100" src="http://4.bp.blogspot.com/_KGPcYjtmXgo/S3B0dqIHKlI/AAAAAAAAAqQ/RJEoN8nBuAM/s400/adb6.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
Wchodzimy do katalogu sdcard... &lt;b&gt;cd sdcard&lt;/b&gt;, nastepnie listujemy jego zawartość&lt;b&gt; ls&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_KGPcYjtmXgo/S3B132IMi6I/AAAAAAAAAqg/imFjp7UUbjw/s1600-h/sd7.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="90" src="http://2.bp.blogspot.com/_KGPcYjtmXgo/S3B132IMi6I/AAAAAAAAAqg/imFjp7UUbjw/s400/sd7.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
Oczywiście w tym momencie mamy dostępne wszelkie komendy unixowe, tak więc możemy dowolnie "bawić" się zawartością naszej karty ;)&lt;br /&gt;
&lt;br /&gt;
To tyle... do następnego razu!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-8528823730300050168?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/azJI-Ms1vnhSmdNMKIIwYLP_zLY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/azJI-Ms1vnhSmdNMKIIwYLP_zLY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/azJI-Ms1vnhSmdNMKIIwYLP_zLY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/azJI-Ms1vnhSmdNMKIIwYLP_zLY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/j5ap4stSvBQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/8528823730300050168/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2010/02/lekcja-4-karta-sd-w-emulatorze-androida.html#comment-form" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/8528823730300050168?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/8528823730300050168?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/j5ap4stSvBQ/lekcja-4-karta-sd-w-emulatorze-androida.html" title="μLekcja 4. Karta SD w emulatorze Androida." /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_KGPcYjtmXgo/S3FkeRaY17I/AAAAAAAAArw/FtSk8VznZFc/s72-c/4298.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.helloandroid.pl/2010/02/lekcja-4-karta-sd-w-emulatorze-androida.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8HQHs5cSp7ImA9WhZQEU0.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-4195423495133934861</id><published>2010-01-29T12:38:00.011+01:00</published><updated>2011-04-18T08:40:31.529+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-18T08:40:31.529+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programowanie" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><title>[Na przerwie] Dlaczego warto zaprzyjaźnić się z Androidem!?</title><content type="html">&lt;span style="font-size: small;"&gt;&lt;b&gt;Wstęp&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Na początku chciałbym zaznaczyć, że poniższy tekst jest subiektywnym poglądem autora na świat smartphonów. Nie jest poparty szczególnymi badaniami rynku, dogłębnymi analizami, a tylko albo aż codziennymi obserwacjami z punktu widzenia przeciętnego użytkownika.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_KGPcYjtmXgo/S2LIhXBJgsI/AAAAAAAAApM/8SMOFK1HLxU/s1600-h/android-logo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://3.bp.blogspot.com/_KGPcYjtmXgo/S2LIhXBJgsI/AAAAAAAAApM/8SMOFK1HLxU/s320/android-logo.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;b&gt;Stan obecny&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Jakiś czas temu trafiłem na artykuł, o intrygującym i dumnie brzmiącym tytule w stylu "Koniec ery smartphonów". Aż lekko mi się ciśnienie podniosło, jak to zobaczyłem. Kliknąłem w link i co się okazało, a to, że powoli możemy mówić o schyłku ery urządzeń zwanych smartphonami. Dlaczego schyłku? Otóż do tej pory "zmyślne telefony" były pewną niszą na rynku, skierowaną do konkretnego odbiorcy, np. klienta biznesowego albo po prostu dla grupy tzw. power-userów.&lt;br /&gt;
Musimy tutaj na chwilę przystanąć i odpowiedzieć sobie na pytanie jak charakteryzujemy smartphony. Według wikipedii, smartphone jest "urządzeniem telefonicznym integrującym w sobie kilka funkcji... łączy funkcje telefonu komórkowego, poczty elektronicznej, przeglądarki sieciowej, pagera, GPS, jak również cyfrowego aparatu fotograficznego i prostej kamery wideo". Co się okazuje? Śmiało można stwierdzić, że 95% nowych sprzedawanych telefonów komórkowych podpada pod tą grupę. Dlatego też, śmiało można powiedzieć, że era smartphonów przemija, bo wszystkie urządzenia mobilne są teraz smartphonami. Innych nie ma i nie będzie.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black1 */
google_ad_slot = "5985861762";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;b&gt;Smartphony a OS i dlaczego Android&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Przy takiej rozpiętości funkcji, przy rosnących wydajnościach procesorów (itp.) i tym samym co raz większych możliwościach drzemiących w smartphonach, nie obejdzie się bez nowoczesnego systemu operacyjnego, który będzie sprawnie pośredniczył pomiędzy hardwarem, a tysiącami codziennie powstających aplikacji poszerzających użyteczność opisywanych urządzeń.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Krótki przegląd rynku mobilnych systemów operacyjnych&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt; &lt;/i&gt;&lt;br /&gt;
&lt;i&gt;Symbian OS&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Na rynku, jak zapewne wiadomo do tej pory królował i króluje Symbian OS. Niestety jego piętą achillesową jest ograniczona dostępność, zawężona tylko do telefonów marki Nokia. Za dziwne, uważam więc statystyki mówiące, że za 3-4 lata będzie systemem numero uno. Przy spadającej popularności Nokii... no sam nie wiem.&lt;br /&gt;
Nokia co prawda wypuszcza nową, uwspółcześnioną wersję Symbiana, ale dopóki jego zastosowanie będzie ograniczało się do ich telefonów, to prawdopodobnie podzieli los naszego następnego bohatera, czyli...&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;iPhone OS&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Kolejnym, pozornie liczącym się system jest iPhone OS. Dlaczego pozornie. Dopóki iPhone nie zmieni strategii dotyczącej jednego (w danej chwili na rynku) uniwersalnego telefonu, nigdy nie osiągnie znaczącej pozycjii na rynku, a będzie tylko ciekawostką z olbrzymim i skutecznym PR'em. Nie chcę tutaj drążyć tematu, bo nic z tego dobrego nie wyniknie, prócz kolejnej wojny na linii apple kontra reszta świata ;)&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Windows Mobile&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Nie zapominajmy także o starym i poważnym graczu jakim jest Windows Mobile, który trochę przysnął, podobno się budzi, ale zwłoka z tym budzeniem przez kolejny rok (Window Mobile 7) może wpłynąć na jego popularność. Tak czy owak, jest obecnie nie wiadomą. Jednakże, nie powinniśmy lekceważyć potentata z Redmond.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Android&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego według mnie Android wyjdzie na prowadzenie. Otóż, składa albo złoży się na to kilka czynników.&lt;br /&gt;
&lt;br /&gt;
1. Firma matka - wszech obecny Google. Nie oszukujmy się, to oni w dużym stopniu kreują    Internet i wytyczają nowe trendy. Dodatkowo, jest to firma z praktycznie nie ograniczonym budżetem i zasobami ludzkimi.&lt;br /&gt;
&lt;br /&gt;
2. System jest oparty na Linuxie, czyli kolejny atut - możliwości plus otwartość.&lt;br /&gt;
&lt;br /&gt;
3. Równe szanse startu. Linux na rynku PC nie może nadal konkurować z hegemonią Microsoftu, ale na rynku urządzeń mobilnych wszyscy gracze mają póki co równe szanse na starcie.&lt;br /&gt;
&lt;br /&gt;
4. Czwarty punkt dla mnie najważniejszy. Wydaje mi się, że Google nie chce Androidem konkurować z iPhonem czy czymkolwiek innym. Ludzie błędnie usiłują cały czas znaleźć w Androidzie iPhone killera.&lt;br /&gt;
Według mnie Android, ma być takim cichym (ukrytym w cieniu) systemem instalowanym w telefonach wszelkich marek. Android nie ma być kojarzony z konkretnym urządzeniem. Google zapędziło się trochę  z Nexusem One, wypuszczając go pod swoją marką. Prawdopodobnie jest to jednak tylko zagranie czysto marketingowe. Tak czy owak, trochę szumu wokół Androida nie zaszkodzi, a sam Nexus wydaje się, że rzeczywiście może konkurować z iPhonem (smile). Wracając jednak do tematu.&lt;br /&gt;
Większość użytkowników kupując nowy telefon nie będzie zdawała sobie sprawy, że ich telefon pracuje pod obsługą systemu spod znaku zielonego robota. Google nie mówi, w jakim telefonie może być zainstalowany Android, a w jakim nie. Producenci sami będą chętnie sięgali po Androida, co jest już wyraźnie zauważalne. Prawdopodobnie ten rok, to będzie prawdziwa ekspansja słuchawek z Androidem. Sama Motorola zapowiedziała wypuszczenie w tym roku od 20 do 30 słuchawek pod tym systemem.&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black */
google_ad_slot = "3801483932";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;i&gt;Pozostałe systemy&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Nie wymieniłem w tym krótkim przeglądzie systemów takich jak WebOS, Maemo, czy też Bada, bo to raczej ciekawostki.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;b&gt;Przyszłość&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
W najjaśniejszych kolorach rysuje się przyszłość dla Androida. Faktem są systemy operacyjne w telefonach, a raczej to już w małych i całkiem wydajnych komputerach. Numerem jeden, będzie oczywiście system który trafi pod strzechy, czyli będzie instalowany na większości urządzeń dostępnych na rynku. Symbian, dopóki tylko na Nokii, na pewno nie. Tak samo z iPhone OS. Konkurentami mogą być dla siebie tylko Windows i Android, jednak fakt otwartości systemu, (jednak) większego zaplecza i braku negatywnych odczuć, które często towarzyszą produktom od Microsoftu, prawdopobonie pozwolą wejść Androidowi na najwyższy stopień podium.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;b&gt;Developers, developers, developers...&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Czy warto zacząć naukę programowania i pisać aplikację na platformę Android? Tu już musisz sobie sam odpowiedzieć na to pytanie. Póki co wszystkie gwiazdy na niebie wskazują, że tak.&lt;br /&gt;
Dodatkowo, startując w tym momencie, masz wyrównane szanse z innymi developerami, którzy także dopiero teraz poznają tę platformę, bo nie zapominajmy, że Android jest młodym robocikiem, który ledwo skończył 2 latka...&lt;br /&gt;
&lt;br /&gt;
...dlatego kubek kawy w dłoń i do klawiatury!&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
Ps.&lt;br /&gt;
No proszę, pisałem kilka dni temu o tym, że Symbian nie ma szans na zawładnięcie rynku póki jest systemem komercyjnym i w dodatku stosowanym przez jednego producenta, a tu dzisiaj z rana taka wiadomość: &lt;a href="http://webhosting.pl/Symbian.uwalnia.kod.zrodlowy.glownym.konkurentem.Android"&gt;Symbian uwalnia kod źródłowy: głównym konkurentem jest Android?&lt;/a&gt; Robi się coraz ciekawiej ;)&lt;br /&gt;
&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-4195423495133934861?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yByR7fkkYlg6I7L4Y2TGccKkWfk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yByR7fkkYlg6I7L4Y2TGccKkWfk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yByR7fkkYlg6I7L4Y2TGccKkWfk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yByR7fkkYlg6I7L4Y2TGccKkWfk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/isjCWa0luGY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/4195423495133934861/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2010/01/dlaczego-warto-zaprzyjaznic-sie-z.html#comment-form" title="Komentarze (6)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/4195423495133934861?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/4195423495133934861?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/isjCWa0luGY/dlaczego-warto-zaprzyjaznic-sie-z.html" title="[Na przerwie] Dlaczego warto zaprzyjaźnić się z Androidem!?" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_KGPcYjtmXgo/S2LIhXBJgsI/AAAAAAAAApM/8SMOFK1HLxU/s72-c/android-logo.jpg" height="72" width="72" /><thr:total>6</thr:total><feedburner:origLink>http://www.helloandroid.pl/2010/01/dlaczego-warto-zaprzyjaznic-sie-z.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UERngzeSp7ImA9WxBXEE8.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-1151581828543014869</id><published>2010-01-21T00:04:00.000+01:00</published><updated>2010-01-21T00:13:27.681+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-21T00:13:27.681+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SQLiteDatabase" /><category scheme="http://www.blogger.com/atom/ns#" term="programowanie" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><title>μLekcja 3. Dostęp do bazy danych z linii poleceń.</title><content type="html">&lt;a href="http://4.bp.blogspot.com/_KGPcYjtmXgo/S1eNIG6itHI/AAAAAAAAAog/7akZLGedEBY/s1600-h/SQLiteLogo3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; TEXT-DECORATION: NONE; border: 0" border="0"&gt;&lt;img border="0" style="border:0" src="http://4.bp.blogspot.com/_KGPcYjtmXgo/S1eNIG6itHI/AAAAAAAAAog/7akZLGedEBY/s320/SQLiteLogo3.png" /&gt;&lt;/a&gt;W trakcie pracy nad pewną aplikacją, zaistniała potrzeba bezpośredniego dostępu do bazy danych wykorzystywanej właśnie w tej aplikacji (Przez bezpośredni dostęp rozumiem możliwość połączenia się z BD z zewnątrz programu). Jeżeli, ktoś się nie przedarł przez dokumentację deweloperską Androida, to może nie wiedzieć o istnieniu takiej możliwości. Postanowiłem więc przybliżyć Wam jeden z takich sposobów!&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Z odsięczą przychodzi nam ADB, a właściwie Shell ADB (Android Debug Bridge) oraz program do obsługi bazy danych &lt;a href="http://www.sqlite.org/sqlite.html"&gt;sqlite3&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Krok po kroku.&lt;br /&gt;
1.) Uruchamiamy emulator bądź telefon.&lt;br /&gt;
2.) Uruchamiamy CMD.exe (Start -&amp;gt; Uruchom -&amp;gt; cmd.exe).&lt;br /&gt;
3.) Przechodzimy do katalogu &lt;i&gt;tools&lt;/i&gt; z Android SDK.&lt;br /&gt;
4.) Wydajemy komendę &lt;b&gt;adb shell&lt;/b&gt;. Uzyskujemy dostęp do shella na naszym emulatorze.&lt;br /&gt;
5.) Przechodzimy do katalogu: &lt;b&gt;cd /data/data/&lt;/b&gt;, gdzie mamy dostępną listę wszystkich zainstalowanych aplikacji na naszym urządzeniu/emulatorze.&lt;br /&gt;
6.) Wybieramy interesującą nas aplikację, np. &lt;b&gt;cd /my.lesson.sampledb&lt;/b&gt; (aplikacja z jednej z poprzednich lekcji).&lt;br /&gt;
7.) Przechodzimy do katalogu z bazami danych... &lt;b&gt;cd /databases&lt;/b&gt;&lt;br /&gt;
8.) Ostatnim krokiem jest uruchomienie interesującej nas BD w Sqlite3, komendą &lt;b&gt;sqlite3 mojaBaza&lt;/b&gt; (Istotna wielkość liter!!!).&lt;br /&gt;
9.) Dla testu możemy wydać komendę &lt;b&gt;.tables&lt;/b&gt;, która zwróci nam istniejące tabele.&lt;br /&gt;
&lt;br /&gt;
W tym miejscu odsyłam do dokumentu &lt;a href="http://www.sqlite.org/sqlite.html"&gt;Command Line Shell For SQLite&lt;/a&gt;, gdzie wyjaśnione zostały zasady obsługi bazy danych z linii poleceń.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-1151581828543014869?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AVdfxW98tYNOHPOYVZtXXzEuKDc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AVdfxW98tYNOHPOYVZtXXzEuKDc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AVdfxW98tYNOHPOYVZtXXzEuKDc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AVdfxW98tYNOHPOYVZtXXzEuKDc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/ISs5uFTGthA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/1151581828543014869/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2010/01/lekcja-3-dostep-do-bazy-danych-z-linii.html#comment-form" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/1151581828543014869?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/1151581828543014869?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/ISs5uFTGthA/lekcja-3-dostep-do-bazy-danych-z-linii.html" title="μLekcja 3. Dostęp do bazy danych z linii poleceń." /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_KGPcYjtmXgo/S1eNIG6itHI/AAAAAAAAAog/7akZLGedEBY/s72-c/SQLiteLogo3.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.helloandroid.pl/2010/01/lekcja-3-dostep-do-bazy-danych-z-linii.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIFQXw5cSp7ImA9WxBQEk4.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-593273755097261117</id><published>2010-01-11T19:17:00.000+01:00</published><updated>2010-01-11T19:28:30.229+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-11T19:28:30.229+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="TextView" /><category scheme="http://www.blogger.com/atom/ns#" term="programowanie" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="Spannable" /><title>μLekcja 2. Formatowanie tekstu w locie</title><content type="html">Kolejna piko-lekcja. Tym razem chciałbym napisać kilka zdań na temat formatowania wyświetlanego (np. w TextView) tekstu "w locie".&lt;br /&gt;
&lt;br /&gt;
Nierzadko zdarza się, że chcemy wystylizować fragment tekstu wyświetlanego na ekranie Androida. &lt;br /&gt;
Jednym z możliwych rozwiązań jest umieszczenie np. dwóch pól TextView na View, każde "sformatowane" wedle własnego uznania. Czego można dokonać poprzez deklaracje odpowiednich atrybutów w pliku (.xml) zawierającym layout interesującej nas aplikacji.&lt;br /&gt;
 &lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Przykład&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;textview 
	android:id="@+id/poleTekstowe"
	android:background="#555555" 
	android:textSize="12sp"
        android:textColor="@android:color/white" /&gt;

&lt;textview 
	android:id="@+id/poleTekstowe2"
	android:background="#000000" 
	android:textSize="14sp"
        android:textColor="@android:color/red" /&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Nie zawsze jest to jednak pożądane rozwiązanie, albo wręcz nie możliwe do realizacji z powodów np. konstrukcji aplikacji.&lt;br /&gt;
&lt;br /&gt;
Na pomoc przychodzi możliwość formatowania tekstu w locie. Dodatkowo mamy na to nie jeden, a dwa sposoby.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Sposób pierwszy&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
W pierwszym sposobie skorzystamy z klasy &lt;a href="http://developer.android.com/reference/android/text/Spannable.html"&gt;Spannable&lt;/a&gt;, rozszerzającej możliwości pola TextView.&lt;br /&gt;
&lt;br /&gt;
W przypadku, gdy formatowanym polem będzie pole typu EditText, nie musimy informować tegoż pola o potrzebie użycia wspomnianej klasy, gdyż EditText korzysta z niej domyślnie.&lt;br /&gt;
&lt;br /&gt;
Inaczej ma się sytuacja przy polu TextView, które wymaga poinformowania o potrzebie użycia Spannable.&lt;br /&gt;
&lt;br /&gt;
Przykład&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
poleTekstowe.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE);
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Następnie deklarujemy obiekt typu Spannable...&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
Spannable str = poleTekstowe.getText();
]]&gt;
&lt;/script&gt;&lt;br /&gt;
... po czym przystępujemy do stworzenia naszych "span"-sekcji&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
]]&gt;
&lt;/script&gt;&lt;br /&gt;
I to wszystko. Sprawdź jakie wyniki otrzymałeś!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Drugi sposób&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Z drugim sposobem formatowania tekstu w locie jest jeszcze mniej kłopotu, a niekiedy jego użycie jest jedyną możliwością np. w RemoteViews (chyba, że ktoś wie jak zastosować sposób pierwszy?).&lt;br /&gt;
&lt;br /&gt;
Otóż, możemy skorzystać ze starego poczciwego HTML'a, bezpośrednio formatując tekst przesyłany do elementu przy pomocy metody .setText() albo .setTextViewText() jak ma to miejsce na poniższym  listingu.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
remoteViews.setTextViewText(R.id.poleTekstowe, Html.fromHtml("&lt;b&gt;To będzie pogrubione&lt;/b&gt; &lt;small&gt;To pomniejszone&lt;/small&gt;"));
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-593273755097261117?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kclCfOsX3JdpR6W_LhSMMNxeuKM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kclCfOsX3JdpR6W_LhSMMNxeuKM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kclCfOsX3JdpR6W_LhSMMNxeuKM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kclCfOsX3JdpR6W_LhSMMNxeuKM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/hd56v_b-OSU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/593273755097261117/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2010/01/lekcja-2-formatowanie-tekstu-w-locie.html#comment-form" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/593273755097261117?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/593273755097261117?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/hd56v_b-OSU/lekcja-2-formatowanie-tekstu-w-locie.html" title="μLekcja 2. Formatowanie tekstu w locie" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.helloandroid.pl/2010/01/lekcja-2-formatowanie-tekstu-w-locie.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUMQH4zfSp7ImA9WxBRF0Q.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-7906464061351511086</id><published>2010-01-06T16:38:00.000+01:00</published><updated>2010-01-06T16:38:01.085+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-06T16:38:01.085+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="appWidgetProvider" /><category scheme="http://www.blogger.com/atom/ns#" term="SharedPreferences" /><category scheme="http://www.blogger.com/atom/ns#" term="onUpdate" /><category scheme="http://www.blogger.com/atom/ns#" term="AppWidgetManager" /><category scheme="http://www.blogger.com/atom/ns#" term="widget" /><title>Lekcja 12. Jak skonfigurować widget!</title><content type="html">&lt;a href="http://1.bp.blogspot.com/_KGPcYjtmXgo/S0StkXzlSHI/AAAAAAAAAng/zZPow2MrNS4/s1600-h/android-widget-design-guidelines.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_KGPcYjtmXgo/S0StkXzlSHI/AAAAAAAAAng/zZPow2MrNS4/s200/android-widget-design-guidelines.png" /&gt;&lt;/a&gt;Jak wiadomo, najlepszym sposobem nauki programowania (jak i w ogóle nauki) jest postawienie sobie konkretnego celu do zrealizowania. Moim celem miało być napisanie prostej aplikacji w formie widżetu realizującego pewne zadanie. Jednak zanim umieścimy nasz widżet na pulpit-droidzie, zdarza się, że musimy go najpierw skonfigurować, podać dane jak np. login czy też hasło. Z pozoru trywialna rzecz i taka naprawdę jest ale po kolei. &lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;ETAP 1&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Pierwszym krokiem jest stworzenie prostego widgetu, takiego jaki był zaprezentowany w &lt;b&gt;lekcji 4&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Potrzebne będą nam pliki:&lt;br /&gt;
&lt;i&gt;&lt;b&gt;MainWidget.clas&lt;/b&gt;s&lt;/i&gt; - nasz główna klasa odpowiedzialna za działanie widgetu,&lt;br /&gt;
&lt;i&gt;&lt;b&gt;main.xml&lt;/b&gt;&lt;/i&gt; - layout widgetu,&lt;br /&gt;
&lt;i&gt;&lt;b&gt;widget_provider.xml&lt;/b&gt;&lt;/i&gt; - informacje o naszym widgetcie (przypominam aby umieścić plik w lokalizacji res/xml)&lt;br /&gt;
oraz &lt;i&gt;&lt;b&gt;manifest&lt;/b&gt;&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Zaczymy od layoutu widgetu &lt;b&gt;main.xml&lt;/b&gt;&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" android:orientation="vertical"
	android:layout_gravity="center"
	android:layout_height="wrap_content"
	android:background="@drawable/ramkablack"&gt;

&lt;textview android:id="@+id/widget_textview"
	android:layout_height="wrap_content"
	android:layout_width="wrap_content"
	android:layout_gravity="center_horizontal|left"
	android:padding="12dip"
	android:textColor="@android:color/white"/&gt;
&lt;/LinearLayout&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Uwaga! Jeśli po wklejeniu tego kodu do edytora, będziesz miał błędy to najprawdopodobniej nie masz tła &lt;i&gt;android:background...&lt;/i&gt;, które możesz wykorzystać z poprzedniej lekcji o widgetach.&lt;br /&gt;
&lt;br /&gt;
Następnie klasa &lt;b&gt;MainWidget.class&lt;/b&gt;&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
public class MainWidget extends AppWidgetProvider {

	RemoteViews remoteViews;

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {

		remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
		remoteViews.setTextViewText(R.id.widget_textview,
				"Przykladowy tekst!!!");

		appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
	}
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Uproszczona jak tylko się dało.&lt;br /&gt;
&lt;br /&gt;
Kolej na &lt;b&gt;widget_provider.xml&lt;/b&gt;&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="146dip"
    android:minHeight="72dip"
    android:updatePeriodMillis="0"
    android:initialLayout="@layout/main"
/&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Wymiary widgetu, użyty layout oraz czas odświeżania metody &lt;i&gt;onUpdate&lt;/i&gt;.&lt;br /&gt;
Ponadto uwaga, od wersji SDK 1.5 &lt;i&gt;updatePeriodMillis&lt;/i&gt; działa jedynie dla wartości powyżej 30 minut. Google się tłumaczy oszczędnością baterii - słaba wymówka ;). Jeżeli potrzebujesz częściej wywoływać (okresowo) pewne zadanie, to zachęcam do zapoznania się z Timerem i jego metodami, a przede wszystkim klasą Alarm Manager - notabene o niej będzie także wkrótce lekcja.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Tip:&lt;/i&gt; W przypadku wybrania updatePeriodMillis="0", widget nie będzie się automatycznie aktualizował.&lt;br /&gt;
&lt;br /&gt;
Ostatnim krokiem jest edycja &lt;b&gt;manifestu&lt;/b&gt;...&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="my.lesson.android.widgetConfigureLesson"
      android:versionCode="1"
      android:versionName="1.0"&gt;
    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
        &lt;receiver android:name=".MainWidget" android:label="Widget"&gt;
            &lt;intent-filter&gt;
                &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&gt;
            &lt;/intent-filter&gt;
            &lt;meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_provider" /&gt;
        &lt;/receiver&gt;
    &lt;/application&gt;
    &lt;uses-sdk android:minSdkVersion="3" /&gt;
&lt;/manifest&gt; 
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;ETAP 2&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Ok. W tym momencie pierwszy etap zakończony. Mamy gotowy widget, którego funkcja ogranicza się do wyświetlenia zdefiniowanej wcześniej frazy.&lt;br /&gt;
&lt;br /&gt;
Kolejnym etapem będzie dodanie ekranu konfiguracyjnego, który wyświetli się w trakcie dodawania widgetu na pulpit.&lt;br /&gt;
&lt;br /&gt;
Pierwszym krokiem niech będzie uzupełnienie pliku &lt;i&gt;widget_provider.xml&lt;/i&gt; o atrybut &lt;i&gt;configure&lt;/i&gt;, wskazujący na aktywności (Activity), która powinna być wywołana przy próbie dodania widgetu.&lt;br /&gt;
&lt;br /&gt;
Ostateczny wygląd providera powinień prezentować się mniej więcej tak:&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="146dip"
    android:minHeight="72dip"
    android:updatePeriodMillis="0"
    android:initialLayout="@layout/main"
    android:configure="my.lesson.android.widgetConfigureLesson.WidgetConfigure"
/&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Następnie tworzymy layout ekranu konfiguracyjnego.&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" android:layout_height="wrap_content"
	android:orientation="vertical" android:text="Ekran konfiguracyjny"&gt;
	
	&lt;textview android:layout_width="fill_parent" android:textStyle="bold" 
		android:layout_height="wrap_content" android:text="Wpisz tu tekst:" /&gt;

	&lt;edittext android:id="@+id/tekst" android:layout_width="fill_parent"
		android:layout_height="wrap_content"  /&gt;
	
	&lt;button android:id="@+id/save_button" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:text="Zapisz" /&gt;
		
&lt;/LinearLayout&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Layout zawiera pole tekstowe, w które wprowadzimy tekst, a następnie "prześlemy" go do widgetu.&lt;br /&gt;
&lt;br /&gt;
Możemy teraz przystąpić do implementacji naszej klasy obsługującej widget.&lt;br /&gt;
W tym celu stwórzmy nową klasę w naszym pakiecie o nazwie np.&lt;i&gt; WidgetConfigure.class&lt;/i&gt; i doprowadźmy ją do postaci...&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.android.widgetConfigureLesson;

import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class WidgetConfigure extends Activity {

	public static final String PREFS_NAME = "WidgetConfigure";
	private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;

	EditText jakisTekst;
	Button jakisPrzycisk;
	AppWidgetManager mAppWidgetManager;

	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);

		// Dzięki temu zapisowi anulujemy wszelkie działania
		// w przypadku chęci wycofania się z dodawania widgetu
		setResult(RESULT_CANCELED);

		// Ustawiamy nasz layout
		setContentView(R.layout.configure_layout);

		// Znajdujemy nasze pole tekstowe
		jakisTekst = (EditText) findViewById(R.id.tekst);
		// oraz przycisk...
		jakisPrzycisk = (Button) findViewById(R.id.save_button);

		// Musimy uzyskać id naszego widgetu z Intentu,
		// który uruchomił nasz ekran konfiguracyjny.
		Intent intent = getIntent();
		Bundle extras = intent.getExtras();
		if (extras != null) {
			mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
					AppWidgetManager.INVALID_APPWIDGET_ID);
		}

		// Jeśli nie ma dostępnego id widgetu, czyli nie istnieje żaden,
		// to kończymy całą zabawę.
		if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
			finish();
		}

		// SharedPrefences jest to zmyślna klasa umożliwiająca zapis, odczyt
		// oraz przechowywanie danych np. konfiguracyjnych jak login, hasło
		final SharedPreferences config = getSharedPreferences(PREFS_NAME, 0);

		// Akcja na kliknięcie przycisku
		jakisPrzycisk.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {

				// Zapisujemy pobrany tekst z pola EditText
				String tekst = jakisTekst.getText().toString();

				SharedPreferences.Editor configEditor = config.edit();
				configEditor.putString("tekst", tekst);
				configEditor.commit();

				//Aby móc zaktualizować zawartość wyświetlaną przez widget
				//po pierwszym uruchomieniu, musimy skorzystać z przygotowanej
				//przez nas metody
				AppWidgetManager appWidgetManager = AppWidgetManager
						.getInstance(getBaseContext());
				MainWidget.updateWidget(getBaseContext(), appWidgetManager,
						mAppWidgetId);

				// Informuje Widget, ze jesteśmy skonfigurowani ;)
				Intent resultValue = new Intent();
				resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
						mAppWidgetId);
				setResult(RESULT_OK, resultValue);
				finish();
			}
		});
	}

}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Szczegółowe objaśnienia w kodzie.&lt;br /&gt;
&lt;br /&gt;
Zmiany zajdą także w klasie &lt;i&gt;MainWidget&lt;/i&gt;&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.android.widgetConfigureLesson;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.SharedPreferences;
import android.widget.RemoteViews;

public class MainWidget extends AppWidgetProvider {

	static RemoteViews remoteViews;

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		
		remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
		remoteViews.setTextViewText(R.id.widget_textview,
		"Witaj świecie");
        
		appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);	
		
	}
	
	public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int mAppWidgetId){
		
		//Pobieramy dane z SharedPreferences, ktore zostaly zapisane
		//podczas konfiguracji widgetu
		SharedPreferences config = context
		.getSharedPreferences(WidgetConfigure.PREFS_NAME, 0);
		String tekst = config.getString("tekst", "");
		
		remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
		remoteViews.setTextViewText(R.id.widget_textview,
		tekst);

		appWidgetManager.updateAppWidget(mAppWidgetId, remoteViews);
	}


	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {

		SharedPreferences config = context.getSharedPreferences(
				WidgetConfigure.PREFS_NAME, 0);
		SharedPreferences.Editor configEditor = config.edit();

		configEditor.remove("tekst");
		configEditor.commit();

		super.onDeleted(context, appWidgetIds);
	}
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
W powyższej klasie pojawiła się tylko jedna zmiana, a dokładnie nowa metoda updateWidget(), która uaktualni tekst na naszym widgetcie o dane pochodzące z etapu konfiguracji.&lt;br /&gt;
&lt;br /&gt;
Teoretycznie można by tą metodę pominąć, a samo przypisanie nowej wartości polu R.id.widget_textview zaimplementować w metodzie onUpdate(), niestety pojawia się pewien problem. Z moich obserwacji wynika, że metoda &lt;i&gt;onUpdate()&lt;/i&gt; jest wykonywana wcześniej niż powinna, czyli dopiero po zakończeniu (zwróceniu RESULT_OK) etapu konfiguracji widgetu, a wykonywana jest przed. A taki przebieg zdarzeń wynikałby z dokumentacji Androida. Jeśli ktoś coś na ten temat wie więcej, byłbym wdzięczny za informacje.&lt;br /&gt;
&lt;br /&gt;
Acha bym zapomniał. Oczywiście mamy także metodę &lt;i&gt;onDeleted()&lt;/i&gt;, która wywoływana jest podczas usuwania widgetu. Dzięki niej możemy posprzątać trochę po sobie.&lt;br /&gt;
&lt;br /&gt;
Ostatni w kolejce do edycji jest &lt;i&gt;manifest&lt;/i&gt;.&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
	package="my.lesson.android.widgetConfigureLesson" android:versionCode="1"
	android:versionName="1.0"&gt;
	&lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
		&lt;activity android:name=".WidgetConfigure"&gt;
			&lt;intent-filter&gt;
				&lt;action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /&gt;
			&lt;/intent-filter&gt;
		&lt;/activity&gt;
		&lt;receiver android:name=".MainWidget" android:label="Widget"&gt;
			&lt;intent-filter&gt;
				&lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&gt;
			&lt;/intent-filter&gt;
			&lt;meta-data android:name="android.appwidget.provider"
				android:resource="@xml/widget_provider" /&gt;
		&lt;/receiver&gt;
	&lt;/application&gt;
	&lt;uses-sdk android:minSdkVersion="3" /&gt;
&lt;/manifest&gt; 
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Koniec.&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-7906464061351511086?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aXEZ6Eib3wNnLW48k3g2GzaWOSo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aXEZ6Eib3wNnLW48k3g2GzaWOSo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aXEZ6Eib3wNnLW48k3g2GzaWOSo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aXEZ6Eib3wNnLW48k3g2GzaWOSo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/PfIw_LWe1Pc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/7906464061351511086/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2010/01/lekcja-12-jak-skonfigurowac-widget.html#comment-form" title="Komentarze (3)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/7906464061351511086?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/7906464061351511086?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/PfIw_LWe1Pc/lekcja-12-jak-skonfigurowac-widget.html" title="Lekcja 12. Jak skonfigurować widget!" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_KGPcYjtmXgo/S0StkXzlSHI/AAAAAAAAAng/zZPow2MrNS4/s72-c/android-widget-design-guidelines.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.helloandroid.pl/2010/01/lekcja-12-jak-skonfigurowac-widget.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAFSXs_cCp7ImA9WhZQEU0.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-8464504954244229830</id><published>2009-12-08T21:34:00.001+01:00</published><updated>2011-04-18T08:38:38.548+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-18T08:38:38.548+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SimpleCursorAdapter" /><category scheme="http://www.blogger.com/atom/ns#" term="Cursor" /><category scheme="http://www.blogger.com/atom/ns#" term="ListView" /><title>μLekcja 1. Własny ListView</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;a href="http://3.bp.blogspot.com/_KGPcYjtmXgo/Sx66hPi6PSI/AAAAAAAAAkU/1zpBQejnnkY/s1600/lista2.PNG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_KGPcYjtmXgo/Sx66hPi6PSI/AAAAAAAAAkU/1zpBQejnnkY/s200/lista2.PNG" /&gt;&lt;/a&gt;W ostatniej lekcji, poświęconej rejestrowi połączeń, do ich wyświetlenia wykorzystaliśmy wbudowaną listę &lt;i&gt;simple_list_item_1&lt;/i&gt;. Niestety wadą takiego rozwiązania jest to, że dostarczamy do danego&lt;i&gt; item'u &lt;/i&gt;jeden konkretny string, co jednocześnie pozbawia nas możliwości przekazania oraz wyświetlenia większej liczby oddzielnych danych (jak np. numer telefonu, data połączenia, czas połączenia) w sposób jak my byśmy tego chcieli.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black1 */
google_ad_slot = "5985861762";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
W takim przypadku najlepiej utworzyć swoją własną listę, w której poszczególne elementy możemy rozmieścić według własnego uznania. Przykładowa lista może wyglądać tak:&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt; 
&lt;linearlayout 
   android:layout_width="fill_parent" 
   android:layout_height="fill_parent" 
   xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/LinearLAyout" android:orientation="vertical"&gt; 
   
   &lt;TextView
      android:text="@+id/TextView01"
      android:id="@+id/name"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/&gt;
   &lt;TextView
      android:text="@+id/TextView02"
      android:id="@+id/number"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/&gt; 
   &lt;textview 
      android:text="@+id/TextView03"
      android:id="@+id/date"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/&gt;
&lt;/LinearLayout&gt; 
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Co prawda powyższy layout nie jest&amp;nbsp;za bardzo&amp;nbsp;wyszukany, ale nic nie stoi na przeszkodzie, aby Twój był. Możesz między innymi zdefiniować czcionki, kolory, style i &amp;nbsp;rozmieszczenie poszczególnych pół tekstowych i wiele innych.&lt;br /&gt;
&lt;br /&gt;
Samo przypisanie wartości (które pobierzemy z rejestru połączeń) do pól na View jak się okazało nie jest skomplikowane.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.customlistview;

import android.app.ListActivity;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;


public class MyActivity extends ListActivity {
    /** Called when the activity is first created. */

 @Override 
 public void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
 
  Cursor c = getContentResolver().query( 
  android.provider.CallLog.Calls.CONTENT_URI, null, null, null, 
  android.provider.CallLog.Calls.DATE + " DESC"); 
  startManagingCursor(c); 
  
  ListAdapter adapter = new SimpleCursorAdapter(
    this,
    R.layout.main,
    c,
    new String[] {android.provider.CallLog.Calls.NUMBER,android.provider.CallLog.Calls.DATE}, 
    new int[] { R.id.number, R.id.date }); 
  this.setListAdapter(adapter);
  } 
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Z pomocą przychodzi nam klasa&amp;nbsp;&lt;i&gt;SimpleCursorAdapter, &lt;/i&gt;umożliwiającą mapowanie danych pochodzących z Cursor'a na TextView oraz ImageView zdefiniowanych w plikach XML'owych (np. main.xml).&lt;br /&gt;
Konstruktor tej klasy wygląda tak:&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
public SimpleCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to)
]]&gt;
&lt;/script&gt;&lt;br /&gt;
... i przyjmuje parametry:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;context &lt;/b&gt;- kontekst miejsca z którego ListView jest uruchamiane&lt;/li&gt;
&lt;li&gt;&lt;b&gt;layout &lt;/b&gt;- nasz layout&lt;/li&gt;
&lt;li&gt;&lt;b&gt;c&lt;/b&gt; - kursor z danymi&lt;/li&gt;
&lt;li&gt;&lt;b&gt;from &lt;/b&gt;- lista z nazwami kolumn reprezentujących dane w kursorze&lt;/li&gt;
&lt;li&gt;&lt;b&gt;to&lt;/b&gt; - lista pól typu TextView, do których mają być przekazane dane.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-8464504954244229830?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wiQrXjGysKlra3hbGtOzPR2Wfew/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wiQrXjGysKlra3hbGtOzPR2Wfew/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wiQrXjGysKlra3hbGtOzPR2Wfew/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wiQrXjGysKlra3hbGtOzPR2Wfew/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/elYD6WPJOMM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/8464504954244229830/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/12/lekcja-1-wasny-listview.html#comment-form" title="Komentarze (2)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/8464504954244229830?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/8464504954244229830?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/elYD6WPJOMM/lekcja-1-wasny-listview.html" title="μLekcja 1. Własny ListView" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_KGPcYjtmXgo/Sx66hPi6PSI/AAAAAAAAAkU/1zpBQejnnkY/s72-c/lista2.PNG" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/12/lekcja-1-wasny-listview.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EGQ348eSp7ImA9WxBTEks.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-6344809184198479445</id><published>2009-12-08T11:52:00.000+01:00</published><updated>2009-12-08T11:53:42.071+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-08T11:53:42.071+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="iPhone" /><title>[Na przerwie] Nie może być. Reality show dla programistów!</title><content type="html">Ponoć zebrała się międzynarodowa ekipa designerów oraz programistów chcąca w siedem dni stworzyć od zera aplikację na iPhone'a. Co ciekawe cały cykl powstawania tej aplikacji można obejrzeć na żywo w internecie. &lt;a href="http://commandguru.com/"&gt;Transmisja &lt;/a&gt;trwa już od 6 grudnia, a zakończyć się ma 12. Hmmm co Wy na to? ;)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_KGPcYjtmXgo/Sx4vtkKq8LI/AAAAAAAAAj4/Svk3pKLZL-8/s1600-h/iphonereality.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_KGPcYjtmXgo/Sx4vtkKq8LI/AAAAAAAAAj4/Svk3pKLZL-8/s200/iphonereality.PNG" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_KGPcYjtmXgo/Sx4vwD1WzkI/AAAAAAAAAkA/VUuBwJJa3Ig/s1600-h/iphonereality2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_KGPcYjtmXgo/Sx4vwD1WzkI/AAAAAAAAAkA/VUuBwJJa3Ig/s320/iphonereality2.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&amp;nbsp;&lt;span style="font-size: x-small;"&gt;News znaleziony na webhosting.pl &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-6344809184198479445?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/X67yk1jXwNBn28of9QeppnK4wLo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/X67yk1jXwNBn28of9QeppnK4wLo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/X67yk1jXwNBn28of9QeppnK4wLo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/X67yk1jXwNBn28of9QeppnK4wLo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/08gj5Ap2MYs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/6344809184198479445/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/12/na-przerwie-nie-moze-byc-reality-show.html#comment-form" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/6344809184198479445?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/6344809184198479445?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/08gj5Ap2MYs/na-przerwie-nie-moze-byc-reality-show.html" title="[Na przerwie] Nie może być. Reality show dla programistów!" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_KGPcYjtmXgo/Sx4vtkKq8LI/AAAAAAAAAj4/Svk3pKLZL-8/s72-c/iphonereality.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/12/na-przerwie-nie-moze-byc-reality-show.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcMRHc4cSp7ImA9WxNaGEg.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-3540078756802027549</id><published>2009-12-03T16:40:00.000+01:00</published><updated>2009-12-03T17:01:25.939+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-03T17:01:25.939+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="intents" /><category scheme="http://www.blogger.com/atom/ns#" term="TabWidget" /><category scheme="http://www.blogger.com/atom/ns#" term="Cursor" /><title>Lekcja 11. Tworzymy rejestr połączeń.</title><content type="html">&lt;a href="http://1.bp.blogspot.com/_KGPcYjtmXgo/SxfZmhFpU8I/AAAAAAAAAhc/iPKiXJPK8FE/s1600/app_rejestr.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_KGPcYjtmXgo/SxfZmhFpU8I/AAAAAAAAAhc/iPKiXJPK8FE/s200/app_rejestr.png" /&gt;&lt;/a&gt;Wiele osób korzystających z Androida narzeka na brak, a właściwie to bardzo ograniczoną wersję rejestru połączeń, jakby się wydawało niezbędnego minimum na wyposażeniu każdego telefonu od co najmniej piętnastu lat. &lt;br /&gt;
&lt;br /&gt;
Oczywiście w mniejszym bądź większym stopniu problem rozwiązują zewnętrzne aplikacje, a w Androidzie w wersji 2.0 jest już całkiem nieźle.&lt;br /&gt;
&lt;br /&gt;
Tak czy owak problem występuję, bo i można to zauważyć po liczbie postów na forach, jak i ciągle pojawiających się aplikacjach rozszerzających możliwości standardowego rejestru.&lt;br /&gt;
Jak łatwo można stworzyć podobną aplikację, chciałem udowodnić w tej lekcji. Nie będzie to zaawansowany kombajn, a prosta aplikacja dająca przyczółek do stworzenia czegoś lepszego, czegoś dostosowanego do własnych potrzeb.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Tyle słowem wstępu. Zaczynamy.&lt;br /&gt;
&lt;br /&gt;
Nawigacja w aplikacji oparta jest o &lt;i&gt;TabWidget&lt;/i&gt;, czyli o system zakładek. Więcej informacji możesz uzyskać pod adresem &lt;a href="http://developer.android.com/guide/tutorials/views/index.html"&gt;http://developer.android.com/guide/tutorials/views/index.html&lt;/a&gt;&lt;br /&gt;
Natomiast historia połączeń, wraz z detalami jest wyświetlana w postaci domyślnej listy &lt;a href="http://developer.android.com/guide/tutorials/views/hello-listview.html"&gt;simple_list_item_1&lt;/a&gt;, o której już zresztą pisałem w lekcji o Sql'u.&lt;br /&gt;
&lt;br /&gt;
Aplikacja opiera się na klasie&amp;nbsp;&lt;i&gt;RejestrActivity.class&lt;/i&gt;, będącej jej  kontrolerem. Dodatkowo aplikacja składa się trzech klas "pomocniczych", odpowiedzialnych odpowiedniego za pobranie informacji o połączeniach przychodzących, wychodzących oraz nieodebranych. &lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;RejestrOut.class, RejestrIn.class, RejestrMissed.class&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Na pierwszy ogień, niech pójdą klasy odpowiedzialne za samo pobranie informacji o połączeniach, choć przedstawię tylko jedną, gdyż budowa pozostałych jest analogiczna, różniąca się właściwie jednym detalem. &lt;span style="text-decoration: line-through;"&gt;Właściwie mogłaby być tylko jedna klasa, ale musiałbym przekazywać z kontrolera informacje o TAB'ie który został kliknięty, a szczerze mówiąc nawet nie wiem jak to zrobić ;) Pomyślę o tym później.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Tymczasem zawartość klasy &lt;i&gt;RejestrOut.class&lt;/i&gt;&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.rejestr;

import java.util.ArrayList;
import android.app.ListActivity;
import android.database.Cursor;
import android.os.Bundle;
import android.text.format.DateUtils;
import android.widget.ArrayAdapter;

public class RejestrOut extends ListActivity {
	
	@Override
	public void onCreate(Bundle icicle){
		super.onCreate(icicle);
	
        Cursor c = getContentResolver().query( 
                  android.provider.CallLog.Calls.CONTENT_URI, 
                  null, null, null, 
                  android.provider.CallLog.Calls.DATE + " DESC"); 
        startManagingCursor(c); 
         
       
        int numberColumn = c.getColumnIndex( 
                  android.provider.CallLog.Calls.NUMBER); 
        int dateColumn = c.getColumnIndex( 
                  android.provider.CallLog.Calls.DATE); 
        int typeColumn = c.getColumnIndex( 
                  android.provider.CallLog.Calls.TYPE); 
        int nameColumn = c.getColumnIndex(
        		  android.provider.CallLog.Calls.CACHED_NAME);
        int durationColumn = c.getColumnIndex(
        		  android.provider.CallLog.Calls.DURATION);
        
        ArrayList&lt;string&gt; callList = new ArrayList&lt;string&gt;(); 
         
        if(c.moveToFirst()){ 
             do{                   
                  int callType = c.getInt(typeColumn); 
                   
                  if(callType == android.provider.CallLog.Calls.OUTGOING_TYPE){  
	                   String callerPhoneNumber = c.getString(numberColumn); 
	                   String callerPhoneName = c.getString(nameColumn);
	                   
	                   String dateString = DateUtils.getRelativeDateTimeString( 
	                		   getApplicationContext(),
	                		   c.getLong(dateColumn), 
	                				   DateUtils.MINUTE_IN_MILLIS, 
	                				   DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_ABBREV_TIME) 
	                				   .toString(); 
	                   String callDuration = c.getString(durationColumn);
	                   if(callerPhoneName!=null){
	                	   callList.add("Data: "+ dateString  + " Numer: " + callerPhoneNumber+ " - " + callerPhoneName + " Czas pol.: " + callDuration); 
	                   }else{
	                	   callList.add("Data: "+ dateString  + " Numer: " + callerPhoneNumber + " Czas: " + callDuration + "s"); 
	                   }
                  }
                  
             }while(c.moveToNext()); 
        } 
        
		this.setListAdapter(new ArrayAdapter&lt;string&gt;(this, android.R.layout.simple_list_item_1, callList));
	}
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
W pierwszej kolejności, wykorzystując Cursor (&lt;a href="http://www.na-androida.pl/2009/11/lekcja-9-sqlitedatabase-po-prostu.html"&gt;patrz Lekcja 9&lt;/a&gt;) pobieramy zawartość rejestru telefonu, wstępnie go sortując po dacie.&lt;br /&gt;
&lt;br /&gt;
Kolejnym krokiem jest pobranie indeksów kolumn odpowiedzialnych za interesujące nas dane/informacje. Zachęcam, do zapoznania się z dokumentacją odnośnie dostępnych pól &lt;a href="http://developer.android.com/reference/android/provider/CallLog.Calls.html"&gt;CallLog.Calls&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Ostatnią rzeczą jaką musimy zrobić, jest umieszczenie wybranych danych na liście, a następnie poprzez &lt;i&gt;setListAdapter&lt;/i&gt; wyświetlenie jej za pomocą wspomnianej na początku defaultowej listy.&lt;br /&gt;
&lt;br /&gt;
Tutaj wspomniana uwaga. W linii...&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
if(callType == android.provider.CallLog.Calls.OUTGOING_TYPE){  
]]&gt;
&lt;/script&gt;&lt;br /&gt;
decydujemy o typie zrealizowanego połączenia. W powyższym przykładzie, przyjmujemy tylko połączenia wychodzące &lt;i&gt;.OUTGOING_TYPE&lt;/i&gt;. Odpowiednio dostępne są także &lt;i&gt;.INCOMING_TYPE &lt;/i&gt;oraz .&lt;i&gt;MISSED_TYPE.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;RejestrActivity.class&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Przejdźmy teraz do naszego kontrolera. Jak wspomniałem wykorzystamy do jego budowy menu w postaci zakładek (TabWidget). Wykorzystanie ich jest dość łatwe.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.rejestr;

import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TabHost;

public class RejestrActivity extends  TabActivity {
	
	private TabHost mTabHost; 

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
              
        mTabHost = getTabHost();
        
        Intent i = new Intent(getApplicationContext(), RejestrOut.class);
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("Wychodzące").setContent(i));
        
        	   i = new Intent(this, RejestrIn.class); 
        mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("Przychodzące").setContent(i));
        
        	   i = new Intent(this, RejestrMissed.class);
        mTabHost.addTab(mTabHost.newTabSpec("tab_test3").setIndicator("Nieodebrane").setContent(i));
        
        mTabHost.setCurrentTab(0);
        
    }
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Do przekazania rezultatów zwróconych przez klasy RejestrOut/In/Missed do zakładek, wykorzystałem  &lt;i&gt;Intenty&lt;/i&gt; z którymi mogłeś się już zaznajomić w jednej z poprzednich &lt;a href="http://www.na-androida.pl/2009/11/lekcja-5-i-jak-intents.html"&gt;lekcji&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Zmierzamy powoli do końca lekcji. Jednak zanim ten nastąpi musimy stworzyć View dla naszych zakładek. W tym celu edytujemy plik main.xml zgodnie z poniższym wzorem.&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;tabhost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;
    &lt;LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"&gt;
        &lt;TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" /&gt;
        &lt;FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"&gt;
            &lt;textview 
                android:id="@+id/textview1"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" 
                 /&gt;
            &lt;textview 
                android:id="@+id/textview2"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" 
                 /&gt;
            &lt;textview 
                android:id="@+id/textview3"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" 
                 /&gt;
    	&lt;/FrameLayout&gt;
    &lt;/LinearLayout&gt;
&lt;/TabHost&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Już naprawdę ostatnim krokiem, jest poinformowanie Androida, o chęci użycia nowych &lt;i&gt;Activity&lt;/i&gt;, co czynimy dodając odpowiednie wpisy w manifeście. Mój manifest wygląda tak:&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="my.lesson.rejestr"
      android:versionCode="1"
      android:versionName="1.0"&gt;
      &lt;uses-permission android:name="android.permission.READ_CONTACTS"/&gt; 
    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
        &lt;activity android:name=".RejestrActivity"
                  android:label="@string/app_name"&gt;
            &lt;intent-filter&gt;
                &lt;action android:name="android.intent.action.MAIN" /&gt;
                &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
		&lt;activity android:name=".RejestrOut" android:label="RejestrOut.Class!"&gt; 
            &lt;intent-filter&gt; 
                &lt;action android:name="android.intent.action.MAIN" /&gt; 
                &lt;category android:name="android.intent.category.SAMPLE_CODE" /&gt; 
            &lt;/intent-filter&gt; 
        &lt;/activity&gt; 
        &lt;activity android:name=".RejestrIn" android:label="RejestrIn.Class!"&gt; 
            &lt;intent-filter&gt; 
                &lt;action android:name="android.intent.action.MAIN" /&gt; 
                &lt;category android:name="android.intent.category.SAMPLE_CODE" /&gt; 
            &lt;/intent-filter&gt; 
        &lt;/activity&gt; 
        &lt;activity android:name=".RejestrMissed" android:label="RejestrMissed.Class!"&gt; 
            &lt;intent-filter&gt; 
                &lt;action android:name="android.intent.action.MAIN" /&gt; 
                &lt;category android:name="android.intent.category.SAMPLE_CODE" /&gt; 
            &lt;/intent-filter&gt; 
        &lt;/activity&gt; 
    &lt;/application&gt;
    &lt;uses-sdk android:minSdkVersion="5" /&gt;
&lt;/manifest&gt; 
]]&gt;
&lt;/script&gt;&lt;br /&gt;
...and that's all  &lt;br /&gt;
&lt;blockquote&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_KGPcYjtmXgo/SxfZmhFpU8I/AAAAAAAAAhc/iPKiXJPK8FE/s1600-h/app_rejestr.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_KGPcYjtmXgo/SxfZmhFpU8I/AAAAAAAAAhc/iPKiXJPK8FE/s400/app_rejestr.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;b&gt;Uwaga!&lt;br /&gt;
Aplikacja napisana została z wykorzystaniem Android SDK 2.0&lt;br /&gt;
W tej formie nie będzie działać na telefonach z wersjami o niższym oznaczeniu. &lt;br /&gt;
Wiem, że w momencie pisania tego tutoriala, na rynku nie ma jeszcze telefonów z Androidem 2.0 na pokładzie. Jednakże pisanie w starszych wersjach Androida, mijałoby się z celem.&lt;/b&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-3540078756802027549?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bqKrNO9PdbhWiXxaII1VdEZdf7o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bqKrNO9PdbhWiXxaII1VdEZdf7o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bqKrNO9PdbhWiXxaII1VdEZdf7o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bqKrNO9PdbhWiXxaII1VdEZdf7o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/A2V_LDVC0UI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/3540078756802027549/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/12/lekcja-11-tworzymy-rejestr-poaczen.html#comment-form" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3540078756802027549?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3540078756802027549?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/A2V_LDVC0UI/lekcja-11-tworzymy-rejestr-poaczen.html" title="Lekcja 11. Tworzymy rejestr połączeń." /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_KGPcYjtmXgo/SxfZmhFpU8I/AAAAAAAAAhc/iPKiXJPK8FE/s72-c/app_rejestr.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/12/lekcja-11-tworzymy-rejestr-poaczen.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUINQng-eCp7ImA9WxNaFko.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-4815026428779614233</id><published>2009-11-30T23:44:00.000+01:00</published><updated>2009-12-01T14:19:53.650+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-01T14:19:53.650+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="onDraw" /><category scheme="http://www.blogger.com/atom/ns#" term="FrameLayout" /><category scheme="http://www.blogger.com/atom/ns#" term="setOnTouchListener" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="Paint" /><category scheme="http://www.blogger.com/atom/ns#" term="onTouch" /><title>Lekcja 10. Hello Circle, czyli rysuj z Androidem.</title><content type="html">Szukając tematu do nowej lekcji trafiłem na blog użytkowniczki Kellbot z Nowego Jorku, która &amp;nbsp;&lt;a href="http://www.kellbot.com/2009/06/android-hello-circle/"&gt;zaprezentowała&lt;/a&gt; bardziej&amp;nbsp;niecodzienną&amp;nbsp;wersję aplikacji Hello World, a mianowicie Hello Circle.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_KGPcYjtmXgo/SxRNs0_ClQI/AAAAAAAAAhM/kggeTnBnS48/s1600/circle.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_KGPcYjtmXgo/SxRNs0_ClQI/AAAAAAAAAhM/kggeTnBnS48/s200/circle.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Aplikacja zamiast wyświetlić tekst, wyświetla kolorowe kółko po "tapnięciu" przez użytkownika w&amp;nbsp;dowolny obszar ekranu telefonu.&lt;br /&gt;
&lt;br /&gt;
Postanowiłem przybliżyć temat, a właściwie spolszczyć ten krótki tutorial...&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Zaczynamy.&lt;br /&gt;
&lt;br /&gt;
Tworzymy nowy projekt. &lt;br /&gt;
&lt;br /&gt;
Edytujemy widok &lt;i&gt;View&lt;/i&gt; naszej przyszłej aplikacji. Zamiast dotychczasowego &lt;i&gt;LinearLayout&lt;/i&gt;, zastosujemy&amp;nbsp;&lt;i&gt;FrameLayout&lt;/i&gt;, który dostarczy nam obszaru na&amp;nbsp;ekranie, na którym będziemy mogli umieszczać własne elementy. W naszym przypadku będą to tytułowe koła. &lt;i&gt;FrameLayout &lt;/i&gt;umożliwia dodanie wielu swoich potomków, które zawsze będą powiązane z lewym górnym rogiem ekranu. Dzieci &lt;i&gt;FrameLayout &lt;/i&gt;układane są na stosie, czyli najnowsze na górze.&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;framelayout android:id="@+id/main_view"
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#FFFFFF" /&gt;

]]&gt;
&lt;/script&gt;&lt;br /&gt;
Jako, że naszym celem będzie umieszczenie wielu elementów (kółek) na ekranie, najlepszym rozwiązaniem będzie stworzenie klasy np. Circle - odpowiedzialnej za nasze koło.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.circle;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;

public class Circle extends View{
	
	private final float x;
	private final float y;
	private final int r;
	private final Paint rysuj = new Paint(Paint.ANTI_ALIAS_FLAG);
	
	public Circle(Context context, float x, float y, int r){
		super(context);
		rysuj.setColor(0xFFFF0000);
		this.x = x;
		this.y = y;
		this.r = r;		
	}
	
	protected void onDraw(Canvas canvas){
		super.onDraw(canvas);
		canvas.drawCircle(x, y, r, rysuj);
	}
}

]]&gt;
&lt;/script&gt;&lt;br /&gt;
Polami klasy Circle są:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;współrzędne docelowej lokalizacji elementu na ekranie (x,y),&lt;/li&gt;
&lt;li&gt;promień&amp;nbsp;koła (r),&lt;/li&gt;
&lt;li&gt;obiekt klasy &lt;i&gt;Paint&lt;/i&gt; odpowiedzialnej za informacje o stylach, kolorach&amp;nbsp;tworzonych figur geometrycznych czy też tekstów.&lt;/li&gt;
&lt;/ul&gt;Następnie tworzymy konstruktor klasy, który jest metodą wywoływaną zawsze podczas tworzenia&amp;nbsp;nowej instancji klasy. W naszym konkretnym konstruktorze, bez&amp;nbsp;rewelacji. Wszystko powinno być&amp;nbsp;jasne.&lt;br /&gt;
&lt;br /&gt;
Zapomniałem na początku wspomnieć, że nasza kulka, tfe.. kółko zostanie utworzone w nowym&amp;nbsp;widoku (View) dlatego też musimy rozszerzyć naszą klasę Circle właśnie o klasę View.&lt;br /&gt;
&lt;br /&gt;
Ostatnim element klasy jest metoda &lt;i&gt;onDraw&lt;/i&gt; niezbędna do wyprowadzenia naszego rysunku na nowo powstałe View.&lt;br /&gt;
&lt;br /&gt;
Na tym etapie mamy gotowy główny widok, a także klasę odpowiedzialną za rysowanie naszego koła.&lt;br /&gt;
Ostatnim etapem tworzenia aplikacji jest utworzenie akcji dzięki której będziemy mogli umieszczać&amp;nbsp;kółka na ekranie za pomocą&amp;nbsp;palca. W tym celu edytujemy główną klasę aplikacji.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.circle;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

public class TapCircle extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
     
        FrameLayout fLayout = (FrameLayout)findViewById(R.id.main_view);
        
        //1
        fLayout.addView(new Circle(this,50,50,25));
        
        //2
        fLayout.setOnTouchListener(new View.OnTouchListener() {			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				float x = event.getX();
				float y = event.getY();
				
				FrameLayout fl = (FrameLayout)v;				
				fl.addView(new Circle(getParent(),x,y,25));
				return false;
			}
		});
    }
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Jak zapewne zauważyłeś, pierwszą czynnością jest utworzenie "chwytaka" (&lt;i&gt;fLayout&lt;/i&gt;) do&amp;nbsp;naszego &lt;i&gt;View&lt;/i&gt; (z &lt;i&gt;Main.xml&lt;/i&gt;).&lt;br /&gt;
Następnie zaprezentowane zostały dwie metody umieszczenia elementu na ekranie. Pierwsza (&lt;i&gt;//1)&lt;/i&gt; - ordynarne&amp;nbsp;określenie parametrów "na sztywno". Element zostanie umieszczony w lewym górnym rogu z&amp;nbsp;marginesem 50pix.&lt;br /&gt;
Druga metoda (&lt;i&gt;//2&lt;/i&gt;), jest tym co tygryski lubią najbardziej. Dzięki metodzie &lt;i&gt;setOnTouchListener&amp;nbsp;&lt;/i&gt;wykryjemy położenie palca na ekranie, a metoda &lt;i&gt;onTouch &lt;/i&gt;zwróci nam dostęp do nowego View, a także do obiektu&amp;nbsp;&lt;i&gt;MotionEvent&lt;/i&gt;, przechowującego&amp;nbsp;informacje&amp;nbsp;o naszym "tapnięciu". Teraz nie pozostaje nic innego jak dodać nowy obiekt Circle na View.&lt;br /&gt;
&lt;br /&gt;
To tyle. Dziękuje za uwagę.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_KGPcYjtmXgo/SxRFO9HLZnI/AAAAAAAAAg8/GUlLsFlI0qQ/s1600/circle.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_KGPcYjtmXgo/SxRFO9HLZnI/AAAAAAAAAg8/GUlLsFlI0qQ/s400/circle.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-4815026428779614233?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nE0uvi0qCPvXFj-ngyU4fqxziEQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nE0uvi0qCPvXFj-ngyU4fqxziEQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nE0uvi0qCPvXFj-ngyU4fqxziEQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nE0uvi0qCPvXFj-ngyU4fqxziEQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/RUTYspFAmfc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/4815026428779614233/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/11/lekcja-10-hello-circle-czyli-rysuj-z.html#comment-form" title="Komentarze (9)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/4815026428779614233?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/4815026428779614233?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/RUTYspFAmfc/lekcja-10-hello-circle-czyli-rysuj-z.html" title="Lekcja 10. Hello Circle, czyli rysuj z Androidem." /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_KGPcYjtmXgo/SxRNs0_ClQI/AAAAAAAAAhM/kggeTnBnS48/s72-c/circle.PNG" height="72" width="72" /><thr:total>9</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/11/lekcja-10-hello-circle-czyli-rysuj-z.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkECQXo8fip7ImA9WhZQEU0.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-2346557056017779571</id><published>2009-11-24T21:30:00.001+01:00</published><updated>2011-04-18T08:37:40.476+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-18T08:37:40.476+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="openOrCreateDatabase" /><category scheme="http://www.blogger.com/atom/ns#" term="SQLiteDatabase" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><title>Lekcja 9. SQLiteDatabase. Po prostu.</title><content type="html">&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/_KGPcYjtmXgo/SwxDTzoCcUI/AAAAAAAAAfE/ulvDb2vW-eg/s1600/ekran_small.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_KGPcYjtmXgo/SwxDTzoCcUI/AAAAAAAAAfE/ulvDb2vW-eg/s200/ekran_small.png" /&gt;&lt;/a&gt;SQLite jest jednym z systemów zarządzania bazami&amp;nbsp;danych. Obok takich tuz jak MSSQL, MySQL, PostgreSQL czy też Oracle stanowi jedną z najpopularniejszych implementacji silnika SQL w szeregu aplikacji/urządzeń. Jak pewnie się domyślasz w Androidzie również został wykorzystany (jak i w Iphonie czy Firefoxie).  Do głównych zalet (choć akurat to zależy od punktu widzenia) SQLite, możemy zaliczyć możliwość użycia bazy danych bez konieczności uruchamiania osobnego procesu, a także fakt, iż dane przechowywane są w jednym pliku binarnym (do 2TB) w postaci B-drzew. Dodatkowym atutem opisywanej BD jest wydajność przy wykonywaniu (w sczególności) podstawowych zapytań typu INSERT lub SELECT. SQLite (jak i wszystko) nie jest wolny od wad, ale nie o tym jest ta lekcja, dlatego w tym miejscu zakończę teorię z nim związaną.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black1 */
google_ad_slot = "5985861762";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
W tej lekcji zapoznasz się z podstawami użycia bazy danych &lt;i&gt;SQLite&lt;/i&gt; w Androidzie.&lt;br /&gt;
Stworzymy prostą aplikację, której celem będzie utworzenie bazy danych, zapisanie do niej pewnych informacji, a następnie wyprowadzenie ich na ekran Androida.&lt;br /&gt;
&lt;br /&gt;
Zacznę od zaprezentowania kodu aplikacji, po czym przystąpię do jego omówienia.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.sampledb;

import java.util.ArrayList;
import android.app.ListActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;

public class sampledb extends ListActivity{
 
 private final String DB_NAME = "mojaBaza";
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // setContentView(R.layout.main);
        
        ArrayList&lt;string&gt; results = new ArrayList&lt;string&gt;();
        
        SQLiteDatabase baza = null;
       
        try{         
        
         baza = this.openOrCreateDatabase(DB_NAME, MODE_PRIVATE, null);
         // MODE_PRIVATE for the default operation
         
         baza.execSQL("CREATE TABLE IF NOT EXISTS Persons (FirstName VARCHAR, LastName VARCHAR)");
         
         baza.execSQL("INSERT INTO Persons  Values('Lech','Kaczynski');");
         baza.execSQL("INSERT INTO Persons  Values('Donald','Tusk');");
         baza.execSQL("INSERT INTO Persons  Values('Lech','Walesa');");
      
      
      Cursor cursor = baza.rawQuery("SELECT LastName FROM Persons WHERE FirstName like 'Lech'",null);
      
      if(cursor.moveToFirst()){ //Metoda zwraca FALSE jesli cursor jest pusty
       do{
        String FirstName = cursor.getString(cursor.getColumnIndex("LastName"));
        results.add(FirstName);
       }while(cursor.moveToNext()); //Metoda zwraca FALSE wówczas gdy cursor przejdzie ostatni wpis
      }
         
      this.setListAdapter(new ArrayAdapter&lt;string&gt;(this, android.R.layout.simple_list_item_1,results));
         
        }
        catch(SQLiteException e) { 
         Log.e(getClass().getSimpleName(), "Could not create or Open the database"); }
        finally {
         if (baza != null) 
          baza.execSQL("DELETE FROM Persons");
          baza.close();
        }
    }
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Zajmijmy się ciekawszymi fragmentami kodu. I tak zaczynamy od metody &lt;i&gt;openOrCreateDatabase()&lt;/i&gt;, za pomocą której otworzymy bazę danych lub w przypadku jej nie istnienia, utworzymy ją. Parametrem metody jest między innymi nazwa bazy danych, a także tryb dostępu - w naszym przpadku jest to &lt;i&gt;MODE_PRIVATE&lt;/i&gt; stosowany w przypadku standardowych operacji. Następnie tworzymy nową tabelę, po czym umieszczamy w niej dane.&lt;br /&gt;
&lt;br /&gt;
Linijka 38. Tworzymy instancję Kursora, który posłuży nam do dostępu do rezultatów zwróconych przez zapytanie SQL.&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black1 */
google_ad_slot = "5985861762";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Linijki 40-45.  Umieszczamy pobrane z zapytania dane na liście. Tutaj polecam zapoznać się z dokumentacją Kursora w AndroidSDK, a dokładnie z linkiem &lt;a href="http://developer.android.com/reference/android/database/Cursor.html"&gt;http://developer.android.com/reference/android/database/Cursor.html&lt;/a&gt;, gdzie opisane są wykorzystane w powyższym przykładzie metody, jak &lt;i&gt;moveToFirst(&lt;/i&gt;) czy &lt;i&gt;moveToNext().&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Zawartość listy wyprowadzamy na ekran przy pomocy metody &lt;i&gt;setListAdapter()&lt;/i&gt;, na jeden z domyślnych layoutów (widoków) zaimplementowanych w Androidzie. Tutaj uwaga! Aby można było skorzystać z powyższej metody musimy rozszerzyć naszą główną klasę o klasę &lt;i&gt;ListActivity&lt;/i&gt;, która umożliwia wyświetlanie listy elementów dzięki powiązaniu z źródłem danych, jak np. Cursor.&lt;br /&gt;
&lt;br /&gt;
To by było na tyle. Nic ciekawego już nie ma.&lt;br /&gt;
&lt;br /&gt;
Efekt...&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_KGPcYjtmXgo/SwxCHcVRI6I/AAAAAAAAAek/w7yGFfW3b4M/s1600/ekran.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_KGPcYjtmXgo/SwxCHcVRI6I/AAAAAAAAAek/w7yGFfW3b4M/s400/ekran.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-2346557056017779571?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aNwZ9op33zrL1qfgRekZ3TpUy04/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aNwZ9op33zrL1qfgRekZ3TpUy04/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aNwZ9op33zrL1qfgRekZ3TpUy04/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aNwZ9op33zrL1qfgRekZ3TpUy04/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/9NfPZyRZgmU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/2346557056017779571/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/11/lekcja-9-sqlitedatabase-po-prostu.html#comment-form" title="Komentarze (12)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2346557056017779571?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2346557056017779571?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/9NfPZyRZgmU/lekcja-9-sqlitedatabase-po-prostu.html" title="Lekcja 9. SQLiteDatabase. Po prostu." /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_KGPcYjtmXgo/SwxDTzoCcUI/AAAAAAAAAfE/ulvDb2vW-eg/s72-c/ekran_small.png" height="72" width="72" /><thr:total>12</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/11/lekcja-9-sqlitedatabase-po-prostu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIHR38-fip7ImA9WhZQEU0.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-1263799343169335625</id><published>2009-11-18T21:00:00.001+01:00</published><updated>2011-04-18T08:35:36.156+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-18T08:35:36.156+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NotificationManager" /><category scheme="http://www.blogger.com/atom/ns#" term="intents" /><category scheme="http://www.blogger.com/atom/ns#" term="Service" /><category scheme="http://www.blogger.com/atom/ns#" term="IBinder" /><category scheme="http://www.blogger.com/atom/ns#" term="Timer" /><category scheme="http://www.blogger.com/atom/ns#" term="PendingIntent" /><category scheme="http://www.blogger.com/atom/ns#" term="Notification" /><title>Lekcja 8. Serwisy w Androidzie. Bynajmniej nie informacyjne.</title><content type="html">&lt;b&gt;Service&lt;/b&gt; jest jednym z podstawowych komponentów dostępnych w androidowych aplikacjach. Jednak to co go wyróżnia, to fakt iż "chodzi" w tle, bez potrzeby interakcji z użytkownikiem.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_KGPcYjtmXgo/SwROnsAJhyI/AAAAAAAAAd0/penAeFvGxEE/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_KGPcYjtmXgo/SwROnsAJhyI/AAAAAAAAAd0/penAeFvGxEE/s320/1.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;Prezentowany &lt;i&gt;service&lt;/i&gt; należy do grupy tak zwanych &lt;i&gt;local service&lt;/i&gt;, charakteryzujących się tym, że chodzą w tym samym procesie z którego zostały uruchomione, co między innymi oznacza, że ich żywotność jest ściśle powiązana z wątkiem z którego zostały wywołane. W przypadku serwisów "długochodzących", trwających cały czas w systemie (np. klient email), albo mocno zasobożernych typu odtwarzacz muzyczny, poleca się użycie &lt;i&gt;remote service&lt;/i&gt;, pozwalających umieścić serwis w osobnym wątku, do którego będzie mogła się odwoływać większa liczba klientów (O remote service wkrótce będzie osobna lekcja).&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black1 */
google_ad_slot = "5985861762";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Poniżej zaprezentowałem prosty przykład użycia serwisu (przepraszam za to niezbyt trafne spolszczenie). Aplikacja umożliwia uruchomienie oraz zatrzymanie usługi (serwisu). Do tego wykorzystamy nieskomplikowany kontroler. Nic nam po serwisach, gdybyśmy nie mogli zobaczyć efektów ich pracy, bo trzeba pamiętać, że serwisy same w sobie nie posiadają interfejsu. Dlatego też do uwidocznienia ich działań, wykorzystamy notyfikację opisaną kilka lekcji wstecz.&lt;br /&gt;
&lt;br /&gt;
Tradycyjnie tworzenie aplikacji zaczniemy od zaprojektowania intefejsu aplikacji "matki".&lt;br /&gt;
Jedyne co nam potrzeba, to dwa przyciski, jeden do uruchamiania, a drugi do zatrzymywania serwisu.&lt;br /&gt;
&lt;br /&gt;
Całość widoku może wyglądać np. tak...&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
&lt;textview  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    /&gt;
&lt;Button
 android:id="@+id/serviceButton"
 android:text="Start service"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center_horizontal"
&gt;&lt;/Button&gt;
&lt;Button
 android:id="@+id/cancelButton"
 android:text="Stop service"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center_horizontal"  
&gt;&lt;/Button&gt;
&lt;/LinearLayout&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Ok. Utwórz teraz nową klasę. nazwij ją np. &lt;i&gt;myService&lt;/i&gt;. Podstawową klasę możesz przemianować na &lt;i&gt;myController&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Zaczynamy od zaprogramowania kontrolera serwisu (&lt;i&gt;myController.class&lt;/i&gt;).&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.services;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;

public class myController extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button start = (Button)findViewById(R.id.serviceButton);
        Button stop = (Button)findViewById(R.id.cancelButton);
        
        start.setOnClickListener(startListener);
        stop.setOnClickListener(stopListener);
    }
    
    private OnClickListener startListener = new OnClickListener() {
        public void onClick(View v){
         startService(new Intent(myController.this,myService.class));
    }          
   };
       
   private OnClickListener stopListener = new OnClickListener() {
       public void onClick(View v){
        stopService(new Intent(myController.this,myService.class));
   }          
  };
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Tak kod kontrolera wygląda u mnie. Samo uruchamianie i zatrzymywanie serwisu jest jak widać banalnie proste...&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
startService(new Intent(myController.this,myService.class));
stopService(new Intent(myController.this,myService.class));
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Teraz pora na bohatera wieczoru, czyli źródło nie kogo innego jak samego serwisu (&lt;i&gt;myService.class&lt;/i&gt;)&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package my.lesson.services;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

public class myService extends Service {

 @Override
 public IBinder onBind(Intent arg0) {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public void onCreate() {
  super.onCreate();
  okresowePowiadomienie();
  Toast.makeText(getApplicationContext(),"Service wystartowal", Toast.LENGTH_LONG).show();
 }
 
 private void okresowePowiadomienie(){
  
  Timer timer = new Timer();
  TimerTask timerTask = new TimerTask(){
   
   public void run() {
    
    NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    Notification notification = new Notification(R.drawable.icon,"Powiadomienie wywolane przez service",System.currentTimeMillis());
    
    Intent notIntent = new Intent(getApplicationContext(), myController.class);   
    PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notIntent, 0);
    
    notification.setLatestEventInfo(getApplicationContext(),"Powiadomienie","Kliknij aby usunac ;)",contentIntent);
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    
    notificationManager.notify(1335, notification); 
    
   }}; 
   
  timer.scheduleAtFixedRate(timerTask , 100, 50000);  
 }
 
 @Override
 public void onDestroy() {
  super.onDestroy();
  Toast.makeText(this, "Service zniszczony!", Toast.LENGTH_LONG).show();
 }
}

]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Widzimy, że klasa myService dziedziczy po klasie Service. Następnie widzimy interfejs do zdalnego wywoływania serwisu &lt;i&gt;IBinder&lt;/i&gt;, dzięki któremu możemy nawiązać stałe połączenie z serwisem.&lt;br /&gt;
&lt;br /&gt;
W dalszej kolejności dochodzimy do metody &lt;i&gt;onCreate&lt;/i&gt;, która wykona dla nas dwie rzeczy.&lt;br /&gt;
Wyświetli tekst, informujący o fakcie uruchomienia serwisu, a przede wszystkim wywoła funkcję &lt;i&gt;okresowePowiadamianie() &lt;/i&gt;, które co określony czas (np. 50 sekund) wyświetli powiadomienie na pasku statusu.&lt;br /&gt;
&lt;br /&gt;
Ostatnią metodą jest metoda &lt;i&gt;onDestroy()&lt;/i&gt;, która zostanie wywołana w momencie zatrzymania serwisu.&lt;br /&gt;
&lt;br /&gt;
Jeżeli w tym momencie chciałeś uruchomić aplikację, to niestety pewnie się to nie udało i nie uda, a przynajmniej do momentu aż&amp;nbsp;nie poinformujesz&amp;nbsp;Androida w AndroidManifeście, o&amp;nbsp;chęci&amp;nbsp;użycia serwisu.&lt;br /&gt;
W tym celu dodaj przed znacznikiem zamykającym &lt;i&gt;application &lt;/i&gt;poniższą linijkę.&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;service android:name=".myService"&gt;&lt;/service&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
W tym momencie możesz już w pełni cieszyć się swoją pierwszą usługą uruchomioną w tle systemu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-1263799343169335625?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6qgCGitzYXRyRReqRLbzdbrshpk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6qgCGitzYXRyRReqRLbzdbrshpk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6qgCGitzYXRyRReqRLbzdbrshpk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6qgCGitzYXRyRReqRLbzdbrshpk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/SZQLTWkKZLM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/1263799343169335625/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/11/lekcja-8-serwisy-w-androidzie.html#comment-form" title="Komentarze (8)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/1263799343169335625?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/1263799343169335625?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/SZQLTWkKZLM/lekcja-8-serwisy-w-androidzie.html" title="Lekcja 8. Serwisy w Androidzie. Bynajmniej nie informacyjne." /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_KGPcYjtmXgo/SwROnsAJhyI/AAAAAAAAAd0/penAeFvGxEE/s72-c/1.png" height="72" width="72" /><thr:total>8</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/11/lekcja-8-serwisy-w-androidzie.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMDQX4-cSp7ImA9WhZQEU0.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-3376584643500501422</id><published>2009-11-12T20:13:00.001+01:00</published><updated>2011-04-18T08:34:30.059+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-18T08:34:30.059+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AndroidManifest" /><category scheme="http://www.blogger.com/atom/ns#" term="InputStream" /><category scheme="http://www.blogger.com/atom/ns#" term="EditText" /><category scheme="http://www.blogger.com/atom/ns#" term="Toast" /><category scheme="http://www.blogger.com/atom/ns#" term="BufferReader" /><category scheme="http://www.blogger.com/atom/ns#" term="URLConnection" /><title>Lekcja 7. Pobieramy źródło strony WWW</title><content type="html">&lt;a href="http://1.bp.blogspot.com/_KGPcYjtmXgo/SvxhyQXR0EI/AAAAAAAAAdk/neVgDqK-SLo/s1600-h/2.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_KGPcYjtmXgo/SvxhyQXR0EI/AAAAAAAAAdk/neVgDqK-SLo/s200/2.gif" /&gt;&lt;/a&gt;Jakiś czas temu zmuszony byłem do "wyłuskania" pewnego fragmentu treści z kodu źródłowego pewnej strony. Jak się okazało nie było to bardzo skomplikowane, a moje początki z tym zagadnieniem są tematem lekcji którą czytasz.&lt;br /&gt;
&lt;br /&gt;
Stworzymy aplikację&amp;nbsp;dzięki&amp;nbsp;której będzie możliwe pobranie tytułu dowolnej strony. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Let combat begin&lt;/b&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black1 */
google_ad_slot = "5985861762";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
W pierwszej kolejności poproszę Cię o utworzenie View, które będzie zawierało jedno pole &lt;i&gt;EditText&lt;/i&gt; oraz jeden &lt;i&gt;Button&lt;/i&gt;.&lt;i&gt; &lt;/i&gt;W pole tekstowe wprowadzisz adres internetowy interesującej Cię strony, a przyciskiem wywołasz metodę parsującą stronę.&lt;br /&gt;
&lt;br /&gt;
Następnym krokiem jest dodanie pozwolenia aplikacji na dostęp do Internetu.&lt;br /&gt;
W tym celu w manifeście aplikacji powyżej tagu &lt;i&gt;application...&lt;/i&gt; dopisz poniższą linijkę:&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;uses-permission android:name="android.permission.INTERNET" /&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Ok. Teraz możesz uzupełnić główną klasę aplikacji o treść z poniższego listingu.&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
public class URLloader extends Activity {
    /** Called when the activity is first created. */
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
     
        Button button = (Button)findViewById(R.id.button);  
  
  button.setOnClickListener(new OnClickListener(){
   public void onClick(View view){
    
    EditText editText = (EditText)findViewById(R.id.editbox);
    CharSequence uri = editText.getText(); 
    
    Toast.makeText(getApplicationContext(), Parse(urlGet(String.valueOf(uri))), 10000).show();
   }
  });
        
    }
    
    private String urlGet(String urlString){
     
     URLConnection urlConnection = null;
        URL url = null;
        String string = null;
        
        try {
   url = new URL(urlString);
   urlConnection = url.openConnection();
   
   InputStream inputStream = urlConnection.getInputStream();
   InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
   BufferedReader reader = new BufferedReader(inputStreamReader);
   
      
   StringBuffer stringBuffer = new StringBuffer();
   
   while((string = reader.readLine()) != null){
    stringBuffer.append(string + "\n");
   }
   inputStream.close(); 
   
   string = stringBuffer.toString();
   
   
  } catch (MalformedURLException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }  
  
  return string;
    }
    
    private CharSequence Parse(String myString){      
     CharSequence title = myString.subSequence(myString.indexOf("&lt;title&gt;")+7,myString.indexOf("&lt;/title&gt;"));
     return title;
    }   
    
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Metoda &lt;i&gt;onCreate&lt;/i&gt; zawiera obsługę naszego jedynego przycisku w aplikacji, którego użycie powoduje wyzwolenie funkcji &lt;i&gt;Parse&lt;/i&gt;, która odpowiedzialna jest za wyszukanie w podanym stringu treści umieszczonej pomiędzy wskazanymi przez nas tagami. Wspomnianym stringiem jest wynik działania funkcji &lt;i&gt;urlGet&lt;/i&gt;, która za parametr przyjmuje adres WWW interesującej nas strony. Jest ona przy okazji najciekawszą częscią aplikacjji. To w niej dochodzi do utworzenia połączenia, zbufforowania strony, w konsekwencji umieszczenia "umieszczenia" jej w zmiennej typu String.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Koniec&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Efekt.Patrz niżej.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_KGPcYjtmXgo/Svxh2j3FGkI/AAAAAAAAAds/QLM3PO-05-8/s1600-h/p.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_KGPcYjtmXgo/Svxh2j3FGkI/AAAAAAAAAds/QLM3PO-05-8/s400/p.gif" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-3376584643500501422?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/d_4rxI08hy87rd1rsrxtM0SNDDg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/d_4rxI08hy87rd1rsrxtM0SNDDg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/d_4rxI08hy87rd1rsrxtM0SNDDg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/d_4rxI08hy87rd1rsrxtM0SNDDg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/J0z913Xs65g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/3376584643500501422/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/11/lekcja-7-pobieramy-zrodo-strony-www.html#comment-form" title="Komentarze (2)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3376584643500501422?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3376584643500501422?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/J0z913Xs65g/lekcja-7-pobieramy-zrodo-strony-www.html" title="Lekcja 7. Pobieramy źródło strony WWW" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_KGPcYjtmXgo/SvxhyQXR0EI/AAAAAAAAAdk/neVgDqK-SLo/s72-c/2.gif" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/11/lekcja-7-pobieramy-zrodo-strony-www.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QNSXc8eSp7ImA9WhZRFk4.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-2997336251611133034</id><published>2009-11-05T21:17:00.002+01:00</published><updated>2011-04-12T20:03:18.971+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-12T20:03:18.971+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NotificationManager" /><category scheme="http://www.blogger.com/atom/ns#" term="intents" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="PendingIntent" /><category scheme="http://www.blogger.com/atom/ns#" term="Notification" /><title>Lekcja 6. N jak Notification, czyli alfabetu ciąg dalszy.</title><content type="html">&lt;a href="http://4.bp.blogspot.com/_KGPcYjtmXgo/SvMwnAQavVI/AAAAAAAAAdc/HPViYqd2FqM/s1600-h/1.PNG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_KGPcYjtmXgo/SvMwnAQavVI/AAAAAAAAAdc/HPViYqd2FqM/s320/1.PNG" /&gt;&lt;/a&gt;Idąc za ciosem, a raczej za Intentami (patrz lekcja numer 5), chciałbym przedstawić kolejną aplikację korzystającą z tych jakże niezwykłych kreaturek, a przy okazji pokazać coś nowego, bez czego żaden system nie mógłby się obejść, czyli powiadomień użytkownika o wydarzeniach zachodzących w jego systemie.&lt;br /&gt;
&lt;br /&gt;
Notyfikacja. Po polskiemu powiadomienia. To one będę bohaterami poniższej lekcji.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Na początek trochę teorii.&lt;br /&gt;
&lt;br /&gt;
Powiadomienia w systemie Android zazwyczaj pojawiają się na pasku statusu (&lt;i&gt;status bar&lt;/i&gt;). To po pierwsze. Jednak ich możliwości na tym się nie kończą. Nie dość, że mamy możliwość "rozwinięcia" powiadomienia, to możemy dołączyć do niego dźwięk, alarm wibracyjny czy też migającą diodę LED.&lt;br /&gt;
&lt;br /&gt;
Ideą powiadomień jest to, że pojawiają się one bez naszej ingerencji, pochodzą od aplikacji/serwisów chodzących w tle. Np. poczta e-mail, sms itp.&lt;br /&gt;
&lt;br /&gt;
Jednak na potrzeby tej lekcji powiadomienie wywołamy sami, z okienka (&lt;i&gt;Activities&lt;/i&gt;), klikając na przycisk&lt;i&gt;.&lt;/i&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black */
google_ad_slot = "3801483932";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Lets get it started&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Celem aplikacji będzie wyświetlenie powiadomienia (komunikatu)&amp;nbsp;na pasku statusu, które będzie można rozwinąć, a następnie klikając w nie zostanie otwarta przeglądarka internetowa ze wskazaną przez nas stroną WWW.&lt;br /&gt;
&lt;br /&gt;
Do stworzenia powiadomienia wykorzystamy dwie klasy:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;i&gt;Notification &lt;/i&gt;-&amp;nbsp;odpowiedzialna &amp;nbsp;za to jak powiadomienie zostanie wyświetlone. Przykładowo jaka ikona zostanie wyświetlona pasku statusu, jaki dźwięk zostanie odtworzony, jakie View zostanie użyte po rozwinięciu paska statusu itd.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;NotificationManager &lt;/i&gt;- klasa do zarządzania powiadomieniami użytkownika o zdarzeniach w systemie. NotificationManager jest klasą, dla której nie można utworzyć jej instancji. W zamian tego używamy metody getSystemService(String) zwracającej do niej referencję. Parametrem tej metody jest jeden z systemowych serwisów, np. VIBRATOR_SERVICE (w przypadku chęci użycia takowego), WIFI_SERVICE itp. Nas interesuje NOTIFICATION_SERVICE.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Zwyczajowo zaczynamy od stworzenia View aplikacji. Tym razem nie będzie inaczej, z wyjątkiem, że sam(a) utworzysz odpowiednie view. Ważne, żeby zawierało przynajmniej jeden przycisk, który będzie odpowiedzialny za wywołanie powiadomienia.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Na tym etapie nie pozostaje nic więcej, jak zaprezentować źródło naszej aplikacji. &lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
 
 private NotificationManager notificationManager;
 private Notification notification;
 private int notificationId;
 
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        notification = new Notification(R.drawable.icon,"Hello",System.currentTimeMillis());
        
        Button start = (Button)findViewById(R.id.notifyButton);
        
        start.setOnClickListener(new OnClickListener(){
         public void onClick(View view){
          
          CharSequence titleText = "To jest tytuł powiadomienia!";
          CharSequence bodyText = "A to jest tekst po rozwienięciu!";
          
             Intent notIntent = new Intent(android.content.Intent.ACTION_VIEW,Uri.parse("http://www.google.com"));
          PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notIntent, 0);
          notification.setLatestEventInfo(getApplicationContext(),titleText,bodyText,contentIntent);
          notification.flags |= Notification.FLAG_AUTO_CANCEL;
          notificationManager.notify(notificationId, notification);
         }
        });
    }
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Przyjrzyjmy się mu bliżej.&lt;br /&gt;
&lt;br /&gt;
Pobieramy referencję do &lt;i&gt;NotificationManager&lt;/i&gt;&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Tworzymy instancję &lt;i&gt;Notification&lt;/i&gt;. Jako parametry przyjmuję ikonę jaka zostanie wyświetlona przy powiadomieniu po rozwinięciu, tekst jaki zostanie wyświetlony na pasku statusu oraz moment kiedy powiadomienie ma się pojawić.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
notification = new Notification(R.drawable.icon,"Hello",System.currentTimeMillis());
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Tworzymy obiekt typu &lt;i&gt;Intent&lt;/i&gt;. Uruchomi przeglądarkę, a następnie przejdzie na stronę o podanym adresie.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
Intent notIntent = new Intent(android.content.Intent.ACTION_VIEW,Uri.parse("http://www.google.com"));;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Tworzymy obiekt typu &lt;i&gt;PendingIntent&lt;/i&gt;. Umożliwia on przekazanie intentu do innej aktywności (Activities). Np. w naszym przypadku zostanie wywołany z powiadomienia.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notIntent, 0);
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Ustawiamy intent oraz teksty jakie mają się pojawić po wywołaniu powiadomienia.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
notification.setLatestEventInfo(getApplicationContext(),titleText,bodyText,contentIntent);
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Opcjonalnie można dodać flagi, w tym przypadku poniższa flaga powoduje automatyczne usunięcie powiadomienia po "wejściu w nie".&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
notification.flags |= Notification.FLAG_AUTO_CANCEL;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Ostatnim krokiem jest przekazanie (metoda &lt;i&gt;notify()&lt;/i&gt;) do &lt;i&gt;NotificationManagera&lt;/i&gt; naszego powiadomienia. Drugim parametrem jest unikalny dla całej aplikacji identyfikator naszej notyfikacji.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
notificationManager.notify(notificationId, notification);
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Koniec. Efekt - patrz niżej.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_KGPcYjtmXgo/SvMwjNkCetI/AAAAAAAAAdU/IUbOqd-Ll_c/s1600-h/2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_KGPcYjtmXgo/SvMwjNkCetI/AAAAAAAAAdU/IUbOqd-Ll_c/s320/2.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-2997336251611133034?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xKNuxWBjpUwtAzozhDces-DXRUc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xKNuxWBjpUwtAzozhDces-DXRUc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xKNuxWBjpUwtAzozhDces-DXRUc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xKNuxWBjpUwtAzozhDces-DXRUc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/sM2w6uJjJJI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/2997336251611133034/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/11/lekcja-6-n-jak-notificication-czyli.html#comment-form" title="Komentarze (4)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2997336251611133034?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/2997336251611133034?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/sM2w6uJjJJI/lekcja-6-n-jak-notificication-czyli.html" title="Lekcja 6. N jak Notification, czyli alfabetu ciąg dalszy." /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_KGPcYjtmXgo/SvMwnAQavVI/AAAAAAAAAdc/HPViYqd2FqM/s72-c/1.PNG" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/11/lekcja-6-n-jak-notificication-czyli.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQDRXw9cSp7ImA9WhZQEU0.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-6491301204848291323</id><published>2009-11-02T19:19:00.004+01:00</published><updated>2011-04-18T08:32:54.269+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-18T08:32:54.269+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="intents" /><category scheme="http://www.blogger.com/atom/ns#" term="onResult" /><category scheme="http://www.blogger.com/atom/ns#" term="onActivityResult" /><title>Lekcja 5. I jak Intents.</title><content type="html">Do tej pory prezentowane we wcześniejszych lekcjach aplikacje korzystały tylko z jednego widoku, z jednego okienka. Byłoby to idealne rozwiązanie z punktu widzenia wygody użytkownika, niestety głównym ograniczeniem są rozmiary ekranów urządzeń mobilnych. Dlatego też, dla zwiększenia przejrzystości, a także „upchnięcia” większej liczby opcji, a raczej ich ustawień dobrze jest wykorzystać dodatkowe widoki, otwierane w nowych oknach. Niby nic takiego, ale pojawia się problem komunikacji pomiędzy tymi okienkami, a dokładnie to przesyłania pomiędzy nimi danych.&lt;br /&gt;
W Javie Dalvik do realizacji tej funkcjonalności wykorzystujemy obiekty zwane Intents.&lt;br /&gt;
&lt;br /&gt;
Do dzieła!&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black1 */
google_ad_slot = "5985861762";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Tworzymy nowy projekt.&lt;br /&gt;
&lt;br /&gt;
W pierwszej kolejności edytujemy plik z wyglądem podstawowego okienka według poniższego schematu.&lt;br /&gt;
&lt;script class="brush: xml" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;" 
    &lt;TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="First Activity"/&gt;
    &lt;Button
        android:id="@+id/button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Press the button"/&gt;
&lt;/LinearLayout&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;main.xml&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Zawartość mam nadzieje jasna.&lt;br /&gt;
&lt;br /&gt;
Dodajemy nową klasę do naszego pakietu. Nazwijmy ją &lt;i&gt;SecondActivity&lt;/i&gt;, po czym chwilowo o niej zapomijmy.&lt;br /&gt;
&lt;br /&gt;
Skierujmy teraz nasze kroki do klasy &lt;i&gt;MainActivity&lt;/i&gt;.&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
public class MainActivity extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        // ToDo add your GUI initialization code here
        setContentView(R.layout.main);

        Button button = (Button)findViewById(R.id.button);

        button.setOnClickListener(new OnClickListener(){
            public void onClick(View arg1){
               Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
               startActivityForResult(intent,1337);              
            }
        });        
    }
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;MainActivity.class&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Uzupełniamy metodę &lt;i&gt;onCreate&lt;/i&gt;. To co nas interesuje, znajduje się wewnątrz metody onClick. W niej tworzymy nową instancję klasy Intent, jako parametry podajemy informacje o kontekście aplikacji oraz nazwę klasy z którą będziemy chcieli się komunikować. Następnie „wystartowujemy” nasz intent z możliwości zwrócenia rezultatów. Jako parametr podajemy referencję do stworzonego przez nas intentu, oraz unikalną liczbę identyfikującą konkretną „sesję”.&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black */
google_ad_slot = "3801483932";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
W tym miejscu przerywamy edycję plików związanych z pierwszym okienkiem, zajmując się drugim.&lt;br /&gt;
&lt;br /&gt;
Zwyczajowo zaczynamy od „naszkicowania” jego wyglądu. Nie możemy zrobić tego w pliku &lt;i&gt;main.xml&lt;/i&gt; gdzie zdefiniowany został wygląd pierwszego okienka. W związku z tym, tworzymy nowy plik xml  w katalogu &lt;i&gt;/res/layout&lt;/i&gt;, o nazwie np. &lt;i&gt;main_second.xml&lt;/i&gt;. Jego zawartość odpowiadać powinna poniższemu listingowi.&lt;br /&gt;
&lt;script class="brush: xml" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;"
    &lt;TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Second Activity"/&gt;
    &lt;EditText
        android:id="@+id/et_keyword"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/&gt;
    &lt;Button
        android:id="@+id/button_close"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Click to close these activity"/&gt;
&lt;/LinearLayout&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;MainSecond.xml&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Głównymi elementami tego okna jest pole wprowadzania/edycji tekstu (EditText) oraz przycisk.&lt;br /&gt;
&lt;br /&gt;
Uzupełniamy, wcześniej stworzoną przez nas klasę SecondActivity. &lt;br /&gt;
&lt;script class="brush: java; wrap-lines:false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
public class SecondActivity extends Activity {

    private EditText et_keyword;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle); 
        setContentView(R.layout.main_second);

        Button buttonClose = (Button)findViewById(R.id.button_close);

        buttonClose.setOnClickListener(new OnClickListener(){
            public void onClick(View arg2){
                     
                     EditText et_keyword =   (EditText)findViewById(R.id.et_keyword);                     
                     Intent data = new Intent();
                     
                     data.putExtra("result", et_keyword.getText().toString());
                     
                     SecondActivity.this.setResult(1, data);                     
                     SecondActivity.this.finish();
            }
        });
    }   
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;SecondActivity.class&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Wyjaśniam szybko co tu się dzieje. Otóż po kliknięciu przez użytkownika przycisku &lt;i&gt;button_close&lt;/i&gt;, wyzwalamy metodę &lt;i&gt;onClick&lt;/i&gt;, w której stworzony zostaje obiekty typu Intent. Przy pomocy metody &lt;i&gt;putExtra&lt;/i&gt; przypisujemy do zmiennej(?) result zawartość tekstu wprowadzonego w polu  &lt;i&gt;EditText&lt;/i&gt;. Następnie przekazujemy rezultaty (&lt;i&gt;setResult&lt;/i&gt;) do pierwszego okienka. Metoda &lt;i&gt;finish &lt;/i&gt;zamyka bieżące okno. &lt;br /&gt;
&lt;br /&gt;
W momencie wykonania metody finish, program powróci do naszego pierwszego okienka (MainActivity). Powróci z pewnymi danymi, które musimy jakoś odebrać. Z pomocą przychodzi  metoda &lt;i&gt;onActivityResult&lt;/i&gt;, która pozwoli nam przyjąć przesłana dane.&lt;br /&gt;
&lt;br /&gt;
Jej zawartość powinna przedstawiać się mniej więcej tak:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: java; wrap-lines:false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
@Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data ) {
          /* Place out code to react on Activity-Result here. */
          super.onActivityResult(requestCode, resultCode, data);
          if(requestCode == 1337){

              Toast tost = Toast.makeText(getApplicationContext(), data.getStringExtra("result"), 1000);
              tost.show();
          }
   }
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;MainActivity.class&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Jako, że metodą &lt;i&gt;onActivityResult &lt;/i&gt;odbierać może dane pochodzące z wielu okienek (activities), wykorzystujemy podany wcześniej identyfikator wywołania.&lt;br /&gt;
Do sprawdzenia poprawności działania komunikacji między oknami, wykorzystujemy obiekt Toast „dymek”.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Uwaga! Zwróćcie uwagę na wersję SDK Androida, bo coś mi się zdaje, ze na przestrzeni ewolucji wspomnianego sdk'a mieszali coś w Intentach.&lt;br /&gt;
&lt;b&gt;Powyższy przykład został zrealizowany przy wykorzystaniu SDK 1.6&lt;/b&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;i&gt;Ps.&lt;br /&gt;
Przez jakiś czas brakowało tu jednej ważnej informacji (której zapomniałem umieścić) o pewnej czynności, którą trzeba dodatkowo wykonać, aby aplikacja zadziała.&lt;br /&gt;
&lt;br /&gt;
Otóż, w powyższym tutorialu zabrakło wpisu informującego aplikację o istnieniu drugiego Aktywności (Activity). Co czynimy oczywiście Manifeście.&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;activity android:name=".SecondActivity"&gt;&lt;/activity&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Podziękowania za zwrócenie na to uwagi, możecie słać do kolegi &lt;b&gt;DrafFter'a ;)&lt;/b&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-6491301204848291323?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rfDQsTMUddHJwDZq6uSdzQRoKck/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rfDQsTMUddHJwDZq6uSdzQRoKck/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rfDQsTMUddHJwDZq6uSdzQRoKck/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rfDQsTMUddHJwDZq6uSdzQRoKck/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/Y3pk9RQ02v4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/6491301204848291323/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/11/lekcja-5-i-jak-intents.html#comment-form" title="Komentarze (11)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/6491301204848291323?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/6491301204848291323?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/Y3pk9RQ02v4/lekcja-5-i-jak-intents.html" title="Lekcja 5. I jak Intents." /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>11</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/11/lekcja-5-i-jak-intents.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUNQn49eSp7ImA9WhZQEU0.&quot;"><id>tag:blogger.com,1999:blog-2287699985177372445.post-3640047623901663101</id><published>2009-10-21T22:36:00.002+02:00</published><updated>2011-04-18T08:31:33.061+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-18T08:31:33.061+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="appWidgetProvider" /><category scheme="http://www.blogger.com/atom/ns#" term="AndroidManifest" /><category scheme="http://www.blogger.com/atom/ns#" term="onUpdate" /><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="widget" /><title>Lekcja 4. Pierwszy Widget, a w dodatku funkcjonalny !</title><content type="html">&lt;div class="separator" style="clear: both; text-align: left;"&gt;Wi..., Ga.. i inne dżety zadomowiły się już chyba na wszystkich systemach operacyjnych. Od dużych po małe. Oczywiście w Androidzie też ich nie zabrakło. Przyjrzyjmy się więc procesowi powstawania jednego z nich.&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_KGPcYjtmXgo/SwRV4ve6BQI/AAAAAAAAAd8/lOebfUAjn-Y/s1600/widget.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_KGPcYjtmXgo/SwRV4ve6BQI/AAAAAAAAAd8/lOebfUAjn-Y/s320/widget.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;Nasz pierwszy widget, będzie realizował pewną prostą acz przydatną czynność, mianowicie będzie informował nas o godzinach wschodów i zachodów słońca.&lt;br /&gt;
&lt;br /&gt;
Do dzieła!&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black1 */
google_ad_slot = "5985861762";
google_ad_width = 468;
google_ad_height = 60;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Część wizualna&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Tworzymy nowy projekt – tu  po staremu. Następnie, zgodnie z naszą tradycją przystępujemy do projektowania layoutu (main.xml).&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: xml" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&gt;
&lt;linearlayout xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;
    android:layout_width=&amp;quot;fill_parent&amp;quot;
    android:orientation=&amp;quot;vertical&amp;quot;
    android:layout_gravity=&amp;quot;center&amp;quot;
    android:background=&amp;quot;@drawable/ramka_black&amp;quot;
    android:layout_height=&amp;quot;wrap_content&amp;quot;&gt;

&lt;textview android:id=&amp;quot;@+id/widget_textview&amp;quot;
    android:text=&amp;quot;@string/widget_text&amp;quot;
    android:layout_height=&amp;quot;wrap_content&amp;quot;
    android:layout_width=&amp;quot;wrap_content&amp;quot;    
    android:layout_gravity=&amp;quot;center_horizontal|center&amp;quot;
    android:layout_marginTop=&amp;quot;5dip&amp;quot;
    android:padding=&amp;quot;10dip&amp;quot;
    android:textColor=&amp;quot;@android:color/white&amp;quot;/&gt;
&lt;/LinearLayout&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Jak widać, korzystamy tylko z jednego komponentu - TextView.&lt;br /&gt;
&lt;blockquote&gt;&lt;b&gt;UWAGA!&lt;/b&gt;&lt;br /&gt;
Być może część z Was zauważyła atrybut:background w tagu LinearLayout. Jest to tło naszego widgetu. Jednak najpierw musi ono znaleźć się w podanej lokalizacji, a dokładnie w katalogu &lt;i&gt;res/drawable/&lt;/i&gt;, który to trzeba najpierw stworzyć, poczym umieścić w nim poniższy plik tła (.png)&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://img14.imageshack.us/i/ramkablack.png/"&gt;&lt;img alt="Image Hosted by ImageShack.us" border="0" src="http://img14.imageshack.us/img14/3255/ramkablack.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Idziemy dalej. Edytujemy plik &lt;i&gt;strings.xml&lt;/i&gt; znajdujący się katalogu &lt;i&gt;Resources/values/&lt;/i&gt;. Uzupełniamy go o opisy nowych pól.&lt;br /&gt;
&lt;script class="brush: xml" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&gt;
&lt;resources&gt;
    &lt;string name=&amp;quot;widget_text&amp;quot;&gt;Hello Widget!&lt;/string&gt;
    &lt;string name=&amp;quot;app_name&amp;quot;&gt;Hello Widget&lt;/string&gt;
&lt;/resources&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Dochodzimy w tym miejscu do istotnego punktu, jakim jest poinformowanie Androida o tym, że będziemy tworzyli widget. Dlatego też otwieramy do edycji plik &lt;i&gt;AndroidManifest.xml&lt;/i&gt; znajdującym się w korzeniu projektu.&lt;br /&gt;
&lt;blockquote&gt;&lt;i&gt;AndroidManifest&lt;/i&gt; jest to plik w którym między innymi deklarujemy jaki typ aplikacji tworzymy, na dostęp do jakich elementów systemu/telefonu zezwalamy tworzonej aplikacji (np. do książki telefonicznej, danych z GPS), itp.&lt;br /&gt;
&lt;/blockquote&gt;Wracając do tematu, wygląd naszego, a raczej Androidowego Manifestu przedstawia się następująco:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: xml; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&gt;
&lt;manifest xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;
      package=&amp;quot;org.me.hellowidget&amp;quot;
      android:versionCode=&amp;quot;1&amp;quot;
      android:versionName=&amp;quot;1.0&amp;quot;&gt;
    &lt;application  android:label=&amp;quot;@string/app_name&amp;quot;&gt;
        &lt;!-- Broadcast Receiver that will process AppWidget updates --&gt;
        &lt;receiver android:name=&amp;quot;.Zachodnik&amp;quot; android:label=&amp;quot;@string/app_name&amp;quot;&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&amp;quot;android.appwidget.action.APPWIDGET_UPDATE&amp;quot; /&gt;
            &lt;/intent-filter&gt;
            &lt;meta-data android:name=&amp;quot;android.appwidget.provider&amp;quot; android:resource=&amp;quot;@xml/zachodnik_widget_provider&amp;quot; /&gt;
        &lt;/receiver&gt;
    &lt;/application&gt;
    &lt;uses-sdk android:minSdkVersion=&amp;quot;3&amp;quot; /&gt;
&lt;/manifest&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Ostatnim krokiem w projektowaniu i kodowaniu strony wizualnej jest edycja pliku &lt;i&gt;res/xml/zachodnik_widget_provider.xml&lt;/i&gt; (trzeba go utworzyć ręcznie), tak zwanego widget providera.&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: xml" type="syntaxhighlighter"&gt;
&lt;![CDATA[
&lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&gt;
&lt;appwidget-provider xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;
    android:minWidth=&amp;quot;146dip&amp;quot;
    android:minHeight=&amp;quot;72dip&amp;quot;
    android:updatePeriodMillis=&amp;quot;10000&amp;quot;
    android:initialLayout=&amp;quot;@layout/main&amp;quot;
/&gt;
]]&gt;
&lt;/script&gt;&lt;br /&gt;
W &lt;i&gt;widget providerze&lt;/i&gt; definiujemy podstawowe parametry widgetu, takie jak jego wymiary, czas podany w milisekundach co jaki widget ma się odświeżać. Dodatkowo mamy podany użyty layout – tu ważne jego nazwa musi być zgodna z nazwą naszego pliku z layoutem. Przypominam u  nas jest to main.xml.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Część logiczna&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Pierwszym krokiem jest utworzenie nowej klasy w pakiecie &lt;i&gt;org.me.zachodnik&lt;/i&gt;. Nazywamy ją &lt;i&gt;Zachodnik&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: java" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package org.me.zachodnik;
import android.appwidget.AppWidgetProvider;

public class Zachodnik extends AppWidgetProvider {

}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Ok. W tym momencie, możemy spróbować skompilować naszą aplikację.  Rezultatem powinien być widget wyświetlający napis &lt;i&gt;Hello World!&lt;/i&gt; Acha, oczywiście widget musimy najpierw umieścić na jednym z pulpitów Androida.&lt;br /&gt;
&lt;div style="text-align:center;"&gt;&lt;script type="text/javascript"&gt;
google_ad_client = "ca-pub-1501216205261683";
/* Hello black */
google_ad_slot = "3801483932";
google_ad_width = 300;
google_ad_height = 250;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Zrzutu ekranu na tym etapie nie przedstawiam, bo nie to nas interesuje.&lt;br /&gt;
&lt;br /&gt;
Długo myślałem… eee właściwie to nie długo ;) jakby „ufunkcjonalnić” nasz widget.  Wybór padł na implementacje algorytmu obliczającego godziny zachodów i wschodów słońca. Skorzystałem z algorytmu udostępnionego na stronie &lt;a href="http://cybermoon.w.interia.pl/"&gt;http://cybermoon.w.interia.pl/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Poniżej zamieszczam cały kod implementacji widgetu. Plik &lt;i&gt;Zachodnik.java&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: java; wrap-lines: false" type="syntaxhighlighter"&gt;
&lt;![CDATA[
package org.me.zachodnik;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.widget.RemoteViews;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import static java.lang.Math.*;



    public class Zachodnik extends AppWidgetProvider {
    private AppWidgetManager appWidgetManager;

        @Override
        public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            Timer timer = new Timer();          
            timer.scheduleAtFixedRate(new ZachodyWschody(context, appWidgetManager),100, 10000);

        }

        private class ZachodyWschody extends TimerTask{

            RemoteViews remoteViews;
            ComponentName thisWidget;
            AppWidgetManager appWidgetManager;            
            private double Wsch, Zach;

            public ZachodyWschody(Context context,AppWidgetManager appWidgetManager){
                this.appWidgetManager = appWidgetManager;
                remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
                thisWidget = new ComponentName(context, Zachodnik.class);                
            }

            public void algorytm(){

                Date data = new Date();

                int R =2009;// data.getYear();
                int M = 10; //data.getMonth();
                int D = 21;//data.getDay();

                double Long = 19; //dane dla Krakowa
                double Lat = 50;
                double Req = -0.833;
                double PI = 3.1415;

                double J = 367*R-(int)(7*(R+(int)((M+9)/12))/4)+(int)(275*M/9)+D-730531.5;
                double Cent = J/36525;
                double L = (4.8949504201433+628.331969753199*Cent) % 6.28318530718; //modulo
                double G = (6.2400408+628.3019501*Cent) % 6.28318530718;
                double O = 0.409093-0.0002269*Cent;
                double F = 0.033423 * sin(G) + 0.00034907 * sin(2*G);
                double E = 0.0430398 * sin(2*(L+F)) - 0.00092502 * sin(4*(L+F)) - F;
                double A = asin(sin(O) * sin(L+F));
                double C = (sin(0.017453293*Req)-sin(0.017453293*Lat)*sin(A)) / (cos(0.017453293*Lat)*cos(A));

                Wsch = (PI - (E+0.017453293*Long+1*acos(C)))*57.29577951/15;
                Zach = (PI - (E+0.017453293*Long+(-1)*acos(C)))*57.29577951/15;
                
                
            }

            @Override
            public void run(){
                algorytm();
                int godzWsch =  (int)Wsch;               
                int godzZach = (int)Zach;
                
                double minWsch = 60*(Wsch-godzWsch);
                double minZach = 60*(Zach-godzZach);
                
                godzWsch = godzWsch + 2; //przesuniec dla naszej strefy czasowej
                godzZach = godzZach + 2;
                

                String wsch = String.valueOf(godzWsch+":"+(int)minWsch);
                CharSequence w = (CharSequence)wsch;
                String zach = String.valueOf(godzZach+":"+(int)minZach);
                CharSequence z = (CharSequence)zach;
                
                remoteViews.setTextViewText(R.id.widget_textview, "Wschód: " + w + "\nZachód:" +  z );
                appWidgetManager.updateAppWidget(thisWidget, remoteViews);

            }
        }
    }
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Sam kod składa się właściwie tylko z metody &lt;i&gt;onUpdate&lt;/i&gt; oraz klasy &lt;i&gt;ZachodyWschody&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Metodę &lt;i&gt;onUpdate&lt;/i&gt; wykorzystujemy podczas tworzenia widgetów. Wywoływana jest w momencie dodania widgetu na pulpit. Odświeżana jest co określony czas,  zdefiniowany wcześniej w atrybucie &lt;i&gt;updatePeriodMilli&lt;/i&gt;. W przypadku naszej aplikacji rolą odświeżania przejmie obiekt typu &lt;i&gt;Timer&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Klasę  &lt;i&gt;ZachodyWschody&lt;/i&gt; na wstępie rozszerzamy o &lt;i&gt;TimerTask &lt;/i&gt;(niezbędne do użycia metody &lt;i&gt;scheduleAtFixedRate&lt;/i&gt;). Składa się ona z konstruktora, funkcji &lt;i&gt;algorytm&lt;/i&gt;() oraz metody run().&lt;br /&gt;
&lt;br /&gt;
Zastosowania elementów &lt;i&gt;RemoteView&lt;/i&gt;, &lt;i&gt;AppWidgetManager&lt;/i&gt; myślę, że można się domyśleć.&lt;br /&gt;
&lt;br /&gt;
Jeżeli kompilacja kodu przebiegła poprawnie, powinniśmy móc użyć naszego widgetu. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_KGPcYjtmXgo/SuDDbwb0KvI/AAAAAAAAAcc/eiVLk5Uk06w/s1600-h/lekcja4final.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_KGPcYjtmXgo/SuDDbwb0KvI/AAAAAAAAAcc/eiVLk5Uk06w/s400/lekcja4final.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2287699985177372445-3640047623901663101?l=www.helloandroid.pl' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/J46bL-DMsWKfMJOaFttjOmMwdW8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J46bL-DMsWKfMJOaFttjOmMwdW8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/J46bL-DMsWKfMJOaFttjOmMwdW8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J46bL-DMsWKfMJOaFttjOmMwdW8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgramowanieNa-androidablogspotpl/~4/dIYR9V96_LA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.helloandroid.pl/feeds/3640047623901663101/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.helloandroid.pl/2009/10/lekcja-4-pierwszy-widget-w-dodatku.html#comment-form" title="Komentarze (28)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3640047623901663101?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2287699985177372445/posts/default/3640047623901663101?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ProgramowanieNa-androidablogspotpl/~3/dIYR9V96_LA/lekcja-4-pierwszy-widget-w-dodatku.html" title="Lekcja 4. Pierwszy Widget, a w dodatku funkcjonalny !" /><author><name>Michał</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_KGPcYjtmXgo/SwRV4ve6BQI/AAAAAAAAAd8/lOebfUAjn-Y/s72-c/widget.PNG" height="72" width="72" /><thr:total>28</thr:total><feedburner:origLink>http://www.helloandroid.pl/2009/10/lekcja-4-pierwszy-widget-w-dodatku.html</feedburner:origLink></entry></feed>

