Roman Wantoch-Rekowski

Android w praktyce:
projektowanie aplikacji

Warszawa 2014

Opiniodawcy: dr hab. inż. Zbigniew Tarapata, prof. WAT
dr inż. Mariusz Chmielewski

Projekt okładki i stron tytułowych Grzegorz Laskowski

Zdjęcie na okładce Kirill_M/Shutterstock

Wydawca Łukasz Łopuszański

Redaktor Bianka Piwowarczyk-Kowalewska

Koordynator produkcji Anna Bączkowska

Skład i łamanie Marcin Szcześniak

Książka, którą nabyłeś, jest dziełem twórcy i wydawcy. Prosimy, abyś przestrzegał praw, jakie im przysługują. Jej zawartość możesz udostępnić nieodpłatnie osobom bliskim lub osobiście znanym. Ale nie publikuj jej w internecie. Jeśli cytujesz jej fragmenty, nie zmieniaj ich treści i koniecznie zaznacz, czyje to dzieło. A kopiując jej część, rób to jedynie na użytek osobisty.

Szanujmy cudzą własność i prawo

Więcej na www.legalnakultura.pl

Polska Izba Książki

Copyright © by Wydawnictwo Naukowe PWN SA

eBook został przygotowany na podstawie wydania papierowego z 2014 r. (wyd. I)

Warszawa 2014

ISBN 978-83-01-17949-6 (ePub)

ISBN 978-83-01-17950-2 (Mobi)

Wydanie I

Wydawnictwo Naukowe PWN SA

tel. 22 69 54 321, faks 22 69 54 288

infolinia 801 33 33 88

e-mail: pwn@pwn.com.pl

www.pwn.pl

Skład wersji elektronicznej:

Virtualo Sp. z o.o.

Spis treści

- Wstęp

- 1. Elementy projektu aplikacji na platformę Android w środowisku Eclipse

- 2. Pierwsza aplikacja „Witaj Świecie”

- 3. Emulator urządzenia z systemem Android AVD

- 4. Główne elementy składowe aplikacji na platformie Android

- 4.1. Kontekst

- 4.2. Aktywności

- 4.3. Intencje

- 4.4. Usługi

- 4.5. Dostawcy treści

- 4.6. Odbiorcy treści

- 5. Podstawy struktury pliku AndroidManifest.xml

- 6. Filtry intencji

- 7. URI – Uniform Resource Identifier

- 8. Pliki preferencji i pliki płaskie

- 8.1. Pliki preferencji

- 8.2. Pliki płaskie

- 9. Rysowanie, animacje i podstawy grafiki 3D

- 9.1. Rysowanie z wykorzystaniem obiektów Canvas i Paint

- 9.2. Definiowanie kształtów w zasobach XML

- 9.3. Rysowanie z wykorzystaniem klasy ShapeDrawable

- 9.4. Animacje

- 9.5. Podstawy grafiki 3D

- 10. Zastosowanie bazy danych SQLite

- 10.1. Projektowanie baz danych

- 10.2. Podstawy języka SQL

- 10.3. Struktura aplikacji zawierającej bazę danych

- 11. Powiadomienia – Notifications

- 12. Wykorzystanie klasy Thread i AsyncTask

- 12.1. Wątki – obliczenia w tle

- 12.2. Wątki – obliczenia w tle z przekazywaniem danych do interfejsu

- 12.3. AsyncTask – obliczenia w tle z prostą integracją z interfejsem

- 13. Przetwarzanie plików XML

- 14. Opis typów zasobów

- 14.1. Łączenie zasobów z programem

- 14.2. Typy zasobów

- 14.3. Definiowanie zasobów alternatywnych (podfoldery /res)

- 14.4. Zasady budowy różnego typu ikon dla systemu Android

- 15. Przegląd elementów interfejsu użytkownika oraz projektowanie układów

- 15.1. Elementy interfejsu GUI

- 15.2. Projektowanie układów – Layouts

- 15.3. Identyfikacja i obsługa gestów

- 15.4. Adaptery danych

- Podstawowe zasoby internetowe

- Przypisy

Wszystkie rozdziały dostępne w pełnej wersji książki.

Wstęp

Projektowanie aplikacji działających na urządzeniach z systemem operacyjnym Android obok całej analizy funkcjonalnej programu wymaga uwzględnienia specyfikacji warunków, w jakich uruchamiana jest ta aplikacja. Należy zwrócić szczególną uwagę na to, że urządzenia z systemem Android są urządzeniami mobilnymi, co oznacza, że ich zasoby są ograniczone – na przykład przez wydajność procesora lub rozmiar pamięci. Jednocześnie aplikacje budowane na urządzenia mobilne charakteryzują się specyficznym interfejsem komunikacji z użytkownikiem. Twórcy systemu Android zaproponowali więc specyficzny dla urządzeń mobilnych (aplikacji mobilnych) sposób uruchamiania i funkcjonowania tych aplikacji w systemie operacyjnym. Jednym z ważniejszych aspektów działania aplikacji mobilnej jest sposób komunikacji z różnymi elementami, w jakie wyposażone jest urządzenie mobilne, np. aparat, żyroskop, karta SIM, GPS.

Efektywne projektowanie aplikacji zgodne z założeniami systemu operacyjnego Android wymaga poznania podstawowych pojęć związanych z budową aplikacji mobilnych oraz cyklu życia aplikacji mobilnej (cykl życia Aktywności).

Idea funkcjonowania aplikacji mobilnej obejmuje cztery podstawowe elementy składowe [1]:

Kontekst (obiekt typu Context)

Kontekst jest środowiskiem, w którym uruchamiana jest zaprojektowana aplikacja mobilna. Za pośrednictwem kontekstu istnieje możliwość zarządzania aplikacją i uzyskiwania dostępu do parametrów aplikacji oraz urządzenia, na którym została uruchomiona.

Aktywność (obiekt typu Activity)

Aktywności stanowią podstawowy budulec do tworzenia zaplanowanej funkcjonalności aplikacji mobilnej i zawierają ich implementację. Oznacza to, że wywoływanie funkcji aplikacji mobilnej odbywa się przez uruchomienie Aktywności. W danym zachowaniu można wywoływać kolejne Aktywności, dzięki czemu uzyskujemy możliwość realizacji nawet bardzo złożonych scenariuszy. Podstawową właściwością Aktywności jest krótki czas jej wykonania oraz kontakt z użytkownikiem aplikacji lub innymi aplikacjami.

Intencja (obiekt typu Intent)

Intencje stanowią mechanizm obsługi zdarzeń występujących w aplikacji mobilnej (komunikaty asynchroniczne). Z wykorzystaniem mechanizmu Intencji możliwe jest uruchomienie Aktywności (także w innej aplikacji) lub serwisu w momencie wystąpienia określonego zdarzenia. Mechanizm Intencji służy także do komunikacji między różnymi aplikacjami uruchomionymi na urządzeniu mobilnym oraz do obsługi zdarzeń pochodzących z innych aplikacji (np. połączenie przychodzące) i wyposażenia urządzenia (np. niski stan baterii, wykonano zdjęcie).

Usługa/Serwis (obiekt typu Service)

Usługi można traktować jako specyficzne zastosowanie Aktywności. Usługi zawierają implementację funkcji, które nie wykorzystują interfejsu komunikacji z użytkownikiem oraz wymagają długiego czasu działania. Może on wynikać z czasochłonnych algorytmów obliczeniowych lub z potrzeby dostępu do bazy danych (w tym zewnętrznych baz danych) i konieczności wysłania lub pobrania dużej ilości danych. Cechą charakterystyczną usługi jest fakt działania „w tle”. W postaci usługi często implementuje się funkcje działające cyklicznie.

Dostawcy treści (obiekt typu ContentProvider)

Dostawcy treści (dane) zapewniają dostęp do swoich zasobów innym aplikacjom zainstalowanym na urządzeniu. Udostępniane dane mogą być przechowywane przez dostawcę w bazie danych SQLite lub w inne trwałej postaci. Dostawcy treści mogą też być związani komponentami sprzętowymi zainstalowanymi w urządzeniu – takimi jak GPS.

Przykłady wykorzystania systemowych dostawców treści oraz sposób zaprojektowania własnego dostawcy treści przedstawiono w podrozdziale 4.5.

Odbiorcy komunikatów (obiekt typu BroadcastReceiver)

Odbiorcy komunikatów są specjalnymi klasami umożliwiającymi komunikację z innymi aplikacjami dzięki otrzymywaniu konkretnych komunikatów wysyłanych przez inne aplikacje zainstalowane na urządzeniu. Przykłady wykorzystania komunikatów systemowych przedstawiono w rozdziale 6, a przykład implementacji własnych komunikatów przedstawiono w podrozdziale 4.6 (Przykład 7).

Szczegółowe informacje na temat sposobu wykorzystania poszczególnych elementów składowych aplikacji mobilnej z opisem zasad ich działania i przykładowych sposobów wykorzystania przedstawiono w kolejnych rozdziałach.

1. Elementy projektu aplikacji na platformę Android w środowisku Eclipse

W środowisku Eclipse do budowy aplikacji mobilnych na platformę Android udostępniony został dedykowany plugin, którego zastosowanie w dużym stopniu porządkuje i upraszcza cały proces twórczy. Zastosowanie środowiska Eclipse umożliwia implementację i testowanie aplikacji na AVD (Android Virtual Devices – patrz rozdział 3) bez konieczności posiadania rzeczywistego urządzenia mobilnego. Takie podejście zmniejsza koszty tworzenia aplikacji i jednocześnie umożliwia testowanie aplikacji na urządzeniach o skrajnie różnych parametrach (rozmiar ekranu, pamięć itd.). Główne okno środowiska Eclipse (przykładowa konfiguracja) jest przedstawione na rysunku 1.

Rysunek 1. Okno główne IDE Eclipse do budowy aplikacji mobilnej na platformę Android

Okno projektu składa się z czterech zasadniczych elementów:

1. Struktura projektu – przedstawia wszystkie elementy wchodzące w skład aplikacji w postaci drzewa katalogów i plików.

2. Główny obszar roboczy – zasadniczy element okna projektu, w którym wprowadza się kod programu, tworzy pliki konfiguracyjne oraz projektuje interfejs komunikacji z użytkownikiem.

3. Szczegóły elementów z głównego obszaru roboczego – dodatkowe informacje dotyczące elementów wybranych w głównym obszarze roboczym. Przykładowo, podczas przeglądania kodu źródłowego w obszarze tym wyświetlają się elementy definicji klas.

4. Konsola z komunikatami (dla wybranej zakładki Console) – zawiera wykaz komunikatów będących konsekwencją działań wykonywanych w środowisku Eclipse (w tym komunikaty o błędach). Na przykładowym ekranie pokazano sekwencję komunikatów związanych z uruchomieniem aplikacji. W tej części projektu można przełączać się między różnymi widokami w zależności od wybranej zakładki. Rysunek 2 przedstawia zakładkę LogCat, która w dalszej części będzie wykorzystywana do wypisywania z aplikacji komunikatów do logu (polecenie Log) w celu śledzenia pośrednich wyników kontrolnych.

Rysunek 2. Zakładka LogCat zawierająca komunikaty zapisywane do logu – przykład Log.d (”Baza SQL”,””)

Rysunek 3. Okno elementów składowych projektu aplikacji mobilnej

Rysunek 3 przedstawia strukturę projektu w postaci drzewa folderów i plików. Odpowiada ona fizycznej strukturze folderów. Na rysunku przedstawiono strukturę wygenerowaną w trakcie procedury tworzenia nowego projektu z jedną klasą startową, prostym interfejsem (tytuł aplikacji i jedno pole typu tekst) oraz ze zdefiniowaną ikoną startową. Nazwy folderów są wykorzystywane w trakcie kompilacji, dlatego nie należy ich modyfikować. Wykaz predefiniowanych nazw folderów i podfolderów jest znacznie szerszy. Projektant aplikacji powinien zachować utworzoną strukturę, ma jednak możliwość dodania własnych folderów.

Projekt aplikacji mobilnej podzielony jest na następujące elementy składowe (wybrane foldery):

src – główny folder zawierający definicję wszystkich elementów oprogramowania zapisanych w języku Java. W przykładzie użyto pliku o nazwie MainActivity.java zawierającego definicję klasy startowej.

gen – folder zawierający klasę R.java generowaną automatycznie przez środowisko w momencie definiowania zasobów aplikacji (folder res). Nie należy w nim dokonywać zmian.

bin – folder zawierający postać wykonywalną aplikacji po poprawnej kompilacji.

libs – folder zawiera biblioteki wykorzystywane do budowy aplikacji.

res – zasadniczy folder zawierający wszystkie zasoby będące elementami składowymi projektowanej aplikacji. Zasoby podzielono na kilka grup:

drawable-* – pliki graficzne (w przykładzie plik ic_launcher.png). Folder zawiera kilka rozszerzeń służących do umieszczenia tego samego rysunku lub ikony w urządzeniach o różnych rozdzielczościach.

layout – pliki XML zawierające definicje GUI.

menus – pliki XML zawierające definicje menu.

values – pliki XML zawierające definicję różnych typów stałych. W przykładzie plik strings.xml zawiera definicje stałych typu string, do których mogą odwoływać się elementy oprogramowania.

Elementem każdej aplikacji jest plik AndroidManifest.xml umożliwiający definiowanie właściwości tworzonej aplikacji.

Folder src zawiera cały kod programu – wszystkie elementy dostępne w języku Java. W przypadku rozbudowanych aplikacji folder ten może składać się z wielu pakietów, a pakiety będą zawierały rozbudowaną strukturę podfolderów. Elementy grafiki (zdjęcia i ikony) umieszczane są w folderze res/drawable-*. Należy pamiętać, że dopasowanie grafiki do rozmiaru i parametrów ekranu urządzenia mobilnego wymaga od projektanta aplikacji przygotowania kilku wariantów tej samej grafiki i umieszczenia każdej z nich w odpowiednim podfolderze z taką nazwą, jaka używana jest w oprogramowaniu. Wyróżnia się kilka rozszerzeń tego podfolderu, na przykład:

• drawable-hdpi – zawiera grafikę o wysokiej rozdzielczości przeznaczoną dla dużych urządzeń (high dots per inch);

• drawable-mdpi – zawiera grafikę dla urządzeń o średniej rozdzielczości;

• drawable-xhdpi – zawiera grafikę o bardzo wysokiej rozdzielczości.

Rysunek 4. Przykład ikon startowych aplikacji dla różnych rozdzielczości urządzeń

Folder, w którym znajduje się projekt GUI (layouts), może zawierać definicję szczegółowych predefiniowanych nazw podfolderów precyzujących wygląd GUI dla różnych urządzeń:

• res/layout/activity_main.xml – domyślna definicja GUI;

• res/layout-small/activity_main.xml – definicja GUI dla małych ekranów;

• res/layout-large/activity_main.xml – definicja GUI dla dużych ekranów;

• res/layout-xlarge/activity_main.xml – definicja GUI dla bardzo dużych ekranów.

Możliwe jest jeszcze doprecyzowanie definicji w zależności od orientacji ekranu:

• res/layout-xlarge-land/activity_main.xml – definicja GUI dla bardzo dużych ekranów w układzie poziomym.

Przedstawiony sposób definiowania GUI dla aplikacji umożliwia wykorzystanie urządzeń o bardzo różnych rozmiarach i budowanie odmiennych interfejsów dla tej samej aplikacji. Układ w postaci listy, odpowiedni dla ekranu o małych rozmiarach, może być nieefektywny dla dużych ekranów, na których bezpośrednio obok listy można wyświetlać szczegóły wybranego elementu.

Rysunek 5. Projekt różnych interfejsów tej samej aplikacji dla urządzeń o odmiennych rozmiarach ekranu

Niektóre elementy składowe projektu mogą być przeglądane i modyfikowane na dwa sposoby – w postaci XML i graficznej:

• pliki zawierające projekt interfejsu GUI (layout) (rys. 6);

Rysunek 6. Widok projektu interfejsu: postać XML i graficzna

• pliki zawierające definicje (values) (rys. 7);

Rysunek 7. Widok pliku definicji: postać XML i graficzna

• plik AndroidManifest.xml.

Rysunek 8. Widok pliku AndroidManifest.xml: postać XML i graficzna

Nie ma znaczenia, która postać pliku jest modyfikowana – wszystkie zmiany wprowadzone w jednej postaci są przenoszone do drugiej przez środowisko Eclipse. Po wybraniu elementu w oknie projektu jego zawartość zostaje wyświetlona w głównym obszarze roboczym.

2. Pierwsza aplikacja „Witaj Świecie”

W tym rozdziale przedstawiona zostanie pierwsza kompletna, prosta aplikacja zawierająca jedną Aktywność z podstawowym interfejsem (layout). Aplikacja została utworzona za pomocą kreatora projektu Android Application Project. W dalszej części przedstawione są kolejne kroki kreatora oraz opis utworzonych plików.

1. Uruchomienie kreatora nowego projektu File/New Project.

Rysunek 9. Kreator projektu Android Application Project

2. Określenie parametrów aplikacji.

Rysunek 10. Kreator projektu Android – parametry aplikacji

Application Name – nazwa aplikacji wyświetlana na pasku tytułu aplikacji (może zawierać polskie znaki);

Project Name – nazwa projektu wyświetlana w oknie projektu;

Package Name – nazwa pakietu tworzona w folderze src, w którym będzie umieszczona klasa pierwszej Aktywności;

Minimum Required SDK – minimalny poziom SDK aplikacji (aplikacja może nie działać na urządzeniach z niższą wersją SDK);

Target SDK/Compile With – należy podawać maksymalny dostępny numer wersji SDK;

Theme – definicja stylu interfejsu aplikacji.

3. Konfiguracja elementów projektu.

Rysunek 11. Kreator projektu Android – elementy projektu

Create custom launcher icon – utworzenie ikony startowej projektu;

Create activity – utworzenie startowej Aktywności.

4. Wybór ikony startowej projektu.

Rysunek 12. Kreator projektu Android – ikona startowa

Kreator udostępnia domyślną ikonę aplikacji. Przyciski [Image], [Clipart], [Text] umożliwiają także wybór innej, wcześniej przygotowanej ikony.

5. Utworzenie startowej Aktywności.

Rysunek 13. Kreator projektu Android – Aktywność startowa

6. Określenie parametrów Aktywności.

Rysunek 14. Kreator projektu Android – parametry Aktywności startowej

Activity Name – nazwa klasy Aktywności (folder src);

Layout Name – nazwa pliku XML z definicją interfejsu (folder res/layout).

Po zaakceptowaniu wprowadzonych parametrów tworzona jest struktura projektu i generowane zawartości plików.

Elementy składowe aplikacji:

1. Plik src/../MainActivity.java

package com.example.witajswiecie;

import android.os.Bundle;

import android.app.Activity;

import android.view.Menu;

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//wywołanie interfejsu

setContentView(R.layout.activity_main);

}

}

2. Plik res/layout/activity_main.xml

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

xmlns:tools=”http://schemas.android.com/tools”

android:layout_width=”match_parent”

android:layout_height=”match_parent”

android:paddingBottom=”@dimen/activity_vertical_margin”

android:paddingLeft=”@dimen/activity_horizontal_margin”

android:paddingRight=”@dimen/activity_horizontal_margin”

android:paddingTop=”@dimen/activity_vertical_margin”

tools:context=”.MainActivity” >

<TextView

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:text=”@string/hello_world” />

</RelativeLayout>

Rysunek 15. Struktura projektu aplikacji „Witaj Świecie”

Rysunek 16. Graficzny podgląd GUI aplikacji „Witaj Świecie”

Plik res/values/strings.xml

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

<resources>

<string name=”app_name”>Witaj Świecie</string>

<string name=”action_settings”>Settings</string>

<string name=”hello_world”>Hello world!</string>

</resources>

Pliki ic_launcher.png w folderach drawable-* zawierają tę samą ikonę w różnych rozmiarach. Pozostałe pliki tworzone w projekcie mają znaczenie pomocnicze i na tym etapie ich analiza nie jest potrzebna.

Rysunek 17. Ikona startowa i widok aplikacji „Witaj Świecie” po uruchomieniu

3.  Emulator urządzenia z systemem Android AVD

W trakcie procesu tworzenia aplikacji nie jest konieczne posiadanie urządzenia mobilnego. Aplikacje można uruchamiać na emulatorze urządzenia z systemem Android – AVD (Android Virtual Device). Takie rozwiązanie znacznie upraszcza i obniża koszty stworzenia i testowania aplikacji, zwłaszcza testowania aplikacji na różnych wersjach systemu operacyjnego Android oraz na różnych rozmiarach i typach urządzeń. Należy jednak pamiętać, że ostateczne testy i sprawdzenie zachowania aplikacji muszą być wykonywane na docelowych urządzeniach, na których działanie może być odmienne od wyników uzyskiwanych na emulatorze.

W tym rozdziale przedstawione zostały właściwości AVD oraz sposób jego konfiguracji i uruchomienia. Interakcja z AVD odbywa się za pomocą klawiatury komputera, przycisków na emulatorze i myszki. Klikając kursorem myszki w ekran urządzenia wirtualnego, odwzorowujemy dotykanie ekranu. Jako gest przeciągania można wykorzystać kursor myszy z wciśniętym lewym klawiszem.

Aby skorzystać z AVD, należy najpierw przygotować (skonfigurować) jego wirtualne urządzenia. Menedżer AVD dostępny jest w menu Window/Android Virtual Device Manager. Rysunek 18 przedstawia okno menedżera AVD. Na liście wyświetlone zostają wcześniej zdefiniowane urządzenia AVD różniące się parametrami. Utworzenie nowego urządzenia AVD odbywa się przez wybranie przycisku New… .

Rysunek 18. Widok menedżera urządzeń AVD

Przykładowe konfiguracje dwóch różnych urządzeń są przedstawione na rysunku 19. Porównywane urządzenia AVD różnią się wersją systemu operacyjnego oraz rozmiarem ekranu.

Rysunek 19. Przykładowe parametry konfiguracyjne dwóch wirtualnych urządzeń AVD

Konfigurując nowe urządzenie, należy określić:

• nazwę AVD,

• rozmiar ekranu oraz jego rozdzielczość,

• rozmiar pamięci operacyjnej,

• rozmiar pamięci wewnętrznej,

• rozmiar karty SD (opcjonalnie),

• rodzaj dostępnych kamer.

Rysunki 20 oraz 21 przedstawiają wygląd okna emulatora po uruchomieniu dwóch różnych typów zdefiniowanych AVD.

Rysunek 20. Widok emulatora AVD 3,7 cala

Rysunek 21. Widok emulatora AVD 7 cali

Po zakończeniu procesu konfiguracji urządzenia są gotowe do użycia. Po uruchomieniu aplikacji (Run As…) wyświetlana jest lista dostępnych urządzeń AVD oraz rzeczywistych urządzeń podłączonych do komputera (patrz rys. 22). Z listy należy wybrać to urządzenie, na którym ma być zainstalowana i uruchomiona aplikacja.

Rysunek 22. Wykaz rzeczywistych i wirtualnych urządzeń do uruchomienia aplikacji

Należy pamiętać, że testowanie aplikacji nie powinno odbywać się wyłącznie z wykorzystaniem AVD. Ostateczne sprawdzenie poprawności działania stworzonej aplikacji powinno zostać wykonane na rzeczywistym urządzeniu. Rysunek 23 przedstawia wygląd tej samej aplikacji uruchomionej na AVD oraz na rzeczywistym urządzeniu.

Rysunek 23. Widok uruchomionej aplikacji na AVD i rzeczywistym urządzeniu

Korzystając z AVD, użytkownik ma dostęp do następujących funkcji:

• zmiana układu ekranu z poziomego na pionowy i odwrotnie – Ctrl+F11 i Ctrl+F12 lub 7 i 9 na klawiaturze numerycznej;

• zmiana głośności – „+” i „–” na klawiaturze numerycznej;

• funkcja „HOME” – Home;

• rozpoczęcie wybierania numeru telefonu – F3;

• włączenie funkcji wyszukiwania – F5;

• wyłączenie urządzenia – F7;

• menu programowe – F2;

• funkcja „BACK” – Esc.