Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00370 007531 20703141 na godz. na dobę w sumie
Android. Receptury - książka
Android. Receptury - książka
Autor: Liczba stron: 616
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-6269-2 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie mobilne >> android
Porównaj ceny (książka, ebook, audiobook).

Sprawdzone rozwiązania dla programistów platformy Android!

Android jest obecnie najpopularniejszą platformą dla telefonów komórkowych i tabletów. Liczba aktywacji to setki tysięcy w ciągu jednego dnia. Skąd wzięła się ta popularność? Nie bez znaczenia są tu banalnie prosta integracja z serwisami społecznościowymi oraz ogromny wybór aplikacji i sprzętu, w którym można przebierać bez końca. Android jest również faworytem deweloperów oprogramowania. Dzięki temu, że platforma jest oparta o język Java, mogą oni błyskawicznie wykorzystać posiadaną wiedzę oraz znane narzędzia. Ta mieszanka jest skazana na sukces!

Książka, którą trzymasz w rękach, pomoże Ci odnieść sukces. Należy ona do ulubionej serii programistów - 'Receptury'. Znajdziesz tu najlepsze przepisy na rozwiązanie typowych problemów. W trakcie lektury nauczysz się błyskawicznie konfigurować środowisko pracy, tworzyć kopie zapasowe danych aplikacji oraz testować Twoje dzieło. Ponadto sprawdzisz, jak komunikować się między procesami, tworzyć zaawansowaną grafikę oraz wyświetlać materiały multimedialne. Przekonasz się również, jak łatwo uzyskać informacje z odbiornika GPS, sterować diodą LED w urządzeniu oraz przygotować aplikację do dystrybucji i sprzedaży. Książka ta powinna trafić w ręce wszystkich pasjonatów systemu Android!

Sięgnij po tę książkę i:

Wypróbuj najlepsze przepisy dla Androida!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: Android Cookbook Tłumaczenie: Tomasz Walczak ISBN: 978-83-246-6269-2 © 2013 Helion S.A. Authorized Polish translation of the English edition of Android Cookbook, 1st Edition, ISBN 9781449388416 © 2012 O’Reilly Media Inc. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Wydawnictwo HELION dołożyło wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie bierze jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Wydawnictwo HELION nie ponosi również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/andrec Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Pliki z przykładami omawianymi w książce można znaleźć pod adresem: ftp://ftp.helion.pl/przyklady/andrec.zip Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treļci Przedmowa ............................................................................................................................. 13 1. Podstawowe informacje .............................................................................................. 19 19 19 21 24 1.1. Wprowadzenie — podstawowe informacje 1.2. Nauka Javy 1.3. Tworzenie aplikacji „Witaj, Ĉwiecie” z poziomu wiersza poleceþ 1.4. Tworzenie aplikacji „Witaj, Ĉwiecie” w Ĉrodowisku Eclipse 1.5. Konfigurowanie Ĉrodowiska IDE w systemie Windows pod kñtem programowania aplikacji na Android 1.6. Cykl Ĕycia w Androidzie 1.7. Instalowanie plików .apk w emulatorze za pomocñ narzödzia ADB 1.8. Instalowanie aplikacji w emulatorze za pomocñ sklepu SlideME 1.9. WspóäuĔytkowanie klas Javy z innym projektem Ĉrodowiska Eclipse 1.10. Wskazywanie bibliotek z implementacjñ funkcji zewnötrznych 1.11. Wykorzystanie przykäadów z pakietu SDK do uäatwienia sobie pracy 1.12. Aktualizowanie pakietu SDK Androida 1.13. Wykonywanie zrzutów w emulatorze i urzñdzeniu z Androidem 1.14. Prosty przykäadowy program do odliczania wstecznego 1.15. Program Tipster — kalkulator napiwków na Android 29 35 36 38 39 41 43 46 52 55 57 2. Projektowanie udanych aplikacji .................................................................................73 73 76 79 81 83 84 2.1. Wprowadzenie — projektowanie udanych aplikacji na Android 2.2. Obsäuga wyjñtków 2.3. Obiekt Application w Androidzie jako singleton 2.4. Zachowywanie danych po zmianie orientacji ekranu 2.5. Monitorowanie poziomu baterii w urzñdzeniach z Androidem 2.6. Tworzenie ekranów powitalnych w Androidzie 2.7. Projektowanie aplikacji na potrzeby konferencji, BarCampu, hackathonu lub instytucji 2.8. Wykorzystanie narzödzia Google Analytics w aplikacjach na Android 88 90 5 2.9. Prosta latarka 2.10. Dostosowywanie aplikacji na telefony z Androidem do tabletów 2.11. Preferencje obowiñzujñce przy pierwszym uruchomieniu aplikacji 2.12. Formatowanie czasu i daty na potrzeby wyĈwietlania 2.13. Kontrolowanie danych wejĈciowych za pomocñ odbiorników KeyListener 2.14. Tworzenie kopii zapasowej danych aplikacji na Android 2.15. Stosowanie wskazówek zamiast okien podpowiedzi 92 94 95 97 99 102 108 3. Testy ............................................................................................................................. 111 111 111 112 121 122 125 128 3.1. Wprowadzenie — testy 3.2. Programowanie sterowane testami w Androidzie 3.3. Konfigurowanie urzñdzeþ AVD na potrzeby testowania aplikacji 3.4. Testowanie aplikacji w wielu urzñdzeniach za pomocñ chmury 3.5. Tworzenie i stosowanie projektu testowego 3.6. Rozwiñzywanie problemów z awariami aplikacji 3.7. Debugowanie z wykorzystaniem instrukcji Log.d i okna LogCat 3.8. Automatyczne otrzymywanie raportów o bäödach od uĔytkowników za pomocñ mechanizmu BugSense 3.9. Korzystanie z lokalnego dziennika czasu wykonania do analizowania bäödów i innych sytuacji 3.10. Odtwarzanie scenariuszy cyklu Ĕycia aktywnoĈci na potrzeby testów 3.11. Rozwijanie päynnie dziaäajñcych aplikacji za pomocñ narzödzia StrictMode 3.12. Korzystanie z programu Monkey 3.13. Wysyäanie komunikatów tekstowych i przekazywanie wywoäaþ miödzy urzñdzeniami AVD 129 131 134 139 140 142 4. Komunikacja wewnétrz- i miýdzyprocesowa .......................................................... 145 145 4.1. Wprowadzenie — komunikacja wewnñtrz- i miödzyprocesowa 4.2. Obsäugiwanie strony internetowej, numeru telefonu lub innych elementów za pomocñ intencji 4.3. Wysyäanie e-maili z poziomu widoku 4.4. Wysyäanie e-maili z zaäñcznikami 4.5. Przekazywanie äaþcuchów znaków za pomocñ instrukcji Intent.putExtra() 4.6. Pobieranie danych z aktywnoĈci podrzödnej do aktywnoĈci gäównej 4.7. Podtrzymywanie dziaäania usäugi w trakcie wyĈwietlania innych aplikacji 4.8. Wysyäanie i odbieranie komunikatów rozgäoszeniowych 4.9. Uruchamianie usäugi po ponownym uruchomieniu urzñdzenia 4.10. UĔywanie wñtków do tworzenia szybko reagujñcych aplikacji 4.11. Korzystanie z klasy AsyncTask do wykonywania operacji w tle 4.12. Przesyäanie komunikatów miödzy wñtkami za pomocñ kolejki wñtków aktywnoĈci i komponentu obsäugi 6 _ Spis treļci 146 147 150 151 152 155 157 158 159 160 166 4.13. Tworzenie androidowej wersji kalendarza Epoch (napisanego w HTML-u i JavaScripcie) 168 5. Dostawcy treļci ............................................................................................................175 175 175 177 179 5.1. Wprowadzenie — dostawcy treĈci 5.2. Pobieranie danych z dostawcy treĈci 5.3. Pisanie dostawcy treĈci 5.4. Pisanie zdalnej usäugi na Android 6. Grafika ......................................................................................................................... 185 185 185 6.1. Wprowadzenie — grafika 6.2. Stosowanie niestandardowej czcionki 6.3. WyĈwietlanie obracajñcego siö szeĈcianu za pomocñ specyfikacji OpenGL ES 6.4. Sterowanie obracajñcym siö szeĈcianem 6.5. Odröczne rysowanie päynnych linii 6.6. Robienie zdjöè za pomocñ intencji 6.7. Robienie zdjöè za pomocñ klasy android.media.Camera 6.8. Skanowanie kodu kreskowego lub kodu QR za pomocñ programu Google ZXing 6.9. WyĈwietlanie diagramów i wykresów za pomocñ klasy AndroidPlot 6.10. Tworzenie ikony do androidowego launchera za pomocñ programu Inkscape 6.11. ãatwe tworzenie ikon do launchera za pomocñ programu Paint.NET i grafik z serwisu OpenClipArt.org 6.12. Korzystanie z plików NinePatch 6.13. Tworzenie wykresów na strony HTML5 za pomocñ biblioteki RGraph 6.14. Dodawanie prostej animacji rastrowej 6.15. PrzybliĔanie obrazu za pomocñ gestów dotykowych 187 191 194 198 200 204 207 208 215 221 224 228 230 236 238 241 242 246 249 251 253 254 7. Graficzny interfejs uŜytkownika ...............................................................................235 235 7.1. Wprowadzenie — interfejs GUI 7.2. Poznawanie i przestrzeganie wytycznych tworzenia interfejsu uĔytkownika 7.3. Obsäuga zmian konfiguracji przez oddzielenie widoku od modelu 7.4. Tworzenie przycisku i odbiornika klikniöè 7.5. Piöè sposobów na doäñczanie odbiornika zdarzeþ 7.6. Stosowanie kontrolek CheckBox i RadioButton 7.7. Wzbogacanie projektu interfejsu uĔytkownika za pomocñ przycisków graficznych 7.8. Udostöpnianie listy rozwijanej z opcjami za pomocñ klasy Spinner 7.9. Obsäuga däugiego klikniöcia 7.10. WyĈwietlanie pól tekstowych TextView i EditText Spis treļci _ 7 7.11. Ograniczanie wartoĈci pola EditText za pomocñ atrybutów oraz interfejsu TextWatcher 7.12. Kontrolka AutoCompleteTextView 7.13. Zapeänianie kontrolki AutoCompleteTextView za pomocñ zapytaþ do bazy SQLite 7.14. Przeksztaäcanie pól tekstowych w pola na hasäo 7.15. Zmiana klawisza Enter na Next na klawiaturze programowej 7.16. Obsäuga w aktywnoĈci zdarzeþ zwiñzanych z klawiszami 7.17. PokaĔ im gwiazdy — kontrolka RatingBar 7.18. Drgajñcy widok 7.19. WyĈwietlanie dotykowych informacji zwrotnych 7.20. Przeäñczanie siö miödzy róĔnymi aktywnoĈciami w widoku TabView 7.21. Tworzenie niestandardowego paska tytuäu 7.22. Formatowanie liczb 7.23. Poprawne stosowanie liczby mnogiej 7.24. WyĈwietlanie drugiego ekranu z poziomu pierwszego 7.25. Tworzenie ekranu wczytywania, wyĈwietlanego przy przeäñczaniu aktywnoĈci 7.26. Zakrywanie innych komponentów za pomocñ klasy SlidingDrawer 7.27. Otwieranie komponentu SlidingDrawer od góry do doäu 7.28. Dodawanie do ukäadu obramowania z zaokrñglonymi rogami 7.29. Wykrywanie gestów w Androidzie 7.30. Tworzenie interfejsu uĔytkownika w Androidzie 1.6 i nowszych wersjach za pomocñ fragmentów z Androida 3.0 7.31. Korzystanie z galerii zdjöè w Androidzie 3.0 7.32. Tworzenie prostego widĔetu aplikacji 255 257 259 260 261 264 265 268 270 273 275 277 281 283 291 292 295 296 299 305 308 311 8. Alerty w interfejsach GUI — menu, okna dialogowe, komunikaty toast i powiadomienia ......................................................................................................... 315 315 316 317 318 321 322 8.1. Wprowadzenie — alerty w interfejsach GUI 8.2. Tworzenie i wyĈwietlanie menu 8.3. Obsäuga wyboru opcji menu 8.4. Tworzenie podmenu 8.5. Tworzenie wyskakujñcych okien dialogowych (okien z alertami) 8.6. Kontrolka Timepicker 8.7. Tworzenie obrotowego mechanizmu wybierania (podobnego do tego z iPhone’ów) 8.8. Tworzenie okna dialogowego z zakäadkami 8.9. Tworzenie okna ProgressDialog 8.10. Tworzenie niestandardowego okna dialogowego z przyciskami, rysunkami i tekstem 8.11. Klasa AboutBox do wielokrotnego uĔytku 325 327 330 331 333 8 _ Spis treļci 8.12. Modyfikowanie wyglñdu komunikatów toast 8.13. Tworzenie powiadomienia wyĈwietlanego na pasku stanu 336 337 9. GUI — kontrolka ListView ..........................................................................................343 343 343 347 349 352 356 357 9.1. Wprowadzenie — kontrolka ListView 9.2. UĔywanie kontrolki ListView do tworzenia aplikacji opartych na listach 9.3. Tworzenie widoków „brak danych” dla kontrolek ListView 9.4. Tworzenie zaawansowanych kontrolek ListView z rysunkami i tekstem 9.5. Stosowanie nagäówków sekcji w kontrolkach ListView 9.6. Zachowywanie pozycji w kontrolce ListView 9.7. Niestandardowy adapter listy 9.8. Obsäuga zmian orientacji — od wartoĈci z kontrolki ListView po wykresy w orientacji poziomej 360 10. Multimedia ..................................................................................................................367 367 367 368 371 373 376 378 380 381 10.1. Wprowadzenie — multimedia 10.2. Odtwarzanie filmów z serwisu YouTube 10.3. UĔywanie obiektu Gallery wraz z kontrolkñ ImageSwitcher 10.4. Rejestrowanie filmów za pomocñ klasy MediaRecorder 10.5. Jak wykorzystaè androidowy mechanizm wykrywania twarzy? 10.6. Odtwarzanie muzyki z pliku 10.7. Odtwarzanie dĒwiöku bez interakcji z uĔytkownikiem 10.8. Konwersja mowy na tekst 10.9. Konwersja tekstu na mowö 11. Utrwalanie danych .....................................................................................................383 383 383 386 387 390 11.1. Wprowadzenie — utrwalanie danych 11.2. Pobieranie informacji o plikach 11.3. Wczytywanie plików z aplikacji, a nie z systemu plików 11.4. WyĈwietlanie zawartoĈci katalogu 11.5. OkreĈlanie äñcznej iloĈci pamiöci oraz iloĈci wolnego miejsca na karcie SD 11.6. Prosty sposób tworzenia aktywnoĈci do ustawiania preferencji uĔytkownika 11.7. Sprawdzanie poprawnoĈci ustawieþ 11.8. Zaawansowane wyszukiwanie tekstu 11.9. Tworzenie bazy SQLite w aplikacji na Android 11.10. Wstawianie danych do bazy SQLite 11.11. Wczytywanie wartoĈci z istniejñcej bazy SQLite 11.12. Praca z datami w bazie SQLite 11.13. Przetwarzanie danych w formacie JSON za pomocñ klasy JSONObject 11.14. Przetwarzanie dokumentów XML za pomocñ interfejsu DOM API 11.15. Przetwarzanie dokumentów w formacie XML z wykorzystaniem interfejsu XmlPullParser 390 394 396 401 402 402 403 406 407 409 Spis treļci _ 9 11.16. Dodawanie danych kontaktowych 11.17. Wczytywanie danych kontaktowych 412 415 12. Aplikacje do obsĥugi poĥéczeħ telefonicznych .......................................................... 417 417 418 421 424 425 428 12.1. Wprowadzenie — aplikacje do obsäugi poäñczeþ telefonicznych 12.2. Wykonywanie operacji w momencie, gdy dzwoni telefon 12.3. Przetwarzanie wychodzñcych poäñczeþ telefonicznych 12.4. Wybieranie numeru telefonu 12.5. Wysyäanie jedno- lub wieloczöĈciowych wiadomoĈci SMS 12.6. Odbieranie wiadomoĈci SMS w aplikacjach na Android 12.7. Wysyäanie wiadomoĈci SMS do emulatora za pomocñ okna Emulator Control 12.8. Korzystanie z androidowej klasy TelephonyManager do pobierania informacji o urzñdzeniu 429 430 13. Aplikacje sieciowe ......................................................................................................441 441 442 13.1. Wprowadzenie — sieè 13.2. Stosowanie usäug sieciowych typu RESTful 13.3. UĔywanie wyraĔeþ regularnych do wyodröbniania informacji z nieustrukturyzowanego tekstu 13.4. Przetwarzanie danych z kanaäów RSS i Atom za pomocñ parsera ROME 13.5. Korzystanie ze skrótów MD5 do przetwarzania zwykäego tekstu 13.6. Przeksztaäcanie tekstu na odnoĈniki 13.7. Dostöp do stron internetowych za pomocñ kontrolki WebView 13.8. Modyfikowanie wyglñdu kontrolki WebView 444 446 450 451 452 453 14. Gry i animacje .............................................................................................................455 455 456 14.1. Wprowadzenie — gry i animacje 14.2. Tworzenie gier na Android za pomocñ frameworku flixel-android 14.3. Tworzenie gry na Android za pomocñ narzödzia AndEngine (Android-Engine) 14.4. Przetwarzanie danych wejĈciowych wprowadzonych w okreĈlonym czasie 458 464 15. Sieci spoĥecznoļciowe ................................................................................................467 467 15.1. Wprowadzenie — sieci spoäecznoĈciowe 15.2. Integrowanie aplikacji z sieciami spoäecznoĈciowymi za pomocñ protokoäu HTTP 15.3. Wczytywanie chronologicznych list tweetów za pomocñ formatu JSON 467 470 16. Lokalizacja i mapy .......................................................................................................473 473 473 475 16.1. Wprowadzenie — aplikacje wykorzystujñce lokalizacjö 16.2. Pobieranie danych o lokalizacji 16.3. Dostöp do danych z GPS-a w aplikacjach 10 _ Spis treļci 16.4. Podawanie fikcyjnych wspóärzödnych GPS w urzñdzeniu 16.5. Geokodowanie i geokodowanie odwrotne 16.6. Przygotowania do korzystania z map Google’a 16.7. WyĈwietlanie aktualnej lokalizacji urzñdzenia na mapach Google’a 16.8. WyĈwietlanie znacznika lokalizacji w widoku MapView 16.9. WyĈwietlanie kilku znaczników w widoku MapView 16.10. Tworzenie warstw dla widoku MapView 16.11. Zmienianie trybów widoku MapView 16.12. WyĈwietlanie ikony na warstwie bez korzystania z obiektów Drawable 16.13. Implementowanie wyszukiwania lokalizacji na mapach Google’a 16.14. WyĈwietlanie widoku MapView w kontrolce TabView 16.15. Obsäuga däugich klikniöè w widokach MapView 16.16. Korzystanie z map OpenStreetMap 16.17. Tworzenie warstw dla map OSM 16.18. Stosowanie skali w mapach OSM 16.19. Obsäuga dotkniöè warstwy mapy OSM 16.20. Aktualizowanie lokalizacji na mapach OSM 477 479 480 486 487 490 495 496 497 501 503 505 509 511 513 514 516 17. Akcelerometr .............................................................................................................. 521 521 521 17.1. Wprowadzenie — czujniki 17.2. Wykrywanie obecnoĈci lub braku czujnika 17.3. Wykorzystywanie akcelerometru do wykrywania potrzñsania urzñdzeniem 17.4. UĔywanie akcelerometru do sprawdzania, czy ekran skierowany jest w dóä, czy w górö 17.5. OkreĈlanie uäoĔenia telefonu z Androidem za pomocñ czujnika orientacji 17.6. Odczyt wskazaþ czujnika temperatury 522 526 527 528 18. Bluetooth .................................................................................................................... 531 531 532 533 536 537 18.1. Wprowadzenie — Bluetooth 18.2. Wäñczanie Bluetootha i umoĔliwianie wykrywania urzñdzenia 18.3. Podäñczanie urzñdzenia z Bluetoothem 18.4. Oczekiwanie na Ĕñdania poäñczenia Bluetooth oraz ich akceptowanie 18.5. Implementowanie wykrywania urzñdzeþ z Bluetoothem 19. Sterowanie systemem i urzédzeniem ........................................................................539 539 539 540 541 542 544 19.1. Wprowadzenie — sterowanie systemem i urzñdzeniem 19.2. Dostöp do informacji o sieci i poäñczeniu 19.3. Pobieranie informacji z pliku manifestu 19.4. Zmienianie trybu dzwonka telefonu na cichy, wibracje lub normalny 19.5. Kopiowanie tekstu i pobieranie go ze schowka 19.6. Powiadomienia oparte na diodach LED Spis treļci _ 11 19.7. Wäñczanie wibracji w urzñdzeniu 19.8. Uruchamianie poleceþ powäoki z poziomu aplikacji 19.9. OkreĈlanie, czy dana aplikacja jest uruchomiona 544 545 546 20. Inne jýzyki programowania i frameworki .................................................................549 549 550 20.1. Wprowadzenie — inne jözyki programowania 20.2. Uruchamianie zewnötrznych, natywnych instrukcji Uniksa i Linuksa 20.3. Uruchamianie kodu natywnego w jözyku C lub C++ za pomocñ interfejsu JNI z pakietu NDK 20.4. Wprowadzenie do aplikacji Scripting Layer for Android (SL4A; wczeĈniej Android Scripting Environment) 20.5. Tworzenie alertów za pomocñ biblioteki SL4A 20.6. Pobieranie dokumentów Google i wyĈwietlanie ich w kontrolce ListView za pomocñ biblioteki SL4A 20.7. UĔywanie kodów QR do rozpowszechniania skryptów SL4A 20.8. UĔywanie JavaScriptu do wykorzystania wbudowanych funkcji telefonu poprzez kontrolkö WebView 20.9. Tworzenie aplikacji niezaleĔnych od platformy za pomocñ frameworku PhoneGap 551 556 558 562 563 566 568 21. Ĥaħcuchy znaków i internacjonalizacja ......................................................................571 571 572 575 577 21.1. Wprowadzenie — internacjonalizacja 21.2. Internacjonalizacja tekstu aplikacji 21.3. Wyszukiwanie i täumaczenie äaþcuchów znaków 21.4. Niuanse zwiñzane z plikami strings.xml 22. Tworzenie pakietów, instalowanie, dystrybucja i sprzedaŜ aplikacji .....................583 583 583 586 587 588 592 595 Skorowidz .............................................................................................................................599 22.1. Wprowadzenie — tworzenie pakietów, instalowanie i dystrybucja 22.2. Tworzenie certyfikatu uĔywanego przy podpisywaniu 22.3. Podpisywanie aplikacji 22.4. Udostöpnianie aplikacji w sklepie Google Play (dawny Android Market) 22.5. Integrowanie sieci AdMob z aplikacjñ 22.6. Zaciemnianie i optymalizowanie kodu za pomocñ ProGuarda 22.7. OdnoĈniki do aplikacji ze sklepu Google Play 12 _ Spis treļci ROZDZIAĤ 10. Multimedia 10.1. Wprowadzenie — multimedia Ian Darwin Omówienie Android to Ĉrodowisko multimedialne. Standardowo obejmuje odtwarzacze muzyki i filmów, a wiökszoĈè komercyjnych urzñdzeþ obok domyĈlnych narzödzi obejmuje teĔ ich bardziej wymyĈlne odpowiedniki, a takĔe odtwarzacze filmów z serwisu YouTube i inne podobne aplikacje. Z receptur z tego rozdziaäu dowiesz siö, jak sterowaè wybranymi aspektami Ĉwiata multimediów w Androidzie. 10.2. Odtwarzanie filmów z serwisu YouTube Marco Dinacci Problem Programista chce w urzñdzeniu umoĔliwiè odtwarzanie filmów z serwisu YouTube. Rozwiézanie Na podstawie identyfikatora URI filmu naleĔy utworzyè obiekt Intent z akcjñ ACTION_VIEW i uruchomiè nowñ aktywnoĈè. Omówienie Na listingu 10.1 pokazano kod potrzebny do uruchomienia filmu z serwisu YouTube za po- mocñ intencji. 367 Aby kod z tej receptury zadziaäaä, w urzñdzeniu uĔytkownika musi byè zainstalowa- na standardowa aplikacja YouTube. Listing 10.1. Uruchamianie filmu z serwisu YouTube za pomocñ intencji public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String video_path = http://www.youtube.com/watch?v=opZ69P-0Jbc ; Uri uri = Uri.parse(video_path); // Ten wiersz powoduje natychmiastowe uruchomienie aplikacji YouTube (jeĞli jest // zainstalowana). JeĪeli usuniesz ten wiersz, uĪytkownik zobaczy listĊ aplikacji // do wyboru. uri = Uri.parse( vnd.youtube: + uri.getQueryParameter( v )); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); } W przykäadzie podano standardowy adres URL filmu z serwisu YouTube.com. Czäon uri.get QueryParameter( v ) säuĔy do okreĈlania identyfikatora filmu na podstawie identyfikatora URI. W przykäadzie identyfikator filmu to opZ69P-0Jbc. 10.3. UŜywanie obiektu Gallery wraz z kontrolké ImageSwitcher Nidhin Jose Davis Problem Programista chce utworzyè interfejs uĔytkownika do przeglñdania kolekcji rysunków. Rozwiézanie PoĔñdany efekt moĔna uzyskaè dziöki zastosowaniu obiektu Gallery wraz z kontrolkñ Image Switcher. Omówienie MoĔna wykorzystaè obiekt Gallery (android.widget.Gallery) i kontrolkö ImageSwitcher (android. widget.ImageSwitcher) do utworzenia eleganckiej przeglñdarki rysunków. Na listingu 10.2 po- kazano ukäad dla obiektu Gallery. Listing 10.2. Ukäad dla obiektu Gallery ?xml version= 1.0 encoding= utf-8 ? RelativeLayout xmlns:android= http://schemas.android.com/apk/res/android android:orientation= vertical 368 _ Rozdziaĥ 10. Multimedia android:layout_width= fill_parent android:layout_height= fill_parent ImageSwitcher android:id= @+id/switcher android:layout_width= fill_parent android:layout_height= wrap_content android:layout_alignParentLeft= true android:layout_alignParentRight= true android:layout_alignParentBottom= true / Gallery android:id= @+id/gallery android:background= #55000000 android:layout_width= fill_parent android:layout_height= 60dip android:spacing= 16px android:layout_alignParentBottom= true android:layout_alignParentLeft= true android:gravity= center_vertical / /RelativeLayout Na listingu 10.3 pokazano, jak wykorzystaè ten ukäad. Listing 10.3. Gäówna aktywnoĈè ImageBrowser z przykäadu z galeriñ public class ImageBrowser extends Activity implements AdapterView.OnItemSelectedListener, ViewSwitcher.ViewFactory { private ImageSwitcher mISwitcher; private ArrayList Drawable allimages = new ArrayList Drawable (); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Usuwanie paska tytuáu requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); getImages(); mISwitcher = (ImageSwitcher)findViewById(R.id.switcher); mISwitcher.setFactory(this); // Animacja przy przeáączaniu rysunków mISwitcher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); mISwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out)); Gallery gallery = (Gallery) findViewById(R.id.gallery); gallery.setAdapter(new ImageAdapter(this)); gallery.setOnItemSelectedListener(this); } private void getImages() { allimages.add(this.getResources().getDrawable(R.drawable.image1)); allimages.add(this.getResources().getDrawable(R.drawable.image2)); allimages.add(this.getResources().getDrawable(R.drawable.image3)); allimages.add(this.getResources().getDrawable(R.drawable.image4)); allimages.add(this.getResources().getDrawable(R.drawable.image5)); 10.3. UŜywanie obiektu Gallery wraz z kontrolké ImageSwitcher _ 369 allimages.add(this.getResources().getDrawable(R.drawable.image6)); allimages.add(this.getResources().getDrawable(R.drawable.image7)); allimages.add(this.getResources().getDrawable(R.drawable.image8)); allimages.add(this.getResources().getDrawable(R.drawable.image9)); } @Override public void onItemSelected(AdapterView ? arg0, View v, int position, long id) { try{ mISwitcher.setImageDrawable(allimages.get(position)); }catch(Exception e){} } @Override public void onNothingSelected(AdapterView ? arg0) { // Pusta } @Override public View makeView() { ImageView i = new ImageView(this); i.setBackgroundColor(0xFF000000); i.setScaleType(ImageView.ScaleType.FIT_CENTER); i.setLayoutParams(new ImageSwitcher.LayoutParams( ImageSwitcher.LayoutParams.FILL_PARENT, ImageSwitcher.LayoutParams.FILL_PARENT)); return i; } public class ImageAdapter extends BaseAdapter { private Context mContext; public ImageAdapter(Context c) { mContext = c; } public int getCount() { return allimages.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { ImageView galleryview = new ImageView(mContext); galleryview.setImageDrawable(allimages.get(position)); galleryview.setAdjustViewBounds(true); galleryview.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); galleryview.setPadding(5, 0, 5, 0); galleryview.setBackgroundResource(android.R.drawable.picture_frame); return galleryview; } } } 370 _ Rozdziaĥ 10. Multimedia 10.4. Rejestrowanie filmów za pomocé klasy MediaRecorder Marco Dinacci Problem Programista chce za pomocñ wbudowanej kamery rejestrowaè filmy i zapisywaè je na dysku. Rozwiézanie NaleĔy zarejestrowaè film i zapisaè go w telefonie za pomocñ klasy MediaRecorder z framewor- ku Androida. Omówienie Do nagrywania dĒwiöku i filmów säuĔy klasa MediaRecorder. Klasa ta ma prosty interfejs API, poniewaĔ jednak oparta jest na prostej maszynie stanowej, metody trzeba wywoäywaè w okre- Ĉlonej kolejnoĈci, tak aby uniknñè wystñpienia wyjñtku IllegalStateException. Utwórz nowñ aktywnoĈè i przesäoþ metodö onCreate za pomocñ kodu z listingu 10.4. Listing 10.4. Metoda onCreate() z gäównej aktywnoĈci @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.media_recorder_recipe); // Film naleĪy nagrywaü w orientacji poziomej setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView); mHolder = mSurfaceView.getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mToggleButton = (ToggleButton) findViewById(R.id.toggleRecordingButton); mToggleButton.setOnClickListener(new OnClickListener() { @Override // Rozpoczynanie i wstrzymywanie nagrywania filmu public void onClick(View v) { if (((ToggleButton)v).isChecked()) mMediaRecorder.start(); else { mMediaRecorder.stop(); mMediaRecorder.reset(); try { initRecorder(mHolder.getSurface()); } catch (IOException e) { e.printStackTrace(); } } } }); } 10.4. Rejestrowanie filmów za pomocé klasy MediaRecorder _ 371 Klatki z podglñdem filmu sñ wyĈwietlane w widoku SurfaceView. Do sterowania nagrywaniem säuĔy przycisk, który pozwala rozpoczñè i wstrzymaè rejestrowanie. Po zakoþczeniu nagrywa- nia naleĔy zatrzymaè pracö obiektu MediaRecorder. PoniewaĔ metoda stop resetuje stan wszyst- kich zmiennych maszyny stanowej, wiöc aby móc rozpoczñè rejestrowanie nastöpnego filmu, naleĔy zresetowaè maszynö stanowñ i jeszcze raz wywoäaè metodö initRecorder. W metodzie initRecorder aplikacja konfiguruje obiekt MediaRecorder oraz aparat, co pokazano na listingu 10.5. Listing 10.5. Konfigurowanie obiektu MediaRecorder /* Inicjowanie obiektu MediaRecorder. Aby obiekt dziaáaá poprawnie, metody * trzeba wywoáywaü w odpowiedniej kolejnoĞci */ private void initRecorder(Surface surface) throws IOException { // Bardzo waĪne jest, aby przed wywoáaniem metody setCamera odblokowaü aparat. // W przeciwnym razie podgląd bĊdzie niewidoczny if(mCamera == null) { mCamera = Camera.open(); mCamera.unlock(); } if(mMediaRecorder == null) mMediaRecorder = new MediaRecorder(); mMediaRecorder.setPreviewDisplay(surface); mMediaRecorder.setCamera(mCamera); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); File file = createFile(); mMediaRecorder.setOutputFile(file.getAbsolutePath()); // Bez ograniczeĔ. Nie zapomnij sprawdziü, ile wolnej pamiĊci jest na dysku mMediaRecorder.setMaxDuration(-1); mMediaRecorder.setVideoFrameRate(15); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); try { mMediaRecorder.prepare(); } catch (IllegalStateException e) { // Zgáaszany, jeĞli poprzednie metody nie zostaáy wywoáane w odpowiedniej // kolejnoĞci e.printStackTrace(); } mInitSuccesful = true; } WaĔne jest, aby przed utworzeniem obiektu MediaRecorder utworzyè i odblokowaè obiekt Camera. Metody setPreviewDisplay i setCamera trzeba wywoäaè natychmiast po utworzeniu obiektu MediaRecorder. Koniecznie trzeba okreĈliè format i plik wyjĈciowy. Inne opcje (jeĈli wystöpujñ) naleĔy ustawiaè w kolejnoĈci przedstawionej na listingu 10.5. Obiekt MediaRecorder najlepiej jest inicjowaè po utworzeniu powierzchni. Aby otrzymywaè po- wiadomienia o tym, Ĕe powierzchnia jest gotowa, aktywnoĈè jest rejestrowana jako odbiornik SurfaceHolder.Callback. Ponadto w kodzie przesäoniöto metodö surfaceCreated. Aplikacja wy- woäuje w niej kod do inicjowania procesu nagrywania. 372 _ Rozdziaĥ 10. Multimedia @Override public void surfaceCreated(SurfaceHolder holder) { try { if(!mInitSuccessful) initRecorder(mHolder.getSurface()); } catch (IOException e) { e.printStackTrace(); // Zastosowaü lepszą obsáugĊ báĊdów? } } Po zakoþczeniu korzystania z powierzchni naleĔy pamiötaè o zwolnieniu zasobów, poniewaĔ Camera to obiekt wspóäuĔytkowany i inne aplikacje takĔe mogñ z niego korzystaè: private void shutdown() { // Zwalnianie obiektów MediaRecorder i — przede wszystkim — Camera, // poniewaĪ ten drugi jest wspóáuĪytkowany i mogą go potrzebowaü inne programy mMediaRecorder.reset(); mMediaRecorder.release(); mCamera.release(); // Po zwolnieniu obiektów nie moĪna ich ponownie wykorzystaü mMediaRecorder = null; mCamera = null; } Aby przedstawiony wczeĈniej kod byä wywoäywany automatycznie po zakoþczeniu korzy- stania z aktywnoĈci przez uĔytkownika, naleĔy przesäoniè metodö surfaceDestroyed: @Override public void surfaceDestroyed(SurfaceHolder holder) { shutdown(); } 10.5. Jak wykorzystaë androidowy mechanizm wykrywania twarzy? Wagied Davids Problem Programista chce, aby aplikacja wykrywaäa, czy na danym zdjöciu znajdujñ siö ludzkie twarze, a jeĈli tak, to gdzie. Rozwiézanie NaleĔy zastosowaè wbudowany androidowy mechanizm wykrywania twarzy. Wykrywanie twarzy to atrakcyjna i ciekawa ukryta funkcja interfejsu API Androida. Jest do- stöpna od Androida 1.5. Wykrywanie twarzy polega na wskazywaniu na zdjöciach fragmen- tów, które przypominajñ ludzkñ twarz. Rozpoznawanie obiektów na podstawie zbioru cech to jedno z zagadnieþ z obszaru uczenia maszynowego. Warto zauwaĔyè, Ĕe nie chodzi tu o funk- cjö rozpoznawania twarzy. Omawiany tu mechanizm jedynie wykrywa fragmenty wyglñdajñce jak twarz, natomiast nie okreĈla, do kogo ona naleĔy. Dopiero w wersji Ice Cream Sandwich 10.5. Jak wykorzystaë androidowy mechanizm wykrywania twarzy? _ 373 (Android 4.0) wprowadzono funkcjö rozpoznawania twarzy, którñ moĔna wykorzystaè do odblokowywania telefonu. Omówienie Gäówna aktywnoĈè (przedstawiona na listingu 10.6) tworzy obiekt FaceDetectionView. W przy- käadowej aplikacji sprawdzany plik zapisano na staäe, jednak w produkcyjnej wersji programu zdjöcia powinny pochodziè z aparatu lub galerii. Listing 10.6. Gäówna aktywnoĈè import android.app.Activity; import android.os.Bundle; public class Main extends Activity { /** Wywoáywana, gdy aktywnoĞü tworzona jest po raz pierwszy */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new FaceDetectionView(this, face5.JPG )); } } FaceDetectionView to niestandardowa klasa, säuĔñca do zarzñdzania wykrywaniem twarzy z wykorzystaniem klasy android.media.FaceDetector. Metoda init() okreĈla grafikö uĔywanñ do oznaczania twarzy. W przykäadzie wiadomo, gdzie znajdujñ siö twarze, a Android powi- nien je znaleĒè. Gäówne operacje wykonywane sñ w metodzie detectFaces(). Wywoäuje ona metodö findFaces klasy FaceDetector. Do tej ostatniej metody naleĔy przekazaè zdjöcie i tablicö na wyniki. Nastöpnie moĔna przejĈè po znalezionych twarzach. Potrzebny kod pokazano na listingu 10.7, a na rysunku 10.1 widoczny jest efekt dziaäania aplikacji. Rysunek 10.1. Wykrywanie twarzy w praktyce 374 _ Rozdziaĥ 10. Multimedia Listing 10.7. Plik FaceDetectionView.java ... import android.media.FaceDetector; public class FaceDetectionView extends View { private static final String tag = FaceDetectionView.class.getName(); private static final int NUM_FACES = 10; private FaceDetector arrayFaces; private final FaceDetector.Face getAllFaces[] = new FaceDetector.Face[NUM_FACES]; private FaceDetector.Face getFace = null; private final PointF eyesMidPts[] = new PointF[NUM_FACES]; private final float eyesDistance[] = new float[NUM_FACES]; private Bitmap sourceImage; private final Paint tmpPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint pOuterBullsEye = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint pInnerBullsEye = new Paint(Paint.ANTI_ALIAS_FLAG); private int picWidth, picHeight; private float xRatio, yRatio; private ImageLoader mImageLoader = null; public FaceDetectionView(Context context, String imagePath) { super(context); init(); mImageLoader = ImageLoader.getInstance(context); sourceImage = mImageLoader.loadFromFile(imagePath); detectFaces(); } private void init() { Log.d(tag, Init()... ); pInnerBullsEye.setStyle(Paint.Style.FILL); pInnerBullsEye.setColor(Color.RED); pOuterBullsEye.setStyle(Paint.Style.STROKE); pOuterBullsEye.setColor(Color.RED); tmpPaint.setStyle(Paint.Style.STROKE); tmpPaint.setTextAlign(Paint.Align.CENTER); BitmapFactory.Options bfo = new BitmapFactory.Options(); bfo.inPreferredConfig = Bitmap.Config.RGB_565; } private void loadImage(String imagePath) { sourceImage = mImageLoader.loadFromFile(imagePath); } @Override protected void onDraw(Canvas canvas) { Log.d(tag, onDraw()... ); xRatio = getWidth() * 1.0f / picWidth; yRatio = getHeight() * 1.0f / picHeight; canvas.drawBitmap( sourceImage, null, new Rect(0, 0, getWidth(), getHeight()), tmpPaint); for (int i = 0; i eyesMidPts.length; i++) { if (eyesMidPts[i] != null) { pOuterBullsEye.setStrokeWidth(eyesDistance[i] / 6); canvas.drawCircle(eyesMidPts[i].x * xRatio, eyesMidPts[i].y * yRatio, eyesDistance[i] / 2, pOuterBullsEye); 10.5. Jak wykorzystaë androidowy mechanizm wykrywania twarzy? _ 375 canvas.drawCircle(eyesMidPts[i].x * xRatio, eyesMidPts[i].y * yRatio, eyesDistance[i] / 6, pInnerBullsEye); } } } private void detectFaces() { Log.d(tag, detectFaces()... ); picWidth = sourceImage.getWidth(); picHeight = sourceImage.getHeight(); arrayFaces = new FaceDetector(picWidth, picHeight, NUM_FACES); arrayFaces.findFaces(sourceImage, getAllFaces); for (int i = 0; i getAllFaces.length; i++) { getFace = getAllFaces[i]; try { PointF eyesMP = new PointF(); getFace.getMidPoint(eyesMP); eyesDistance[i] = getFace.eyesDistance(); eyesMidPts[i] = eyesMP; Log.i( Twarz , i + + getFace.confidence() + + getFace.eyesDistance() + + Ustawienie: ( + getFace.pose(FaceDetector.Face.EULER_X) + , + getFace.pose(FaceDetector.Face.EULER_Y) + , + getFace.pose(FaceDetector.Face.EULER_Z) + ) + Punkt na wysokoĂci oczu: ( + eyesMidPts[i].x + , + eyesMidPts[i].y + ) ); } catch (Exception e) { Log.e( Twarz , i + – brak twarzy ); } } } } 10.6. Odtwarzanie muzyki z pliku Marco Dinacci Problem Programista chce odtwarzaè pliki dĒwiökowe przechowywane w urzñdzeniu. Rozwiézanie NaleĔy utworzyè i odpowiednio skonfigurowaè obiekty MediaPlayer oraz MediaController, a na- stöpnie podaè ĈcieĔkö do pliku. Potem moĔna rozkoszowaè siö muzykñ. Omówienie Odtwarzanie plików muzycznych jest proste — wystarczy skonfigurowaè obiekty MediaPlayer i MediaController. 376 _ Rozdziaĥ 10. Multimedia Najpierw naleĔy utworzyè aktywnoĈè z implementacjñ interfejsu MediaPlayerControl (listing 10.8). Listing 10.8. Poczñtek klasy z implementacjñ interfejsu MediaPlayerControl public class PlayAudioActivity extends Activity implements MediaPlayerControl { private MediaController mMediaController; private MediaPlayer mMediaPlayer; private Handler mHandler = new Handler(); W metodzie onCreate trzeba utworzyè i skonfigurowaè obiekty MediaPlayer i MediaControler. Pierwszy z tych obiektów wykonuje standardowe operacje na plikach muzycznych — odtwarza je, wstrzymuje i przechodzi do wskazanego miejsca w pliku. Drugi obiekt to widok z przyci- skami uruchamiajñcymi wspomniane operacje za pomocñ metod interfejsu MediaPlayerControl. Kod metody onCreate przedstawiono na listingu 10.9. Listing 10.9. Metoda onCreate() odtwarzacza @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mMediaPlayer = new MediaPlayer(); mMediaController = new MediaController(this); mMediaController.setMediaPlayer(PlayAudioActivity.this); mMediaController.setAnchorView(findViewById(R.id.audioView)); String audioFile = ; try { mMediaPlayer.setDataSource(audioFile); mMediaPlayer.prepare(); } catch (IOException e) { Log.e( PlayAudioDemo , Nie moĝna odtworzyÊ pliku + audioFile + . , e); } mMediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mHandler.post(new Runnable() { public void run() { mMediaController.show(10000); mMediaPlayer.start(); } }); } }); } Oprócz skonfigurowania obiektów MediaController i MediaPlayer w aplikacji trzeba utworzyè anonimowy odbiornik OnPreparedListener, aby uruchamiaè odtwarzacz tylko wtedy, gdy plik Ēródäowy jest gotowy do odtworzenia. NaleĔy teĔ pamiötaè o zwolnieniu zasobów obiektu MediaPlayer w momencie usuwania aktyw- noĈci (listing 10.10). Listing 10.10. Porzñdkowanie zasobów odtwarzacza @Override protected void onDestroy() { 10.6. Odtwarzanie muzyki z pliku _ 377 super.onDestroy(); mMediaPlayer.stop(); mMediaPlayer.release(); } Trzeba teĔ zaimplementowaè interfejs MediaPlayerControl. Kod implementacji jest bardzo pro- sty, co pokazano na listingu 10.11. Listing 10.11. Implementacja interfejsu MediaPlayerControl @Override public boolean canPause() { return true; } @Override public boolean canSeekBackward() { return false; } @Override public boolean canSeekForward() { return false; } @Override public int getBufferPercentage() { return (mMediaPlayer.getCurrentPosition() * 100) / mMediaPlayer.getDuration(); } // Pozostaáe metody tylko kierują wywoáania do obiektu MediaPlayer } Na zakoþczenie naleĔy przesäoniè metodö onTouchEvent, aby wyĈwietlaè przyciski z obiektu MediaController po dotkniöciu ekranu przez uĔytkownika. PoniewaĔ obiekt MediaController tworzony jest programowo, ukäad aktywnoĈci jest bardzo prosty: ?xml version= 1.0 encoding= utf-8 ? LinearLayout xmlns:android= http://schemas.android.com/apk/res/android android:orientation= vertical android:layout_width= fill_parent android:layout_height= fill_parent android:id= @+id/audioView /LinearLayout 10.7. Odtwarzanie dŚwiýku bez interakcji z uŜytkownikiem Ian Darwin Problem Programista chce, aby aplikacja odtwarzaäa pliki dĒwiökowe bez interakcji z uĔytkownikiem. 378 _ Rozdziaĥ 10. Multimedia Rozwiézanie Aby odtwarzaè pliki dĒwiökowe bez interakcji z uĔytkownikiem (bez kontrolek do zmiany gäoĈnoĈci, wstrzymywania odtwarzania itd.), wystarczy utworzyè obiekt MediaPlayer dla da- nego pliku i wywoäaè metodö start(). Omówienie Jest to najprostsza technika odtwarzania plików dĒwiökowych. W porównaniu z aplikacjñ z receptury 10.6 ten program nie udostöpnia uĔytkownikom kontrolek do sterowania odtwa- rzaniem. Dlatego zwykle naleĔy udostöpniè przynajmniej przycisk Stop lub Anuluj — zwäasz- cza jeĈli plik jest däugi. JeĔeli jednak w aplikacji chcesz tylko odtwarzaè krótkie efekty dĒwiö- kowe, nie musisz udostöpniaè takich kontrolek. Dla pliku trzeba utworzyè obiekt MediaPlayer. Plik dĒwiökowy moĔe znajdowaè siö na karcie SD lub w katalogu res/raw aplikacji. JeĈli plik dĒwiökowy jest elementem programu, naleĔy umieĈciè go we wspomnianym katalogu. Tu uĔywany jest plik res/raw/alarm_sound.3gp. Refe- rencja do niego to R.raw.alarm_sound, a do odtwarzania pliku säuĔy nastöpujñcy kod: MediaPlayer player = MediaPlayer.create(this, R.raw.alarm_sound); player.start(); JeĈli plik znajduje siö na karcie SD, moĔna odtworzyè go w nastöpujñcy sposób: MediaPlayer player = new MediaPlayer(); player.setDataSource(fileName); player.prepare(); player.start(); Istnieje teĔ metoda pomocnicza, MediaPlayer.create(Context, URI). Metoda ta automatycznie wywoäuje metodö prepare(). Aby sterowaè odtwarzaczem w aplikacji, moĔna wywoäywaè odpowiednie metody, np. player. stop(), player.pause() itd. JeĈli chcesz ponownie uruchomiè odtwarzacz po jego zatrzymaniu, wywoäaj znów metodö prepare(). Do odbierania powiadomieþ o zakoþczeniu odtwarzania säuĔy odbiornik OnCompletionListener: player.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { Toast.makeText(Main.this, Zakoñczono odtwarzanie , Toast.LENGTH_SHORT).show(); } }); Po ostatecznym zakoþczeniu korzystania z obiektu MediaPlayer naleĔy wywoäaè metodö release() tego obiektu, aby zwolniè pamiöè. JeĈli aplikacja tworzy duĔo obiektów MediaPlayer i nie zwalnia pamiöci, moĔe nastñpiè wyczerpanie zasobów. Zobacz takŜe Aby wykorzystaè wszystkie moĔliwoĈci obiektu MediaPlayer, naleĔy poznaè jego róĔne stany i przejĈcia miödzy nimi. Pomaga to zrozumieè, które metody moĔna wywoäywaè. Na stronie http://developer.android.com/reference/android/media/MediaPlayer.html znajdziesz kompletny dia- gram stanów obiektu MediaPlayer. 10.7. Odtwarzanie dŚwiýku bez interakcji z uŜytkownikiem _ 379 10.8. Konwersja mowy na tekst Corey Sunwold Problem Programista chce, aby aplikacja rejestrowaäa mowö i przetwarzaäa jñ jako tekst. Rozwiézanie Jednñ z wyjñtkowych cech Androida jest wbudowane przetwarzanie mowy na tekst. Zapew- nia to alternatywö dla wprowadzania tekstu. Jest to przydatne, poniewaĔ uĔytkownicy majñ czasem zajöte röce i nie mogñ wpisywaè informacji. Omówienie Android udostöpnia wygodny interfejs API do korzystania z wbudowanej funkcji rozpozna- wania mowy. Interfejs ten oparty jest na intencji RecognizerIntent. Przykäadowy ukäad jest bardzo prosty (przedstawiono go na listingu 10.12). W ukäadzie znaj- duje siö tylko kontrolka TextView o nazwie speechText i kontrolka Button o nazwie getSpeechButton. Ta ostatnia kontrolka säuĔy do uruchamiania mechanizmu rozpoznawania mowy, a zwracane wyniki pojawiajñ siö w kontrolce TextView. Listing 10.12. Program ilustrujñcy rozpoznawanie mowy public class Main extends Activity { private static final int RECOGNIZER_RESULT = 1234; /** Wywoáywana, gdy aktywnoĞü tworzona jest po raz pierwszy */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button startSpeech = (Button)findViewById(R.id.getSpeechButton); startSpeech.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, Mowa na tekst ); startActivityForResult(intent, RECOGNIZER_RESULT); } }); } /** * Obsáuga wyników zwróconych przez aktywnoĞü przetwarzającą mowĊ 380 _ Rozdziaĥ 10. Multimedia */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RECOGNIZER_RESULT resultCode == RESULT_OK) { ArrayList String matches = data.getStringArrayListExtra( RecognizerIntent.EXTRA_RESULTS); TextView speechText = (TextView)findViewById(R.id.speechText); speechText.setText(matches.get(0).toString()); } super.onActivityResult(requestCode, resultCode, data); } } Zobacz takŜe http://developer.android.com/reference/android/speech/RecognizerIntent.html. 10.9. Konwersja tekstu na mowý Ian Darwin Problem Programista chce, aby aplikacja „wypowiadaäa” napisane säowa, tak aby uĔytkownik mógä siö z nimi zapoznaè bez spoglñdania na ekran (np. w trakcie prowadzenia samochodu). Rozwiézanie NaleĔy zastosowaè interfejs API TextToSpeech. Omówienie Interfejs API TextToSpeech wbudowany jest w Android, choè w niektórych wersjach platfor- my trzeba doinstalowaè pliki dĒwiökowe. Aby rozpoczñè korzystanie z omawianego mechanizmu, potrzebny jest tylko obiekt TextTo Speech. Teoretycznie wystarczy napisaè poniĔszy kod: private TextToSpeech myTTS = new TextToSpeech(this, this); myTTS.setLanguage(Locale.US); myTTS.speak(textToBeSpoken, TextToSpeech.QUEUE_FLUSH, null); myTTS.shutdown(); Aby jednak zapewniè poprawne dziaäanie aplikacji, trzeba zastosowaè kilka intencji. Jedna powinna sprawdzaè, czy dane mechanizmu TTS sñ dostöpne (i instalowaè je, jeĈli jest inaczej). Druga jest potrzebna do uruchamiania mechanizmu TTS. Dlatego w praktyce kod powinien wyglñdaè tak jak na listingu 10.13. Ta ciekawa prosta aplikacja po kaĔdym wciĈniöciu przyci- sku Mów wygäasza jedno z kilku banalnych zdaþ. 10.9. Konwersja tekstu na mowý _ 381 Listing 10.13. Program ilustrujñcy konwersjö tekstu na mowö public class Main extends Activity implements OnInitListener { private TextToSpeech myTTS; private List String phrases = new ArrayList String (); public void onCreate(Bundle savedInstanceState) { phrases.add( Hello Android, Goodbye iPhone ); phrases.add( The quick brown fox jumped over the lazy dog ); phrases.add( What is your mother s maiden name? ); phrases.add( Etaoin Shrdlu for Prime Minister ); phrases.add( The letter Q does not appear in antidisestablishmentarianism ) ); super.onCreate(savedInstanceState); setContentView(R.layout.main); Button startButton = (Button) findViewById(R.id.start_button); startButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Intent checkIntent = new Intent(); checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); startActivityForResult(checkIntent, 1); } }); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 1) { if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) { myTTS = new TextToSpeech(this, this); n myTTS.setLanguage(Locale.US); } else { // Brak danych mechanizmu TTS. Aplikacja próbuje je zainstalowaü Intent ttsLoadIntent = new Intent(); ttsLoadIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); startActivity(ttsLoadIntent); } } } public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { int n = (int)(Math.random() * phrases.size()); myTTS.speak(phrases.get(n), TextToSpeech.QUEUE_FLUSH, null); } else if (status == TextToSpeech.ERROR) { myTTS.shutdown(); } } n Pierwszy argument to kontekst (aktywnoĈè), a drugi — odbiornik OnInitListener, tu takĔe zaimplementowany w gäównej aktywnoĈci. Po zainicjowaniu obiektu TextToSpeech wywo- äywany jest wspomniany odbiornik. Metoda onInit() tego odbiornika ma powiadamiaè o tym, Ĕe mechanizm TTS jest gotowy. Przedstawiona tu prosta aplikacja Speaker tylko generuje säowa. W bardziej rozbudowanym programie warto uruchomiè wñtek lub usäugö do obsäugi mowy. 382 _ Rozdziaĥ 10. Multimedia Skorowidz formatowanie czasu i daty, 97 Google Analytics, 90 kontrolowanie danych wejĈciowych, 99 latarka, 92 lokalizacja, 473 mapy, 473 menu kontekstowe, 75 menu opcji, 75 monitorowanie poziomu baterii, 83 moĔliwe stany, 35 obsäuga poäñczeþ telefonicznych, 417 obsäuga wyjñtków, 76 projektowanie, 73 sieciowe, 441 singleton, 79 stoper z odliczaniem wstecznym, 55 stosowanie wskazówek, 108 Tipster, 57 tworzenie ekranów powitalnych, 84 tworzenie kopii zapasowej, 102 wspóäuĔytkowanie danych, 80 wymagania, 73 zmiana orientacji ekranu, 81 zrzutu ekranu, 54 biblioteki, 41 AndroidPlot, 41, 207 HttpClient, 442, 443 OpenStreetMap, 41 RGraph, 224 Bluetooth, 531 podäñczanie innego urzñdzenia, 533 wäñczanie, 532 wykrywanie urzñdzeþ, 537 Ĕñdania poäñczeþ, 536 cykl Ĕycia, 35 diagram stanów, 36 ekran powitalny, 86 formatowanie liczb, 277 Double.toString(), 277 kody formatujñce, 278 599 A ADB, 37 AdMob, 589 akcelerometr, 521 czujniki, 521 dostöpnoĈè czujnika, 522 executeShakeAction(), 525 getSensorList(), 522 isAccelerationChanged(), 525 onAccuracyChanged(), 527 onSensorChanged(), 523, 526, 527 orientacji, 527 SensorManager, 522 temperatury, 528 wykorzystywanie danych, 524 alerty, 315 komunikaty toast, 336 powiadomienia, 337 dĒwiök, 339 reakcja na klikniöcie, 342 powiadomienie, 341 wäñczanie diody LED, 340 wyĈwietlanie, 338 przetwarzanie w tle, 330 Python, 558 Service, 338 wyskakujñce okna dialogowe, 321 AlertDialog, 321, 532 AndEngine, 458 Android, 13 akcelerometr, 521 czujniki, 521 animacje, 455 aplikacje, 35 awarie, 125 Backup Manager, 102 cykl Ĕycia, 35 dostosowywanie do tabletów, 94 Android formatowanie liczb liczba mnoga, 281 metody formatujñce, 278 fragment, 305 göstoĈè ekranu, 74 grafika, 185 animacja rastrowa, 228 animacje, 455 niestandardowa czcionka, 185, 188 OpenGL ES, 185, 188 paleta kolorów, 216 przybliĔanie obrazu, 230 rysowanie päynnych linii, 194 skanowanie kodów, 204 täo domyĈlnego widoku, 221 trójwymiarowa, 188 tworzenie ikony, 208, 215 tworzenie wykresów, 224 wyĈwietlanie danych, 207 zdjöcia, 198, 200 gry, 455 frameworki, 455 GUI, 58, 235 alerty, 315 animacja, 269 czas, 322 ekran wczytywania, 291 komponenty, 58 kontrolka ListView, 343 lista rozwijana, 251 menu, 316 niestandardowe okno dialogowe, 328 obrotowy mechanizm wybierania, 325 obsäuga däugiego klikniöcia, 253 obsäuga zmian konfiguracji, 238 odbiornik zdarzeþ, 242 otwieranie nowego ekranu, 283 pole wyboru, 247 przeksztaäcanie pól tekstowych, 260 przycisk wysyäania, 262 przyciski graficzne, 249 przyciski opcji, 247 tworzenie przycisku, 241 widĔet, 236 widĔet aplikacji, 236 wykrywanie gestów, 299 wyĈwietlanie pól tekstowych, 254 zakrywanie innych komponentów, 292 internacjonalizacja, 571 äaþcuchy znaków, 575 tekst aplikacji, 572 Java, 19 pakiet JDK, 29 600 _ Skorowidz pomijane interfejsy API, 20 RGraph, 224 Ĉrodowisko IDE Eclipse, 29 kanaäy danych, 76 komunikacja, 145 AsyncTask, 145 dostawcy treĈci, 175, 178 e-mail, 147 intencje, 145 IPC, 179 komponenty obsäugi, 145 komunikaty rozgäoszeniowe, 157 odbiorniki rozgäoszeniowe, 145 podtrzymywanie dziaäania usäugi, 155 przekazywanie äaþcuchów znaków, 151 uĔywanie wñtków, 159 kontrolki, 59 rozmieszczanie, 59 mechanizmy wprowadzania danych, 75 multimedia, 367 Gallery, 368 mechanizm wykrywania twarzy, 373 odtwarzanie plików muzycznych, 377 rejestrowanie filmów, 371 YouTube, 367 NinePatch, 221 pakiet ADK, 21 pakiet SDK, 24 aktualizacja, 46 przykäadowe programy, 44 wtyczka ADT, 29 sterowanie, 539 kopiowanie tekstu, 542 menedĔer aktywnoĈci, 547 polecenia powäoki, 545 poäñczenie z sieciñ, 539 tryb dzwonka, 541 ustawienia projektu, 540 wäñczanie wibracji, 544 wyĈwietlanie powiadomieþ, 544 Ĉrodowisko Eclipse, 24 parametry nowego projektu, 25 tworzenie nowego projektu, 45 uruchamianie projektu, 27 testy, 111 awarie, 125 BugSense, 129 chmura, 121 cykl Ĕycia, 134 debugowanie kodu, 128 konfigurowanie urzñdzeþ AVD, 112 lokalny dziennik czasu wykonania, 131 projekt testowy, 122 sterowanie programowaniem, 111 urzñdzenia AVD, 23 konfigurowanie, 112 utrwalanie danych, 383 baza SQLite, 401, 402, 403 dodawanie danych kontaktowych, 412 pobieranie informacji o plikach, 383 ustawianie preferencji, 390 wczytywanie danych kontaktowych, 415 wczytywanie plików z aplikacji, 386 wyszukiwanie tekstu, 396 wyĈwietlanie zawartoĈci katalogu, 387 wielkoĈè ekranu, 74 Windows, 29 Ĉrodowisko IDE Eclipse, 29 wtyczka ADT, 24 wyĈwietlanie czasu i daty, 97 DateFormat, 97 DateUtils, 99 Formatter, 99 java.util.Date, 98 TextView, 97 Time, 99 zachowywanie danych, 81 getLastNonConfigurationInstance(), 81 onCreate(), 82 onRetainNonConfigurationInstance(), 81 onSaveInstanceState(), 81 zdalna usäuga, 179 bindService(), 181 invokeService(), 182 onBind(), 179 onCreate(), 180 onDestroy(), 180 releaseService(), 182 startService(), 181 stopService(), 182 zrzut ekranu, 52 Device Screen Capture, 53 Android Compatibility, 305 Android Localizer, 575 aplikacje, 35 akcelerometr czujnik orientacji, 527 dostöpnoĈè, 522 pobieranie danych, 523 wykorzystywanie danych, 524 awarie, 125 adb logcat, 125 NPE, 126 Backup Manager, 102 implementacja, 102 polecenie bmgr, 107 Bluetooth akceptowanie poäñczeþ, 536 pobieranie adresu MAC, 532 pobieranie nazwy urzñdzenia, 532 tworzenie serwera, 536 wymiana danych z urzñdzeniem, 534 certyfikat, 583 generowanie, 584 korzyĈci, 584 cykl Ĕycia rejestrowanie zdarzeþ, 135 dostawca treĈci, 178 dostosowywanie do tabletów, 94 Google Analytics, 90 Java kod natywny, 552 jözyk C kod natywny, 553 kontrolka ListView, 343 nagäówki sekcji, 352 obsäuga zmian orientacji, 360 wyĈwietlanie listy wierszy, 344 zachowywanie pozycji, 356 kontrolowanie danych wejĈciowych, 99 KeyListener, 99 typy odbiorników, 102 konwersja tekstu na mowö, 382 kopia zapasowa, 102 Backup Manager, 102 latarka, 92 etapy rozwijania, 92 lokalizacja, 473 aktualizowanie lokalizacji, 474 fikcyjne wspóärzödne GPS, 477 geokodowanie, 479 geokodowanie odwrotne, 480 OpenStreetMap, 473 pobieranie danych o lokalizacji, 474 podawanie fikcyjnej lokalizacji, 478 urzñdzenia GPS, 473 mapy, 473 mapy Google’a, 480 AddressOverlay, 495 ItemizedOverlay, 491 MapTest, 481 MyOverlay, 488 obsäuga däugich klikniöè, 506 wyszukiwanie lokalizacji, 502 wyĈwietlanie ikony, 499 wyĈwietlanie warstwy, 495 menu kontekstowe, 75 menu opcji, 75 Skorowidz _ 601 aplikacje obsäuga poäñczeþ telefonicznych, 417 pobieranie danych, 430 poäñczenia przychodzñce, 418, 420 poäñczenia wychodzñce, 421 wiadomoĈci SMS, 425 wybieranie numeru telefonu, 424 odbiornik dotyku, 231 odnoĈniki, 595 OpenStreetMap, 509 aktualizowanie lokalizacji, 517 obsäuga dotkniöè warstwy, 515 optymalizowanie kodu, 593 pobieranie dokumentów Google, 562 podpisywanie, 586 projektowanie, 73 ekrany powitalne, 84 formatowanie czasu i daty, 97 funkcje urzñdzenia, 75 kanaäy danych, 76 kontrolowanie danych wejĈciowych, 99 latarka, 92 mechanizmy wprowadzania danych, 75 obsäuga wyjñtków, 76 odbiornik rozgäoszeniowy, 83 wielkoĈè i göstoĈè ekranu, 74 przeksztaäcanie wyjñtków, 78 rozpoznawanie mowy, 380 sieciowe, 441 parser danych, 446 przeksztaäcanie tekstu, 450, 451 RESTful, 442 wyraĔenia regularne, 444 wyĈwietlanie stron internetowych, 452 skanowanie kodów, 204 SCAN_FORMATS, 206 SCAN_MODE, 206 SL4A, 556 Ĉledzenie korzystania, 90, 91 Google Analytics, 90 udostöpnianie, 587 przesyäanie, 587 rejestrowanie, 587 wspóäuĔytkowanie danych, 80 wykrywanie gestów, 299 wymagania, 73 wyĈwietlanie danych, 207 wyĈwietlanie reklam, 588 zaciemnianie kodu, 593 aplikacje sieciowe, 441 parser danych, 446 getRSS(), 447 przeksztaäcanie tekstu, 450 602 _ Skorowidz kontrolka TextView, 451 MD5, 450 na odnoĈniki, 451 na postaè nieczytelnñ, 450 stosowanie RESTful, 442 converse(), 442 HTTP GET, 442 HTTP POST, 442 klient usäugi, 443 URL, 442 URLConnection, 442 wyraĔenia regularne, 444 BookRank, 445 wyĈwietlanie stron internetowych, 452 kontrolka WebView, 452 B Bluetooth, 531 podäñczanie innego urzñdzenia, 533 wymiana danych z urzñdzeniem, 534 wäñczanie, 532 AlertDialog, 532 isEnabled(), 532 konfigurowanie, 533 onActivityResult(), 532 pobieranie adresu MAC, 532 pobieranie nazwy, 532 wykrywanie urzñdzeþ, 537 tryb parowania, 537 Ĕñdania poäñczeþ, 536 akceptowanie poäñczeþ, 536 listenUsingRfcommWithServiceRecord(), 536 start(), 536 tworzenie serwera, 536 BugSense, 129 C cykl Ĕycia, 35 android.Activity, 35 diagram stanów, 36 rejestrowanie zdarzeþ, 135 D dane, 383 baza SQLite, 401 data i czas, 403 insert(), 402 moveToFirst(), 403 moveToNext(), 403 dane baza SQLite onCreate(), 401 pobieranie danych, 402 query(), 403 SQLiteOpenHelper, 401 strftime(), 403 tworzenie, 401 zapisywanie danych, 402 informacje o plikach, 383 File, 384 metody zwracajñce informacje, 384 JSON, 406 generowanie danych, 406 przetwarzanie äaþcucha znaków, 407 kontaktowe, 412 addContact(), 413 dodawanie danych, 412 pobieranie danych, 415 parser danych, 446 pobieranie, 430 akcelerometr, 523 baza SQLite, 402 dane kontaktowe, 415, dostawcy treĈci, 175 lokalizacja, 574 poäñczenia telefoniczne, 430 TelephonyManager, 430 pojemnoĈè karty SD, 390 ustawianie preferencji, 390 domyĈlne, 394 getBoolean(), 393 getDefaultSharedPreferences(), 393 getString(), 393 onCreate(), 392 onSharedPreferenceChanged(), 394 PreferenceActivity, 394 PreferenceCategory, 391 PreferenceScreen, 391, 392 wczytywanie plików z aplikacji, 386 openRawResource(), 387 wyszukiwanie tekstu, 396 DbAdapter, 396 wyĈwietlanie zawartoĈci katalogu, 387 accept(), 389 FilenameFilter, 389 kontrolka ListView, 388 listFiles(), 388 XML, 407 interfejs DOM API, 407 interfejs XmlPullParser, 409 newInstance(), 410 newPullParser(), 410 przetwarzanie kodu, 408 require(), 411 statyczne zasoby, 411 dokumenty Google, 562 lista dokumentów, 564 pobieranie, 562 dostawcy treĈci, 175, 178 MyContantProvider, 177 pobieranie danych, 175 getContentResolver(), 177 onActivityResult(), 176 query(), 177 D-pad, 192 Droid, 185, 186 EDGE, 441 E F Facebook, 467 fragment, 305 frameworki, 455, 549 AndEngine, 458 AppCelerator Titanium, 549 Flixel, 456 PhoneGap, 549, 568 G Gallery, 368 geokodowanie, 479 gesty dotykowe, 230 odbiornik dotyku, 231 Google Analytics, 90 Google Play, 587 GPRS, 441 graficzny interfejs uĔytkownika, Patrz GUI grafika, 185 animacja rastrowa, 228 onWindowFocusChanged(), 229 start(), 229 niestandardowa czcionka, 185, 188 Iceberg, 186 OTF, 186 TTF, 186 Typeface.create(), 186 ustawianie, 187 OpenGL ES, 185 przybliĔanie obrazu, 230 odbiornik dotyku, 231 Skorowidz _ 603 grafika rysowanie päynnych linii, 194 expandDirtyRect(), 195 getHistoricalX(int), 195 getHistoricalY(int), 195 getHistorySize(), 194 invalidate(), 195 TouchEvent, 194 skanowanie kodów, 204 SCAN_FORMATS, 206 SCAN_MODE, 206 täo domyĈlnego widoku, 221 kontrolka EditText, 222 trójwymiarowa, 188 buffer.position(0), 191 D-pad, 192 obracanie szeĈcianu, 192 onDrawFrame(), 190 onSurfaceChanged(), 190 requestFocus(), 194 setFocusableInTouchMode(), 194 wyĈwietlanie szeĈcianu, 190 tworzenie ikony, 208, 215 formaty ikon, 220 obramowanie, 217 paleta kolorów, 216 PNG, 209 SVG, 210 wielkoĈè, 210 wymiary grafiki, 217 wymiary ikon, 217 tworzenie wykresów, 224 RGraph, 224 wyĈwietlanie danych, 207 AndroidPlot, 207 zdjöcia, 198, 200 android.media.Camera, 200 configure(), 202 onActivityResult(), 199 surfaceChanged(), 202 gry, 455 frameworki, 455 AndEngine, 458 Flixel, 456 GUI, 235, 238 alerty, 315 AlertDialog, 321 komunikaty toast, 336 powi
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Android. Receptury
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: