Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Wykład 1 Wprowadzenie.

Podobne prezentacje


Prezentacja na temat: "Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Wykład 1 Wprowadzenie."— Zapis prezentacji:

1 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Wykład 1 Wprowadzenie

2 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Układ zajęć : Wykład: 15 godzin wykładu zorganizowane w postaci 15 jednogodzinnych wykładów Zaliczenie/egzamin w formie pisemnej Środa Sala E2 ( WEIE )

3 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Układ zajęć : Laboratorium: 15 godzin laboratoriów zoogranizowanych po dwie godziny,co dwa tygodnie Zaliczenie w postaci projektu Środa 11: :00 Sala 110 ( WEIE )

4 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Wykład – wykaz zagadnień: 1.Podstawy budowy i programowania urządzeń mobilnych (telefon komórkowy, PDA - Personal Digital Assistant) 2.Wprowadzenie do Javy MicroEdition (J2ME) 3.Grafika 2D i 3D w J2ME (API niskiego poziomu) 4.GUI w J2ME 5.Połączenia sieciowe w J2ME 6.Składowanie danych w urządzeniach mobilnych przy wykorzystaniu J2ME 7.Dystrybucja programów w J2ME 8.Programowanie i testowanie w Microsoft Mobile ASP.NET 9.Programowanie i testowanie w Symbian OS 10.Programowanie i testowanie w Adroid OS 11.Podstawy i rola Objective C w rozwiązaniach mobilnych Laboratorium: 1.Tworzenie oprogramowanie na telefony komórkowe w środowisku J2ME

5 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Literatura: Literatura podstawowa: 1 J2ME. Java dla urządzeń mobilnych. Ćwiczenia Krzysztof Rychlicki-Kicior ISBN: X Helion Krzysztof Rychlicki Kicior "J2ME. Praktyczne projekty" Helion ISBN: Marek Wierzbicki "Java. Programowanie obiektowe" Helion 2006 ISBN: Kim Topley "J2ME. Almanach" O'Reilly ISBN: Literatura uzupełniająca: 1.Miller B.M., Bisdikian Ch.: Bluetooth, Helion, Gliwice, White, James i Hemphill, Davies (2002) "Java 2 Micro Edition. Java in Small Things.", Manning Publications Co., Greenwich, Internet

6 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Podstawy budowy i programowania urządzeń mobilnych (telefon komórkowy, PDA - Personal Digital Assistant)

7 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ 1.Podstawy budowy i programowania urządzeń mobilnych (telefon komórkowy, PDA - Personal Digital Assistant) CDC( Connected Device Configuration ) Konfiguracja CDC (ang. Connected Device Configuration) jest konfiguracją środowiska Java ME zdefiniowanych przez Java Community Process. Konfiguracja CDC przeznaczona jest dla urządzeń wyposażonych w ok kB pamięci i pracujących z 32-bitowymi procesorami, czyli np. dla wideotelefonów konsol gier, zestawów audio-wideo, PDA. Specyfikacja znajduje się w dokumentacji JSR-36 i JSR-218. Jest ona przeznaczona dla urządzeń posiadających: stałe połączenie z siecią, 32 bitowy procesor, minimum 512KB dostępnej pamięci ROM, minimum 256KB pamięci operacyjnej RAM, graficzny interfejs użytkownika.

8 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Konfiguracja CLDC (ang. Connected Limited Device Configuration) jest bardziej ograniczoną wersją CDC i jest zdefiniowany przez Java Community Process. Konfiguracja CLDC jest przeznaczona dla urządzeń wyposażonych w około 512 kB pamięci i pracujących z 16- lub 32-bitowymi procesorami, czyli np. dla telefonów komórkowych, notesów elektronicznych czy pagerów. W stosunku do CDC, CLDC brakuje między innymi: obsługę działań na liczbach zmiennoprzecinkowych, uruchamianie kodu natywnego dzięki JNI (ang. Java Native Interface), obsługę słabych referencji, serializację obiektów, definiowanie przez użytkownika loaderów klas, obsługę mechanizmu debugowania.

9 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ J2ME - Mobile Information Device Profile (MIDP) MIDP jest uzupełnienie konfiguracji CLDC o odpowiednie klasy języka Java przeznaczone dla urządzeń mobilnych jak np. telefony komórkowe. Specyfikacja MIDP jest rozwijana przez Java Community Process (JCP). W 2000 r. udostępniono wersję 1.0. W 2002 roku wersję 2.0 MIDP. Programy napisane z wykorzystaniem MIDP noszą nazwę MIDletów (szerzej o MIDletach będzie mowa w dalszej części wykładu oraz na laboratorium). Uruchamiane są w środowisku K virtual machine.MIDletów Profil MIDP zawiera bardziej rozbudowaną obsługę platformy Java niż sama konfiguracja CLDC. MIDP wymagają zatem więcej pamięci. Specyfikacja CLDC wymaga przynajmniej 120 kB pamięci RAM (Random Accesss Memory) na przechowywanie specyfikacji MIDP, oraz co najmniej 32 kB na stos. Oprócz tego wymaga minimum 8 kB pamięci nieulotnej,jest ona potrzebna, aby MIDlety mogły zapisywać dane – np.. Adresy i nr telefony w przypadku MIDletu pracującego jako książka adresowa.Java Urządzenia korzystające z MIDP powinny być wyposażone w ekrany umożliwiające wyświetlenie co najmniej dwóch kolorów w rozdzielczości minimum 96 na 54 pikseli. Oprócz tego, do komunikacji z użytkownikiem posiadać powinny jedno lub więcej następujących mechanizmów: klawiatura telefonu, klawiatura QWERTY, ekran dotykowy. Ich wyposażenie musi także zapewniać obsługę protokołu HTTP 1.1.

10 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Wymagania programowe Minimalne założenia: Minimalne jądro do zarządzania sprzętem (np. obsługa przerwań, wyjątków, minimalne szeregowanie). Jądro musi zapewnić co najmniej jeden szeregowalny wątek, by uruchomić Virtualną Maszynę Javy. Mechanizm czytania i pisania z nieulotnej pamięci aby utrzymać API dostęp do czytania i pisania w bezprzewodowej sieci urzadzenia aby utrzymać API mechanizm zapewniający zapisywanie znaczników czasowych w rekordach zapisanych w zasobach pamięci trwałej minimalna zdolność do zapisywania w mapie bitowej graficznego wyświetlacza mechanizm przechwytujący dane z wejścia z jednego (lub więcej) z trzech urządzeń machanizm zarządzający cyklem życia aplikacji urządzenia

11 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Architektura MIDP

12 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Najniższy blok (MID) przedstawia poziom sprzętu urządzenia przenośnego. Jego część stanowi native system software, który zawiera system operacyjny i biblioteki użyte przez konkretne urządzenie. Powyżej jest warstwa oprogramowania, czyli CLDC. Tutaj także znajduje się K-Virtual Machine (KVM) oraz skojarzone biblioteki zdefiniowane przez specyfikację CLDC. CLDC posiada dwa rodzaje API: 1. MIDP: Zbiór API zdefiniowanych przez MIDP. 2. OEM-specific: Klasy, które mają dostęp do specyficznych funkcjonalności konkretnego urządzenia. Nie zapewniają zatem przenośności aplikacji, które z nich korzystają. Spowodowane jest to dużą różnorodnością urządzeń mobilnych, dostępnych na rynku. Na samym szczycie znajdują się MIDP: Aplikacja MIDP lub MIDlet, używa tylko API zdefiniowane przez specyfikację MIDP i CLDC. Używana najczęściej, zapewnia przenośność aplikacji. OEM-Specific: Aplikacje wykorzystujące specyficzne możliwości danych urządzeń. Aplikacje nie są przenośne. Native: rodzima aplikacja, która nie jest napisana w Javie. Pakiety i klasy Pakiety i klasy wchodzące w skład J2ME - MIDP: java.util.Timer - ułatwienie dla wątków w szeregowaniu zadań java.util.TimerTask - zadanie które może być szeregowane przez Timer javax.microedition.rms - mechanizm obsługi zasobu pamięci trwałej javax.microedition.midlet - definicja aplikacji MIDP, interkacji między nimi oraz środowiska w którym aplikacja działa javax.microedition.io - obsługa sieci oparta na CLDC javax.microedition.lcdui - interfejs użytkownika dla aplikacji

13 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Zmiany w MIDP 2.0, w stosunku do MIDP 1.0 Rozszerzony interfejs użytkownika Modyfikacja elementów takich jak : Popup ChoiceGroup czy Alert ekranu. Media Support Dodana obsługa dźwięku w formacie.wav, oraz możliwość wykorzystania mediów strumieniowych Game Support Game API to rozszerzenie zapewniające nowe możliwości twórcom gier w zakresie wykorzystania grafiki np. poprzez długo oczekiwane sprite'y i warstwy. Expanded Connectivity(Rozszerzona Łączność) Wsparcie dla standardów HTTP, HTTPS, datagramów, gniazd oraz komunikacji wykorzystującej port szeregowy. Oprócz tego oferuje wsparcie szyfrowania transmisji za pomocą protokołów SSL, WTLS czy podpisywania midletów certyfikatami X.509. Push Architecture Model push, umożliwia przesyłanie danych z serwera do aplikacji, np aktywacje zainstalowanych na urządzeniu midletów, przesyłanie komunikatów i powiadomień wprost do aplikacji. Over-the-air (OTA) Provisioning Ttechnika instalowania, uruchamiania i aktualizacji midletów over-the-air (OTA), stała się oficjalnie częścią specyfikacji. End-to-end Security Wsparcie dla technologii takich jak : HTTPS i wykorzystuje istniejące standardy, takie jak SSL, WTLS, czy podpisu elektronicznego.

14 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ J2ME – MIDlet, budowa i przykład

15 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ import javax.microedition.midlet.MIDlet; public class PierwszyMIDlet extends MIDlet { public void startApp(){ } public void pauseApp(){ } public void destroyApp(boolean){ } /** Opcjonalny konstruktor:**/ } Szkielet MIDletu

16 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ MIDlet musi mieć również publiczny bezargumentowy konstruktor : public NazwaKlasy() {} W przypadku zwykłej aplikacji, napisanej w języku JAVA, metoda wywoływania inicjalizacji obiektów była statyczną metodą main(), w przypadku MIDletu jest to public void startApp() {} MIDlet może ulec zawieszeniu, w tym celu wywołać można metodę public void pauseApp() {} W tym momnecie MIDlet zwalnia swoje zasoby, zawieszone jest działanie "timerów". Ekran wówczas może być przekazany np. innemu MIDletowi. W stan zawieszenia może również dobrowolnie wprowadzić siebie aplikacja. Dokonuje tego wywołując metodę Public notifyPaused() {} W przypadku wywołania metody notifyPaused() platforma nie wywołuje już metody pauseApp(). Zakłada, że MIDlet wywołując metodę notifyPaused() jest już gotowy do przejścia w stan zawieszenia. Dlatego metoda pauseApp() często poprzedza wywołanie metody notifyPaused().

17 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Aby powrócić ze stanu zawieszenia w stan aktywny, MIDlet wywołuje bezargumentową metodę resumeRequest() {} Informuje ona informuje maszynę wirtualną, że MIDlet jest gotowy do działania. Uruchomiony zostanie, gdy tylko przydzielone mu będą odpowiednie zasoby, co nastąpi, gdy takie będą (np.. Zwolni je inny MIDlet). W przypadku powrotu ze stanu zawieszenia w stan aktywny, ponownie wywoływana jest metoda Public startApp() {} Oczywiście rodzi to niebezpieczeństwo podwójnego alokowania pamięci podczas inicjacji obiektów w tej metodzie. Trzeba więc albo inicjować obiekty w konstruktorze lub wprowadzić inne metody zabezpieczeń przed dublowaniem się obiektów. Zakończyć działanie MIDletu można za pomocą metody : public void destroyApp(boolean) {} Tutaj usuwanie są obiekty, ewentualne dane zapisywane są w pamięci trwałej. MIDlet można również zakończyć wywołując metodę notifyDestroyed() Platforma nie wywołuje wówczas metody destroyApp(). Przyjmuje, iż aplikacja została już przygotowana do zamknięcia.

18 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Grafika 2D i 3D w J2ME (API niskiego poziomu) Źródło : O'reilly - j2me in a nutshell, str. 397

19 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Zatem klasa Canvas pozwala na dostęp do pojedynczych pikseli wyświetlanych na ekranie urządzenia. Zawiera metody pozwalające np. na rysowanie figur geometrycznych, definiowania ich koloru, czy wyświetlanie tekstu (z uwzględnieniem wielkości, czcionki, czy pozycji na ekranie.) Nie definiuje natomiast elementów interfejsu użytkownika, takich jak przycisku czy pola tekstowe. Te elementy udostępniają inne klasy, i są to elementu należące do API wysokiego poziomu. Klasa Canvas jest klasą dziedziczącą po klasie Displayable. Udostępnia ona powierzchnię ekranu do dowolnych operacji graficznych. Nie można dodać do niej komponentów, pozwala jedynie na niskopoziomowe operacje graficzne. Klasa Canvas nie udostępnia żadnych możliwości graficznych. Jest to zadanie klasy Graphics. Natomiast klasa Canvas przenosi obraz z obiektu klasy Graphics na ekran. Klasy Canvas oraz Graphics zawarte są w pakiecie javax.microedition.lcdui, zatem wymagane jest użycie Dodatkowej paczki: import javax.microedition.lcdui.*;

20 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Klasa Canvas zawiera metody, dzięki którym możemy sprawdzić cechy urządzenia (ekranu). Poniższe metody pozwalają pozyskać wymiary ekranu (w pikselach) i sprawdzić, czy urządzenie dostarcza podwójne buforowanie: public int getHeight() public int getWidth() public boolean isDoubleBuffered() Podwójne buforowanie polega na tym, iż zmiany w wyglądzie nie są widoczne od razu dla użytkownika, a przygotowywane są w buforze poza ekranem, a następnie wyświetlanie na nim. Pomaga to uniknąć migotania ekranu. Z kolei informację o liczbie wyświetlanych przez urządzenie kolorów możemy poznać dzięki metodom z klasy Display: public boolean isColor() public int numColors()

21 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Klasa Canvas wywiedziona z Displayable. A już Displayable daje możliwość dołączenia do niej komend. Można zatem dołączać je do obiektów klas rozszerzających klasę Canvas. Metoda korzystania z klasy Canvas : będziemy definiowanie klasy wywodzące się z niej, wypełniając jedyną abstrakcyjną w niej metodę: protected abstract void paint(Graphics g) Korzystając z podanego nam jako argument (przez maszynę wirtualną) argumentu typu Graphics, będziemy w tej metodzie definiować wygląd naszego obiektu. Oprócz tego Canvas posiada także wiele zdefiniowanych metod, pozwalających na np. Ponowne narysowanie obiektu (metoda repaint()), reagować na naciśnięcie lub zwolnienie przycisku klawiatury, czy zdarzenie wygenerowane przez inne urządzenie wejściowe (np. Dotkniecie ekranu dotykowego czy przesunięcie rysika). Do tego dochdzą metody pozwalające sprawdzić właściwości ekranu.

22 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Przykład użycia dla Canvas private class Ekran extends Canvas{ String tekst = ; int szerokosc,wysokosc; public Ekran(String napis){ tekst = napis; szerokosc = getWidth(); wysokosc = getHeight(); } public paint(Graphics g){ g.setColor(0xffffff); //zmiana aktualnego koloru // Rysowanie prostokąta o rozmiarze ekranu g.fillRect(0, 0, ScreenWidth, ScreenHeight); g.setColor(255,0,0); //zmiana aktualnego koloru // Wyświetlenie tekstu na środku ekranu g.drawString(label, ScreenWidth/2, ScreenHeight/2, g.HCENTER|g.TOP); repaint(); //Narysowanie ekranu od nowa. }

23 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Przykład użycia dla Canvas c.d. import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.*; public class PierwszyMIDlet extends MIDlet { private Display display; private class Ekran extends Canvas{ String tekst = ; int szerokosc,wysokosc; public Ekran(String napis){ tekst = napis; szerokosc = getWidth(); wysokosc = getHeight(); } public paint(Graphics g){ g.setColor(0xffffff); //zmiana aktualnego koloru // Rysowanie prostokąta o rozmiarze ekranu g.fillRect(0, 0, ScreenWidth, ScreenHeight); g.setColor(255,0,0); //zmiana aktualnego koloru // Wyświetlenie tekstu na środku ekranu g.drawString(label, ScreenWidth/2, ScreenHeight/2, g.HCENTER|g.TOP); } public void startApp(){ display = Display.getDisplay(this); display.setCurrent(new Ekran(Pierwszy MIDlet")); } public void pauseApp(){ } public void destroyApp(boolean unconditional){ }

24 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ import javax.microedition.midlet.*; import javax.microedition.lcdui.*; class ImageInCanvas extends Canvas { Image image; public ImageDemoCanvas () { try { image = Image.createImage (/logo.png); } catch (IOException e) { throw new RuntimeException (Unable to load Image +e); } public void paint (Graphics g) { g.setGrayScale (255); g.fillRect (0, 0, getWidth (), getHeight ()); g.drawImage (image, 0, 0, Graphics.TOP | Graphics.LEFT); } Przykład klasy pozwalającej na wyświetlanie obrazów na ekranie urządzenia

25 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ public int getColor(); public void setColor( int RGB); public void setColor( int red, int green, int blue); public Font getFont(); public void setFont( Font font); public int getTranslateX(); public int getTranslateY(); public void clipRect(int x, int y, int width, int height); public void drawArc(int x, int y, int width, int height, // native int startAngle, int arcAngle); public void drawChar(char character, int x, int y, // native int anchor); public void drawChars(char[] data, int offset, // native int length, int x, int y, int anchor); public void drawImage(Image img, int x, int y, // native int anchor); public void drawLine( int x1, int y1, int x2, int y2); // native public void drawRect(int x, int y, int width, int height); // native public void drawRoundRect(int x, int y, int width, // native int height, int arcWidth, int arcHeight); public void drawString(String str, int x, int y, // native int anchor); public void drawSubstring(String str, int offset, int len, // native int x, int y, int anchor); public void fillArc(int x, int y, int width, int height, // native int startAngle, int arcAngle); public void fillRect(int x, int y, int width, int height); // native public void fillRoundRect(int x, int y, int width, // native int height, int arcWidth, int arcHeight); public void setClip( int x, int y, int width, int height); public void translate( int x, int y); Ciekawsze metody klasy Graphics

26 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Oprócz operacji związanych z ekranem urządzenia, klasa Canvas zawiera także metody obsługi zdarzeń z urządzeń wejściowych, takich jak klawiatura, czy ekran dotykowy, czy np. Rysik (w przypadku urządzeń typu PDA). W przypadku klawiatury mamy do dyspozycji następujące metody : protected void keyPressed(int keyCode) -Klawisz naciśniety protected void keyReleased(int keyCode) -Klawisz puszczony protected void keyRepeated(int keyCode) -Klawisz przytrzymamy Niektóre klawisze zdefiniowane są na stałe: KEY_NUMn - gdzie n, to oznaczenie kolejnych przycisków (od 0 do 9), KEY_STAR - klawisz oznaczający klawisz ze znaczkiem gwiazdki, KEY_POUND - klawisz ze znaczkiem hash.

27 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ private class Ekran extends Canvas { public konstruktor() { String s = ""; } // Pozostałe instrukcje // public void paint(Graphics g){ g.setColor(0,255,0); g.fillRect(ScreenWidth/2, ScreenHeight/2, ScreenWidth, ScreenHeight); g.setColor(0,0,0); g.drawString(s, ScreenWidth/2, ScreenHeight/2, g.HCENTER|g.TOP); } public void Klawisz(){ public void keyPressed (int key) { s = "Naciśnięty klawisz: "+key; repaint(); repaint(); } public void keyReleased (int key) { s = "Puszczony klawisz: "+key; repaint(); repaint(); } public void keyRepeated (int key) { s = "Przytrzymany klawisz: "+key; repaint(); repaint(); } Przykład użycia dla Canvas (obsługa zdarzeń)

28 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ GUI w J2ME

29 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ GUI J2ME (API wysokiego poziomu) Źródło : O'reilly - j2me in a nutshell, str. 397

30 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Komponenty wysoko-poziomowego GUI: Alert – Służy do wyświetlania wiadomości o nagłym zdarzeniu. Może zawierać zarówno tekst jak i grafikę. Alert testAlert = new Alert(Belkla gorna", Tresc alertu.", null, AlertType.INFO); testAlert.setTimeout(Alert.FOREVER); Typ alertuOpis ALARMInformowanie użytkownika o nagłych zdarzeniach CONFIRMATIONProśba do użytkownika o potwierdzenia akcji ERRORInformacja o błędzie INFOInformacja dla użytkownika WARNINGOstrzeżenie o niebezpiecznych operacjach

31 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Komponenty wysoko-poziomowego GUI: ChoiceGroup – element dający możliwość wyboru z listy opcji. Może zawierać tekst jak i grafikę. Obrazek jest połozy obok tekstu i traktowany jako jeden obiekt. private ChoiceGroup cg_kierunek, cg_przystanek, cg_typ cg_typ = new ChoiceGroup("Typ srodka komunikacji : ", Choice.EXCLUSIVE); cg_typ.append("Tramwaj", null); cg_typ.append("Autobus", null); TextBox – kontrolka umożliwiająca użytkownikowi na wpisanie i edycje tekstu. Ma ustaloną maksymalną ilość tekstu. Maksymalny rozmiar tekstu może być większy od ekranu, na którym ma zostać wyświetlony, wtedy automatycznie pojawiają się paski przewijania. private TextBox tekst; tekst = new TextBox(Belka górna",Tekst domyślny",20,0); Trzeci parametr oznacza maksymalny rozmiar tekstu, czwarty parametr pozwala na włączenie ograniczeń co Do edycji tekstu.

32 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ TekstField – podobnie jak TextBox słuzy do wprowadzania tekstu, z ta różnica, ze pozwana na Wprowadzenie masek,np. w przypadku wpisywania nr telefonu klawiatura automatycznie przełączy Na tryb wprowadzania liczb. private TextField tekst; tekst = new TextField(Belka górna",Tekst domyślny",20,0); Trzeci parametr oznacza maksymalny rozmiar tekstu, czwarty parametr pozwala na włączenie ograniczeń co Do edycji tekstu. Komponenty wysoko-poziomowego GUI: Ticker – pasek znajdujący się na górze ekranu, w którym przejawia się przewijający się tekst. Parametry takie jak szybkość czy kierunek przesuwania się tekstu są zdefiniowanie przez urządzenie I nie ma możliwości ich zmiany. Ticker aTicker = new Ticker (Ticker J2ME!"); Forma.setTicker(aTicker);

33 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Gauge – Element odpowiadający za działanie wszelkiego rodzaje paski postępu, może tez Służyć jako regulator poziomu jakiejś wartości. private Gauge glosnosc; glosnosc = new Gauge(Glosnosc",true,10,1); Pierwszy parametr określa etykietę regulatora Drugi parametr określa, czy można zmieniać jego ustawienia Trzeci parametr określa wartość maksymalną Czwarty parametr oznacza wartość, jaka suwak przymnie po zainicjowaniu. Na ekranie wyświetlany na raz może być tylko jeden obiekt z wyżej wymienionych, ponieważ na raz wyświetlany może być tylko jeden obiekt dziedziczący po klasie Screen. A co jeśli chcemy Wyświetlić na raz kilka obiektów, np. TextBox z podpisem ? Private TexBox teskt; / reszta instrukcji / Public startApp(){ display = Display.getDisplay(this); tekst = new TextBox("Belka górna","Tekst domyślny",20,0); display.setCurrent(tekst); }

34 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ W przypadku, gdy chcemy wyświetlić na ekranie na raz kilka elementów, trzeba je umieścić w jakimś kontenerze. W tym celu można zastosować element Form. Form zajmuje się wyświetlaniem i pozycjonowaniem elelmentów Znajdujących się wewnątrz. public void startApp(){ display = Display.getDisplay(this); txt = new TextField("Belka górna","Tekst domyślny",20,0); cg_typ = new ChoiceGroup("Typ srodka komunikacji : ", Choice.EXCLUSIVE); forma1 = new Form("Demo Form"); cg_typ.append("Tramwaj", null); cg_typ.append("Autobus", null); forma1.append(cg_typ); forma1.append(txt); display.setCurrent(forma1); }

35 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Oprócz Form istnieje jeszcze inny komponent, pozwalający na grupowanie wewnątrz innych elementów graficznych. Jest to komponent List, który działa nieco podobnie do elementu choice. Użytkownik może przeglądać elementy tej listy, a dopiero wybranie któregoś elementu powoduje jakaś akcje Dla aplikacji. Dokonuje się tego za pomocą komponentu Command. CommandListener Jeśli klasa implementuje interfejs CommandListener to można tworzyc w niej interaktywne przyciski typu Button. Jest to dość popularne rozwiązanie do obsługi komend. W J2ME niestety nie mamy żadnych buttonów itp. więc interakcja odbywa się poprzez klawisze na telefonie. Aby ją obsłużyć należy dodać obiekt typu Command do obiektu tworzącego formę w aplikacji. Konstruktor obiektu Command wygląda następująco: publi Command(String tekst, int typ, int priorytet) tekst - nazwa wyświetlana typ - typ komendy (Ok, Exit, Cancel, Help) priorytet - służy do układania kolejności. Można też wg niego rozróżniać komendy

36 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ public class PierwszyMIDlet extends MIDlet implements CommandListener { private Display display; private TextBox tekst; private TextField txt; public Form forma1; private ChoiceGroup cg_typ; public void startApp(){ display = Display.getDisplay(this); txt = new TextField("Belka górna","Tekst domyślny",20,0); cg_typ = new ChoiceGroup("Typ srodka komunikacji : ", Choice.EXCLUSIVE); forma1 = new Form("Demo Form"); cg_typ.append("Tramwaj", null); cg_typ.append("Autobus", null); forma1.append(cg_typ); forma1.append(txt); forma1.addCommand(new Command("Exit",Command.EXIT,0)); forma1.setCommandListener(this); display.setCurrent(forma1); } public void commandAction(Command c, Displayable d) { if (c.getCommandType()==Command.EXIT) notifyDestroyed(); }

37 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ public class PierwszyMIDlet extends MIDlet implements CommandListener { private Display display; private TextField a,b,Wynik; public Form forma1; private Command exitCommand; private Command calculateCommand; private ChoiceGroup dzial_typ; public void startApp(){ display = Display.getDisplay(this); a = new TextField(Liczba 1: ",0",20,0); b = new TextField(Liczba 2: ",0",20,0); Wynik = new TextField(Wynik: ",0",20,0); dzial_typ = new ChoiceGroup(Wybierz dzialanie : ", Choice.EXCLUSIVE); forma1 = new Form("Demo Form"); dzial_typ.append(dodaj", null); dzial_typ.append(odejmnij", null); forma1.append(dzial_typ); forma1.append(a); forma1.append(b); forma1.append(Wynik); exitCommand = new Command("Wyjście", Command.SCREEN, 2); calculateCommand = new Command("Oblicz", Command.SCREEN, 1); forma1.addCommand( exitCommand ); forma1.addCommand( calculateCommand ); forma1.setCommandListener(this); display.setCurrent(forma1); }

38 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ public void commandAction(Command c, Displayable s) { if (c == exitCommand) { destroyApp(false); notifyDestroyed(); } if (c == calculateCommand) { float A,B,wynik; try { A = Float.parseFloat(a.getString().equals("")?"0":a.getString()); B = Float.parseFloat(b.getString().equals("")?"0":b.getString()); } catch (Exception e) { A=B=0; } wynik = A + B; wynik.setString(+wynik); }

39 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Połączenia sieciowe w J2ME

40 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Źródło:

41 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Źródło : O'reilly - j2me in a nutshell, str. 326

42 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Urządzenia mobilne prawie zawsze posiadają na możliwość komunikacji z innym urządzeniami tego typu oraz często także z Internetem. W przypadku J2ME problem ten rozwiązano tworząc Interfejs Connection, który reprezentuje dowolne połączenie (np. za pomocą protokołu http czy też innego). Z interfejsu tego wywodzą się interfejsy realizujące różne rodzaje połączenia. Jest on klasą bazową dla wielu metod przesyłania danych zarówno w sieci jak i w obrębie urządzenia. Interfejs Connection ma tylko jedną metodę: public abstract void close() throws IOException interfejs reprezentujący dowolne połączenie nie ma metody otwierającej takie połączenie. Zestawienie połączenia jest możliwe za pomocą odpowiednich metod klasy Connector. Klasa Connector zawiera tylko statyczne metody i są to metody pozwalające utworzenie referencji do interfejsu Connection i realizacji połączenia danego typu. Metody te wyglądają następująco : public static Connection open(String nazwa) throws IOException public static Connection open(String nazwa,int tryb_dostepu ) throws IOException public static Connection open(String nazwa,int tryb_dostepu,boolean czas) throws IOException

43 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Metody przedstawione powyżej zwracają referencję do interfejsu Connection oraz pozwalają na nawiązanie połączenia z innym urządzeniem. Urządzenie jest określane w pierwszym argumencie. Połączenie może zachodzić w trybie czytania, pisania, lub obydwu jednocześnie, przy czym tryb połączenia w obie strony jest przyjmowany domyślnie. Oprócz tego czas oczekiwania na połączenie może być ograniczany. Każda z metod open zwraca referencję do obiektu utworzonego na podstawie klasy implementującej Connection. Mogą to być referencje klasu HttpConnection (dla protokołu http), StreamConnection (dla gniazd), DatagramConnection (dla datagramów). Postać nazwy urządzenia, z którym chcemy nawiązać polaczenie wygląda następująco : {protokół}:[{adres_sieciowy}][{parametry}] Poniżej przekłady nazw dla różnych urządzeń : socket://www.kojot.test.com:8080 datagram://:555 file:///home/user/plik

44 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Protokół HTTP Protokół ten wykorzystywany jest do przesyłania danych pomiędzy serwerem WWW, a klientem, a w tym celu korzysta z gniazd. Jest też jest jedynym protokołem, o którym się zakłada, że jest obsługiwany przez każde urządzenie spełniające założenia MIDP. Jednakże w przypadku małych urządzeń takich jak telefon komórkowy istnieje problem braku wbudowanej przeglądarki WWW. Wprawdzie producent ma obowiązek implementacji protokołu http, ale czasem jest to rodzaj bramy,która tłumaczy komunikaty http na postać rozumianą przez urządzenie. Poniżej przykład obrazujący sposób nawiązania połączenia z danym adresem internetowym : hc = (HttpConnection)Connector.open("http://www.wp.pl Connector.READ_WRITE"); Jak widać podaliśmy dwa parametry metodzie open : nazwę urządzenia (http), adres (www.wp.pl), oraz tryb dostępu. Nie narzuciliśmy ograniczenia czasu dostępu (np. zakładamy, że dysponujemy dobrym łączem). Podstawowe czynności które należy wykonać, aby skorzystać z HttpConection do pobrania strony www : Tworzymy łańcuch zawierający adres URL strony WWW którą chcemy pobrać, następnie wywołać metodę open() i utworzyć obiekt klasy HttpConnection. Czasem trzeba ustalić rodzaj żądania oraz parametry. Domyślnym żądaniem jest GET. Następnie należy sprawdzić za pomocą metody getResponseCode() czy serwer odpowiedział pozytywnie na żądanie. Podobnie jak w przypadku magazynów musimy posłużyć się strumieniami, zatem wywołujemy metodę openInputStream() lub openDataInputStream() i w ten sposób uzyskujemy dostęp do strumienia wejściowego. Na koniec zamykamy strumień wejściowy.

45 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Przykład wykorzystania klasy HTTPConnection: public void startApp() throws IOException{ HttpConnection hc = null; InputStream is = null; int ch; try{ hc = (HttpConnection)Connector.open("http://www.wp.pl Connector.READ_WRITE"); is = hc.openInputStream(); while ((ch = is.read()) != -1) { str.append((char)ch); } finally { if (is != null) is.close(); if (hc != null) hc.close(); } import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection;

46 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Zatem obiekt typu HttpConection może być wykorzystywany do przesyłania danych w postaci strumieni danych wejściowych i wyjściowych, dodatkowo można określić ich długość, typ i sposób kodowania. Metody te pochodzą z klasy ContentConnection. Serwer www wysyła odpowiedź, którą można odebrać za pomocą metody getResponseCode(), poniżej przykłady odpowiedzi : stałe klasy HttpConnectionZnaczenie HTTP_OKZasób dostępny bez błędu (200) HTTP_MOVED_PERMZasób przeniesiony pod inny adres i jest podany w nagłówku (301) HTTP_SEE_OTHERNależy wysłać żądanie GET pod adres podany w nagłówku (303) HTTP_BAD_REQUESTŻądanie dotarło w postaci zniekształconej i nie może być zrealizowane (400) HTTP_FORBIDDENŻądanie nie może być zrealizowane (403) HTTP_NOT_FOUNDZasób nie istnieje (404)

47 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Zapytania i odpowiedzi w protokole http Komunikat przesyłający żądanie do serwera www składa się z trzech elementów Wiersz zawierający żądanie HTTP, po nim nowa linia, Nagłówki żądania, każdy w nowym wierszu, po nich linia wolna – jest to element opcjonalny, Dane dodatkowe potrzebne do wykonania żądania - występuje gdy jest niezbędny. Przykłady żądań : ŻądanieZnaczenieWartość GETHttpConnection.GETProśba o przesłanie pliku o podanej ścieżce HEADHttpConnection.HEADJak wyżej, z tą różnica, że wysyłane są jedynie nagłówki, bez danych POSTHttpConnection.POSTMetoda stosowana, gdy na stronie są formularze. Postać parametrów żądań umieszczanych w adresie lub w ciele żądania wygląda następująco: nazwa1=wartość&nazwa2=wartość&nazwa3=wartość

48 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Gniazda ( Socket ) Gniazda w J2ME nie różnią się zbytnio od gniazd z innych wersji JAVY, czy też innych języków (np. C/C++). Jedyna różnicą jest to, że standard MIDP nie wymaga obsługi gniazd. Powodowane jest to tym, że gniazda wykorzystują protokół TCP/IP, a urządzenia mobilne nie koniecznie muszą mieć dostęp do Internetu i w ogóle obsługiwać stosu TCP/IP. Klasa StreamConnection dziedziczy z Connection. Zatem chcą uzyskać połączenie za pomocą gniazda, z serwerem świadczącym usługi na jakimś porcie musimy utworzyć połączenie za pomocą metody open(). Otwarcie połączenia może mieć jedną z poniższych postaci : StreamConenection sc = (StreamConnection)Connector.open("socket://:32839"); StreamConenection sc = (StreamConnection)Connector.open("socket:// :80") StreamConenection sc = (StreamConnection)Connector.open("socket://jakis_adres:80") ; Sposób nawiązywania połączenia jest nadal taki sam. Jak widać podaliśmy dwa parametry metodzie open : nazwę urządzenia (socket), i adres (www.wp.pl). Jeżeli połączenie może być nawiązane, to należy otworzyć strumień wyjściowy i za pośrednictwem tego strumienia wysłać polecenie do nasłuchującego serwera. Otwarcie strumienia wyjściowego może mieć poniższą postać: OutputStream os = sc.openOutputStream();

49 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Za pomocą tego strumienia należy wysłać zrozumiałe dla serwera zapytanie. Jeżeli będzie to serwer www to zapytanie może mieć postać: "GET / HTTP/1.1\n\n" Zapytanie należy przesłać jako ciąg bajtów. Należy pamiętać, że urządzenie może buforować dane i polecenie niekoniecznie natychmiast zostanie wysłane. Zamknięcie strumienia Następnie należy otworzyć strumień wejściowy oczekiwać na odpowiedź serwera. Otwarcie strumienia wejściowego ma poniższą postać. OutputStream os = sc.openInputStream() ; Dane napływające to również ciąg bajtów o nieznanej długości. Jeżeli znany jest format danych przesyłanych przez serwer, to można skorzystać z przesyłanych informacji. Można odczytać pewną liczbę bajtów, należy pamiętać, że dane nie muszą napływać w jednolitych porcjach. Dane można odczytać podobnie jak w poprzednim przykładzie.

50 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Przykład wykorzystania gniazda (Socketa): String ulr= SocketConnection c = null; InputStream s = null; OutputStream os; try { c = (SocketConnection)Connector.open(url); s = c.openInputStream(); os = sc.openOutputStream(); //wyslanie zapytania, oczekiwanie na odebranie danych… } catch (ConnectionNotFoundException e) { // Połączenie nie może być zrealizowane } catch (IllegalArgumentException e) { //Błędne zapytanie } finally { try { if (s != null) s.close(); if (c != null) c.close(); }

51 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Połączenia sieciowe w J2ME - bluetooth

52 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Składowanie danych w urządzeniach mobilnych przy wykorzystaniu J2ME

53 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Pamięć nieulotna Midlety niekiedy muszą zapamiętywać i przechowywać informacje na stałe, są to dane wprowadzane przez użytkowników(np. dane konfiguracyjne aplikacji). Specyfikacja MIDP wymaga, by wszystkie urządzenia posiadały pamięć nieulotną, czyli taką, w której będzie przechowywana informacja nawet wtedy, gdy midlet kończy swoje działanie lub w sytuacji, gdy urządzenie zostanie fizycznie wyłączone. W praktyce problem ten rozwiązywany jest różnie przez różne urządzenia, chociaż dla programisty nie ma to żadnego zdarzenia, ponieważ interfejs jest jeden. Informacje są przechowywane w postaci kolekcji rekordów (record store). Każda kolekcja rekordów jest identyfikowana przez nazwę, która jest rzecz jasna unikalna. Midlety dostęp mają jedynie do swoich kolekcji, nie mają za to dostępu do kolekcji rekordów innych Milletów. Nie mają również dostępu do danych utworzonych przez inne aplikacje. Sposób zapisu danych może być różny na różnych modelach u różnych producentów. Jednak dla J2ME został opracowany uniwersalny sposób dla wszystkich urządzeń o nazwie RMS - Record Management System.

54 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Nad zbiorami rekordów w J2ME czuwa klasa RecordStore. Aby utworzyć jakiś zbiór należy wywołać jej statyczną metodę: public static RecordStore openRecordStore(String nazwa, boolean tryb) Pierwszy parametr określa nazwę zbioru (nazwa może być dowolna) Drugi parametr oznacza tryb dostępu / tworzenia do zbioru -Jeśli ustawiony jest na true wtedy, gdy w momencie próby otwarcia nie istnieje – zostanie utworzony nowy. W przypadku wartości false można otworzyć jedynie istniejący magazyn. W przypadku,gdy nie istnieje – wyrzucany jest wyjątek. W MIDP 2.0 dodano dwie nowe metody openRecordStore o innych parametrach i bardziej specjalistycznych zadaniach. M.in. z ustawieniem uprawnień i przypisywaniem danego zbioru do konkretnego MIDletu. Metoda zwraca nam utworzony (lub otworzony) zbiór na którym możemy wykonywać operacje zapisu i odczytu. W razie błędów generowane są następujące wyjątki: RecordStoreNotFoundException - zbiór nie istnieje (w przypadku gdy nie ma być automatycznie utworzony) RecordStoreFullException - brak dostępnej pamięci IllegalArgumentException - błędna nazwa zbioru RecordStoreException - inny błąd

55 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Zatem: RecordStore store = RecordStore.openRecordStore(ZbiorTestowy", true); //wyrzuci wyjątek RecordStoreNotFoundException jeśli zbiór nie istnieje RecordStore secondStore = RecordStore.openRecordStore(ZbiorTestowy", false); Po zakończeniu pracy z kolekcją można ją zamknąć : public static void closeRecordStore(); lub także skasować : public static void deleteRecordStore() ; // O tym w dalszej części wykładu

56 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Magazyn rekordów składa się z rekordów, które są tablicą bajtów. Każdy rekord ma przypisany identyfikator – jest to liczba całkowita dodatnia. Nie jest ona częścią rekordu, tylko jest przydzielana podczas dopisywania rekordu do magazynu. Gdy dana wartość zostanie raz przydzielona to nie może już zostać przydzielona żadnemu innego rekordowi, nawet w sytuacji,gdy rekord ten zostanie usunięty z magazynu. Metoda dodająca nowy rekord do magazynu : public static int addRecord(byte[] dane,int od_którego,int ile) ; dodaje nowy rekord do zbioru i zwraca nam ID rekordu. Parametr pierwszy to dane do zapisu w postaci tablicy bajtów. Parametr drugi : od którego bajtu ma być zapisywane Parametr trzeci: ile bajtów ma zostać zapisanych. - void setRecord(int recordId, byte[] newData, int offset, int numBytes) ta metoda służy do zastąpienia rekordu nowym. Dodatkowym parametrem jaki trzeb podać jest ID rekordu który ma być zastąpiony, reszta jak powyżej.

57 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Każdy rekord, jak wspomniano wyżej,jest tablicą bajtów. Zatem aby umieść w nim jakieś dane, trzeba je najpierw zamienić na tablicę bajtów. Można to oczywiście przeprowadzić na wiele sposób, przykładowo za pomocą klas DataOutputStream i ByteArrayOutputStream. Przykład 1. Sposób zapisu rekordu 1. Tworzymy nowy magazyn : RecordStore nowy_magazyn = null; Klasa Dane będzie służyć to tworzenia obiektów zawierających dane do zapisu w magazynie class Dane{ String DaneTxt; int DaneNum; Dane(String a, int b){ DaneTxt = a; DaneNum = b; } }

58 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ private byte[] zapiszStrumien(Dane przyklad) throws IOException { ByteArrayOutputStream bs = new ByteArrayOutputStream(); DataOutputStream os = new DataOutputStream(bs); os.writeUTF(przyklad.daneTxt); os.writeInt(przyklad.daneNum); return bs.toByteArray(); } 2. Zapisujemy dane do strumienia : 3. Zapisujemy dane w postaci strumienia do rekordu : private void zapiszRecord(Dane przyklad)throws IOException,RecordStoreException { try{ byte[] dane = zapiszStrumien(przyklad); id = nowy_magazyn.addRecord(dane,0,dane.length); }catch(Exception e){System.out.println(e); } } zmienna id (niezdefiniowana nigdzie w metodzie zapiszRecord ) może służyć do wyświetlania identyfikatora nowego rekordu, jeśli jest to do czegoś potrzebne.

59 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Ważne jest aby zamykać strumień i zbiór, urządzenia mobilne nie posiadają dużo pamięci więc należy je oszczędzać (nie zamykanie strumieni może być jedną z przyczyn tzn. wycieków pamięci). Podczas każdej operacji addRecord, setRecord i deleteRecord na zbiorze inkrementowana jest jego wersja. Wersję zbioru można otrzymać poprzez wywołanie int getVersion(). Odczyt danych z rekordów można realizować na kilka sposobów, na przykład podając identyfikator rekordu w magazynie. Metoda to wykonująca wygląda następująco : byte[] dane = nowy_magazyn.getRecord(id); Jeśli nie znamy zbiorów MIDletu możemy pobrać ich nazwy za pomocą metody statycznej RecordStore.listRecordStores(); Zwraca ona tablicę Stringów lub null w przypadku gdy nie ma żadnego dostępnego zbioru. Przydatną może okazać się tutaj metoda enumerateRecord(): enumerateRecord(RecordFilter filtr, RecordComparator porownaj, boolean kontrolowac);

60 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Argument RecordFilter filtr pozwala zdefiniować sposób wyboru rekordów z magazynu. Jest to interfejs wymagający określenia metody o nazwie matches(). Dzięki niemu można dokładnie ustawić jakie kryteria muszą spełnić rekordy, aby zostały odczytane, np. wybrać wszystkie rekordy (z przykładu przedstawionego wyżej, które zawierają liczbę dodatnią.) Podanie wartości null spowoduje, że rekordy odczytywane będą bez ograniczeń. Argument RecordComparator porownaj pozwala na uporządkowanie wg wybranego kryterium, np.: uporządkuj rosnąco według wartości liczb. Podanie wartości null spowoduje, że rekordy odczytywane będą kolejno zgodnie z natywną implementacją. Argument boolean kontrolowac pozwala na podjęcie decyzji, czy sposób odczytu rekordów (kryteria, kolejność) będą mogły się zmieniać za każdym razem, gdy nastąpi zmiana w magazynie. W takiej sytuacji zmianie musi ulec obiekt pozwalający na wyliczanie, jest to jednak dosyć czasochłonne. W przypadku, gdy ten parametr przyjmuje wartość false, należy budować na nowo obiekt enumerteRecord przy każdej zmianie.

61 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ private Dane getDane(int id,RecordStore nowy_magazyn)throws IOException, RecordStoreException { byte[] dane = nowy_magazyn.getRecord(id); DataInputStream is = new DataInputStream( new ByteArrayInputStream(dane)); Dane przyklad2 = new Dane(is.readUTF(), is.readInt()); return przyklad2; } A oto przykład odczytu danych z magazynu, trzeba oczywiście pamiętać o zamianie danych z postaci tablicy bajtów do postaci oryginalnej:

62 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Poniżej przykład metody odczytującej dane z całego magazynu (ze wszystkich rekordów danego magazynu, przy wykorzystaniu metody enumerateRecord(); ) private String czytajMagazyn(String nazwa) throws Exception { RecordStore nowy_magazyn = null; int id; String ret; try{ nowy_magazyn = RecordStore.openRecordStore(nazwa,true); }catch(Exception e){ System.out.println("Blad Otwarcia magazynu!"); } RecordEnumeration wyl = nowy_magazyn.enumerateRecords(null,null,false); while(wyl.hasNextElement()){ id = wyl.nextRecordId(); Dane przyklad = getDane (id,spis); ret = id + " " + przyklad.daneTxt + " " + przyklad.daneNum; System.out.println(id + " " + przyklad.daneTxt + " " + przyklad.daneNum + "\n";); } try{ wyl.destroy(); nowy_magazyn.closeRecordStore(); }catch(Exception e){ System.out.println("Blad zamkniecia" + e); } return ret; }

63 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Na koniec usuwanie. Mamy do dyspozycji dwie proste metody: void deleteRecord(int recordID); usuwa rekord o podanym ID ze zbioru static void deleteRecordStore(String recordStoreName); usuwa cały zbiór rekordów o podanej nazwie. Ale uwaga - zbiór musi być zamknięty inaczej otrzymamy wyjątek RecordStoreException.

64 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Dystrybucja programów w J2ME

65 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Programowanie i testowanie w Symbian OS

66 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Symbian to nazwa systemu operacyjnego, dołączonych do niego bibliotek, rozwiązań interfejsu użytkownika oraz specyfikacji dla programów narzędziowych wyprodukowanych przez konsorcjum Symbian. W jego skład wchodzą najwięksi producenci telefonów komórkowych: Nokia Samsung Motorola Siemens Sony Ericsson Symbian został stworzony w oparciu o system EPOC, wykorzystywany w PDA firmy Psion PLC.

67 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Obecnie licencje na wykorzystywanie systemu operacyjnego Symbian posiadają: Arima BenQ Fujitsu Lenovo LG Matsushita Mitsubishi Motorola Nokia Samsung Sharp Siemens Sony Ericsson.

68 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ EPOC jest rodziną systemów operacyjnych opracowanych przez firmę Psion przeznaczonych dla urządzeń przenośnych, przede wszystkim PDA EPOC16 EPOC16, początkowo nazywany po prostu EPOC. Jest to system operacyjny opracowanym przez Psion w późnych latach 80. i wczesnych 90. Powstał z myślą o dla urządzenia "SIBO" (SIxteen Bit Organisers). System ten pracował na platformach opartych o procesor Intel Jego architektura jest 16-bitowa, jest systemem operacyjnym przeznaczonym dla pojedynczego użytkownika, mogącym pracować w trybie wielozadaniowości (z wywłaszczaniem). Napisany został w dwóch językach: asemblerze oraz języku C i zaprojektowanym tak, aby mógłbyć umieszczony w pamięci ROM. Pierwsze urządzenia pod kontrolą EPOC16, zostały wypuszczone na rynek w W późnych latach 90. systemowi przypisano nazwę EPOC16, aby odróżnić go od nowego systemu operacyjnego jakim był EPOC32.

69 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ EPOC32, Symbian OS Pierwsze wydanie EPOC32 (Release 1) pojawiło się w Series 5 ROM v1.0 w Powstało szybko wiele jego wersji. System operacyjny EPOC32 został później przemianowany na Symbian. EPOC32 i EPOC16 były zupełnie odmiennymi systemami operacyjnymi. EPOC32 napisany w języku C++, który był rozwijany w połowie lat 90. Jest systemem operacyjnym przeznaczonym dla pojedynczego użytkownika, mogącym pracować w trybie wielozadaniowości(z wywłaszczaniem). Posiada zabezpieczenie pamięci, zatem należy dzielić aplikacje na silnik i interfejs użytkownika. EPOC32 był początkowo przeznaczony dla rodziny procesorów ARM, włączając w to: ARM7, ARM9, StrongARM i XScale Intela, ale może być kompilowany w odniesieniu do urządzeń korzystających z innych typów procesorów. W czerwcu 1998, Psion Software stała się firmą Symbian Ltd., spółką joint venture pomiędzy Psion i wytwórcami telefonów: Ericsson, Motorola i Nokia. Jako wydanie szóste (Release 6), EPOC był już nazywany po prostu Symbian.

70 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Jakie możliwości daje SYMBIAN? Symbian to system operacyjny dla telefonów komórkowych. Pozwala zmienić zwykły telefon komórkowy w urządzenie wielofunkcyjne. użytkownik może dowolnie korzystać z dodatkowego oprogramowania. Umożliwia m.in. korzystanie z internetu [przeglądanie stron www, poczta elektroniczna, ftp, komunikatory internetowe etc.], przeglądanie i edycję dokumentów word, excel czy pdf, odtwarzanie i nagrywanie muzyki, fotografowanie i edycję zdjęć, nagrywanie i odtwarzanie video [włącznie z formatami typu DivX, Xvid, AVC], nawigację GPS, zapewnia również rozrywkę poprzez wiele różnego rodzaju gier. Żeby móc korzystać z dobrodziejstw Symbiana trzeba kupić telefon oparty na tym systemie. Urządzenia te dzielą się ze względu na interfejs użytkownika. S60 Dzieli się na 4 edycje. S60 1 edycji S60 2 edycji S60 3 edycji S60v3 dodatkowo dzieli się na wersje FP1 (Feature Pack 1) i FP2 (Feature Pack 2). Więcej informacji w artykułach: S60 5 edycji UIQ - aktualnie nie rozwijany(telefony z ekranem dotykowym). Dzieli się na 2 edycje. UIQ 2 edycji UIQ 3 edycji Series80 - Nokia - urządzenia typu Communicator z pełną klawiaturą QWERTY - aktualnie nie rozwijany Series90 - Nokia - tablety internetowe - aktualnie nie rozwijany NTT DoCoMo's MOAP - FOMA - dostępny tylko w Japonii

71 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Programowanie pod Symbian : Wspieranie języki : C++ Java Pyhton Środowiska Programistyczne (Przykłady): Carbide C++ Express NetBeans (Java, C++) Eclipse (Java) Symbian C++ Termin Symbian C++ odnosi się do specyficznej odmiany języka C++, wraz z towarzyszącymi mu Frameworkami używanymi przez Symbiana. Symbian C++ znacząco różni się od powszechniejszego C++, związane jest to z platformami, jak również i doświadczenia z przeszłości (Symbian jest przecież kontynuacją systemu operacyjnego EPOC firmy Psion, którego pierwsze wersje powstały w latach 80.). Różnice pomiędzy Standardowym C++, a Symbian C++ są duże. Przykładem jest zupełnie inny mechanizm wyjątków. Java – Sytuacja podobna jak w przypadku większości innym platform, wykorzystujących J2ME.

72 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Symbian C++ - krótkie wprowadzenie Symbian C++ jest językiem bardzo restrykcyjnym. Wynika to z bardzo ograniczonych zasobów (w stosunku np. Do komputerów PC). Twórcy starali się standaryzować wszystko, włączanie z odpowiednim nazewnictwem w kodzie. A wszystko to między innymi, aby uniknąć błędów (np. wycieków pamięci). Nazwę typu poprzedza duża litera T (od Type), zmienne które odpowiadają unsigned - posiadają przed nazwą typu (po T) dużą literę U (od unsigned): TInt8, TUInt8 – zmienna całkowita 8-bitowa oraz jej odpowiednik typu unsigned TInt16, TUInt16 – analogicznie j.w., ale 16-bitowa TInt32, TUint32 – j.w., ale 32-bitowa (TInt, TUInt) TInt64 – zmienna całkowita 64-bitowa, w praktyce przechowywana jako 2 zmienne 32-bitowe TReal32 – zmienna zmiennoprzecinkowa o podwójnej precyzji 32-bitowa TReal, TReal64 – j.w., ale 64-bitowa TText8, TText16 – zmienne tekstowe (odpowiednikami w C++ są odpowiednio – unsigned char oraz unsigned short int) TBool – zmienne booleanowskie TAny – odpowiednik void z C++, najczęściej używany jako TAny *

73 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Kiedy funkcja może wyjść (leaveować)? 1. Funkcja może wychodzić, gdy zawiera w sobie inne funkcje mogące wychodzić, czyli oznaczone L na końcu. Gdy wykorzystujemy jakąś funkcje leaveującą, oznacza to że nasza funkcja także może leaveować, a więc musimy oznaczyć ją literką L. 2. Możemy także programowo wywołać leaveowanie, wywołując statyczną metodę User::Leave //lub którąś z jej wersji. Mamy do wyboru: User::Leave(jakiś_błąd); //Leave jest wywołany, jeżeli wystąpi jakiś_błąd. Przykład: User::Leave(KErNoMemory); W tym momencie program wyjdzie, jeżeli zabraknie pamięci. User::LeaveNoMemory() //funkcja wychodzi, gdy jest brak pamięci,odpowiednik funkcji poprzedniej User::LeaveIfNull() – funkcja wychodzi jeżeli zwrócony wskaźnik jest NULL. User::LeaveIfError() – czyli gdy wywoływana funkcja zwróci nam błąd. Przykład (łączenie się z serwerem plików): User::LeaveIfError(iFs.Connect()); W tym momencie jeżeli poprawnie połączymy się z serwerem plików, program pójdzie dalej. Jeżeli jednak wystąpi jakiś błąd – zrobimy Leave.

74 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Nazwy klas (prefiksy): T – typy Klasy T nie posiadają destruktora, występują w sposób jak typy wbudowane. C – klasy Klasy C to klasy dziedziczące po CBase. M – interfejsy (Mixin) Klasy M są interfejsami składającymi się z funkcji wirtualnych. Nazwy danych (prefiksy) E – stałe typów wyliczeniowych Stała typu wyliczeniowego, powinna być składową stałej o nazwie rozpoczynającej się od T K – stałe i – zmienne składowe Każda nie-statyczna zmienna składowa (i od instance). a – argumenty Wszystkie zmienne deklarowane jako argumenty. Nazwy funkcji (sufiksy) L – funkcje, które mogą leaveować (leaveowanie zostanie wyjaśnione później). C – funkcje, które zostawiają coś na Cleanup Stacku (Cleanup Stack zostanie wyjaśniony później). Nazwy makr Pisane dużymi literami, podkreślenia zamiast spacji. Symbole wbudowane Pisane z podwójnym podkreśleniem jako prefiks oraz sufiks.

75 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ W przypadku zmiennych boolean prawda oraz fałsz programowo są oznaczane odpowiednio jako ETrue oraz EFalse. : TBool b= Etrue; if (b == ETrue) {... } Tutaj mała uwaga – w C++ wszystko co nie jest zerem uznawane jest za prawdę, natomiast w Symbian C++ ETrue odpowiada za wartość 1. TBool b = Funkcja(); if (b) {... } Otóż wszyscy programiści C++ na pewno mają na uwadze różnice w rozmiarze typów zmiennych w przypadku różnych platform i/lub różnych kompilatorów. Z uwagi, że pisząc aplikacje na Symbian OS należy uwzględnić różne telefony (również kompilatory, środowiska), stosując typy zmiennych zaprezentowane w liście powyżej mamy pewność, iż zawsze będą takie jakie mają być. Jedynym odstępstwem od tej reguły jest zwracany typ void przez funkcje (w przypadku deklarowania wskaźników typu pustego, należy posługiwać się typem TAny).

76 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Od Symbian OS 8.1 możliwe jest użycie mechanizmów przechwytywania wyjątków znanych z języka C++, chociaż takie podejście do sprawy nie jest zalecane. Twórcy systemu namawiają do pozostania przy bardziej przetestowanym, bogatszym i zaimplementowanym w systemie od pierwszej wersji mechanizmie walki z błędami. Błędy Panics W momencie powstawia bledu system najlepsze co moze zrobic, to zamknac aplikacje. Podstawową używaną tutaj funkcją jest User::Panic(panicCategory, integer), gdzie panicCategory powinien być maksymalnie 16 znakowym określeniem błędu, integer natomiast 32-bitowym numerem błędu. Powszechnym sposobem używania Panics jest użycie makr __ASSERT_DEBUG oraz __ASSERT_ALWAYS; pierwszy jest kompilowany w wersji Debug, drugi w wersji Debug jak również i przy kompilowaniu wersji finalnej. Poniższy przykład obrazuje użycie opisanych makr: void CMyClass::Foo(TInt aIndex) { __ASSERT_ALWAYS (aIndex > 0, Panic(_L("Błąd typu Panic"), 11)); } Prototyp funkcji wygląda jak pokazano poniżej: __ASSERT_ALWAYS(warunek, wyrażenie); Kiedy to wyrażenie jest wykonane gdy warunek nie jest prawdą. W tym przypadku Panic zostanie wywołane gdy aIndex będzie wartością mniejszą bądź równą zero, natomiast błąd zwrócony będzie treści Błąd typu Panic (_L() musi być używane do przekazywania własnych treści.

77 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Mechanizm Leave służy do wychodzenia z funkcji, natomiast TRAP oraz TRAPD do przechwytywania tych wyjść, przy czym używanie przechwytywania nie jest zalecane ze względu na ich szybkość (a raczej nie- szybkość) działania oraz pamięciożerność. TRAP TInt err; TRAP(err, funkcjaL()); TRAP(D) TRAPD –zajmuje się od razu deklaracją zmiennej; przykład użycia TRAPD: TRAPD(err, funkcjaL()); oraz przykład użycia TRAP TInt err; TRAP(err, funkcjaL()); Jak widać, w przypadku wersji TRAPD kod skraca się o jedną linijkę. Warto tutaj zauważyć, iż w przypadku gdy nie zastosujemy żadnego przechwycenia w programie, system zrobi to za nas.

78 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Leave Mechanizm leave jest pewnym odpowiednikiem wyjątków z normalnego C++. Służy określeniu miejsc w programie, gdzie coś może pójść nie tak nie z winy programisty. Są to na przykład funkcje, w których alokujemy pamięć. Programista nie może wiedzieć, czy pamięć jest akurat dostępna. Jeżeli tak – wszystko w porządku. Jeżeli nie – funkcja leaveuje. Funkcje które mogą leaveować oznaczane są dużą literką L na końcu. Nie jest to tylko kosmetyka. User::Leave() Wyjście z funkcji User::Leave(kodBłędu) Wyjście z funkcji z kodem błędu (jest przekazywany do TRAP(D)) User::LeaveIfError(kodBłędu) Wyjście z funkcji tylko w przypadku gdy kodBłędu jest negatywny (mniejszy od 0, wszystkie błędy są wartościami ujemnymi) User::LeaveNoMemory() Odpowiednik User::Leave(KErrNoMemory) User::LeaveIfNull(wskaźnik) Wychodzi z funkcji z KErrNoMemory jeśli przekazany wskaźnik jest NULL

79 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Należy zwrócić uwagę co się dzieje ze wszystkimi wskaźnikami, które zostały zainicjowane przed takim wyjściem – otóż jeżeli zostanie on usunięty, natomiast miejsce w pamięci nadal jest zajęte. Miejsce w pamięci nadal jest zajęte, jednak nie mamy do niego już dostępu - następuje wyciek pamięci. CleanupStack CleanupStack wykorzystywany jest, gdy po zaalokowaniu pamięci na dany obiekt, funkcja może wywołać Leave nie dochodząc do momentu w którym uprzednio stworzony obiekt jest poprawnie usuwany. Przykład użycia: void JakasKlasa::FunkcjaL() { TInt * liczba = new (ELeave) TInt; //tutaj może dojść do wycieku pamięci… … delete liczba; } Klasa * nowy_obiekt = new (ELeave) Klasa; // tu może coś nie wyjść… Nowy_obiekt->Funkcja(); delete nowy_obiekt; Klasa * nowy_obiekt = new (ELeave) Klasa; CleanupStack::PushL(nowy_obiekt); Nowy_obiekt->FunkcjaL(); CleanupStack:PopAndDestroy(nowy_obiekt); Oraz jak to wygląda z CleanupStack:

80 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ W takim przypadku, od razu po alokacji pamięci dla obiektu w następuje zachowanie tego wskaźnika na CleanupStack. W momencie, gdy Funkcja() zakończy swe działanie nie powodując żadnego błędu, funkcja CleanupStack::PopAndDestroy(nowy_obiekt) zdejmuje ten wskaźnik od razu go niszcząc, oraz usuwane przydzielone mu zasoby. Natomiast jeżeli Funkcja() wyjdzie, wtedy jako część procesu czyszczenia wszystkie obiekty znajdujące się na CleanupStack są poprawnie usuwane. Istnieje kilka wariacji funkcji zdejmujących z CleanupStack: CleanupStack:Pop() – zdejmuje ze stosu ostatnio położony wskaźnik CleanupStack:Pop(2) – zdejmuje ze stosu ostatnie dwa położone wskaźniki CleanupStack:Pop(wsk) – zdejmuje ze stosu i sprawdza czy jest to wsk CleanupStack::PopAndDestroy(); oraz CleanupStack::PopAndDestroy(wskaźnik); Funkcja zdejmuje wskaźnik do obiektu i od razu go niszczy (czyli wywołuje delete na obiekcie, który ten wskaźnik pokazuje). CleanupStack::PushL(wskaźnik); - odkładanie wskaźników.

81 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ -Nie odkładamy składowych klas na CleanupStack. Dlatego, że składowe klasy niszczymy w destruktorze tej klasy, który będzie wywołany kiedy ta klasa będzie niszczona. Jeżeli odłożymy taką zmienną, system będzie chciał zniszczyć obiekt dwa razy – pierwszy, bo będzie miał wskaźnik na stosie, a drugi raz gdy będzie niszczył klasę w destruktorze. -Podsumowując wskaźniki do obiektów odkładamy na stos wtedy, kiedy między stworzeniem obiektu a jego zniszczeniem nie mamy gwarancji, że program na pewno nie wyjdzie. Jeśli takiego zagrożenia nie ma – nie ma potrzeby stosowania tego mechanizmu. Tak więc że nie zawsze musimy odkładać na stos wszystkiego, co tworzymy Zatem Nie należy nadużywać tego mechanizmu i kłaść na CleanupStack tylko te wskaźniki, w których pomiędzy stworzeniem a usunięciem może wystąpić Leave.

82 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Programowanie i testowanie w Microsoft Mobile ASP.NET

83 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Rozwój oprogramowania Systemy operacyjne urządzeń mobilnych

84 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Windows CE – system operacyjny opracowany przez Microsoft jako system dla urządzeń przenośnych typu PDA (np.: Pocket PC lub Palm) lub jako system wbudowany. Wersja 1.0 była bardziej rozbudowanym organizerem niż systemem operacyjnym (z punktu widzenia użytkownika.) Windows CE jest zoptymalizowany dla urządzeń o minimalnej pamięci – jądro Windows CE może być uruchomione nawet w 1 MB pamięci. System nie wymaga d pracy dysku twardego, może być więc system zamkniętym, i być umieszczony w pamięci ROM. Obsługuje 256 priorytetów wykonywania i korzysta z dziedziczenia priorytetów w razie, przydatnych w sytuacji inwersji piorytetów. Podstawową jednostką wykonywania jest wątek, co umożliwia prostsze zarządzanie procesami. Windows CE używany jest także w komputerach pokładowych samochodów wraz z systemem rozpoznawania mowy mającym zapewnić bezdotykową obsługę systemu operacyjnego.

85 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Windows CE 1.x specyfikacja urządzeń na których system miał pracować : Wymiary nie większe niż 18x10x2.5 cm Zasilanie z dwóch baterii AA Waga mniejsza niż 500 g Klawiatura QWERTY zawierająca klawisze takie jak SHIFT, CTRL i ALT Dotykowy wyświetlacz LCD o rozdzielczości 480x240 pikseli w 4 odcieniach szarości Minimum 4 MB pamięci ROM Minimum 2 MB pamięci RAM Port podczerwieni Port COM zgodny z RS-232 Slot PC Card (PCMCIA) Wbudowana obsługa dźwięku Procesor SuperH 3, MIPS 3000 lub MIPS 4000 Microsoft nie wypowiedział się jednoznacznie co oznacza skrót CE, lecz twierdzi, że taka nazwa nie była celowa. Oświadczył jednak, że CE wyrażać może w sobie wiele koncepcji, takich jak Compact (ang. Kompaktowy), Connectable (ang. Łącznościowy), Compatible (ang. Kompatybilny). Najczęściej jednak nazwę tłumaczy się jako "Compact Edition" lub "Consumer Electronics".

86 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Wygląd GUI systemu Windows CE 1.0 Źródło: Internet.

87 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Wersje systemu 1 Windows CE 1.x 2 Windows CE HandheldPC 2.x 3 Windows CE Palm-Size PC Windows CE Palm-Size PC Windows CE HandeldPC HandheldPC Professional 6 Windows CE HandeldPC 3.x - HandheldPC Windows CE.net (4.x) 8 Windows CE Windows CE Windows Mobile (i ten system również posiada kilka wersji.) Od wersji 4.0 z systemem zintegrowano.NET Compact Framework. Windows CE 6.0 powstał we wrześniu 2006 roku. Nazwa kodowa "Yamazaki". M.in. zwiększono przestrzeń adresową procesu z 32 MB do 1 GB i umożliwiono uruchomienie procesów (w porównaniu z 32 w wersji 5.0).

88 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Microsoft Windows Mobile Microsoft Windows Mobile to 32-bitowy system operacyjny przeznaczony dla urządzeń typu Pocket PC oraz Smartphone. Windows Mobile nie jest zupełnie osobnym systemem, lecz rozszerzeniem Windows CE o dodatkową funkcjonalność, API (ang. Application Programming Interface) oraz Shell. Dostępne wersje Systemu: Windows Mobile 2003 Windows Mobile 2003SE Windows Mobile 5.0 Windows Mobile 6.0 (64 MB RAM, wyświetlacz 3,5 cala) Windows Mobile 6.1 Classic Istnieją wersje przeznaczone dla PocketPC z wbudowanym modułem GSM: Windows Mobile 2003 Premium Phone edition Windows Mobile 2003SE Phone edition Windows Mobile 5.0 (Magneto) Phone edition Windows Mobile 6.0 Phone edition Windows Mobile 6.1 Professional Windows Mobile 6.5 Professional Windows Mobile Professional (w trakcie rozwoju) Windows Mobile 7 Professional (w trakcie rozwoju)

89 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Istnieją również wersje dla smartphone obsługujące ekrany 176x220 oraz 240x320 bez ekranu dotykowego: Smartphone 2002 Windows Mobile 2003 for Smartphone Windows Mobile 2003SE for Smartphone Windows Mobile 5.0 for Smartphone Windows Mobile 6.0 for Smartphone Windows Mobile 6.1 Standard Wygląd GUI systemu Windows Mobile 5.0 Źródło: Internet.

90 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ.NET Compact Framework Platforma umożliwiająca uruchamiane aplikacji napisanych w językach rodziny.NET, bedaca swego rodzaju maszyną wirtualną (jak np. JVM). Zatem można powiedzieć, że.Net Framework to maszyna wirtualna udostępniająca biblioteki, odpowiedzialne za nisko-poziomową interakcję z systemem operacyjnym, językom zarządzanym (ang. managed) wysokiego poziomu, np. C#. Kod napisany w C# czy J# jest najpierw kompilowany do pośredniego języka MSIL (Microsoft Intermediate Language). Wynikiem tego działania jest moduł zawierający instrukcje MSIL. Jedną z przyczyn zastosowania MSIL jest mozliwość wykorzystywania wielu języków programowania (VB, C#, J#, JScript, i Visual C++), skąd pojawia się konieczność pośredniej kompilacji kodu do MSIL. Następnie, moduł ten zamieniany jest na natywne instrukcje danego systemu operacyjnego CLR (ang. Common Language Runtime). Zatem.Net Framework postrzegać powinno się bardziej, jako platformę wielojęzykową, a nie jak maszynę wirtualną (jak np. maszyna wirtualna Javy) – wieloplatformową. Przeprowadzane są obecnie prace nad rozszerzeniem owych pięciu wspieranych języków programowania do ponad dwudziestu pięciu.

91 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Architektura.NET Compact Framework Źródło: Internet

92 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Common Language Runtime – wspólne środowisko uruchomieniowe. Jego podstawowym zadaniem jest zlokalizowanie, wczytywanie oraz zarządzanie typami.NET w imieniu użytkownika. CLR zajmuje się niskim poziomem pracy aplikacji np.: automatyczne zarządzanie pamięcią, integracją językową oraz ułatwianie wdrożenia ( i wsparcie dla różnego rodzaju wersji ) bibliotek kodu binarnego. CLR składa się z dwóch zasadniczych elementów: Runtime execution engine - mechanizm wykonawczy środowiska uruchomieniowego – mscoree.dll. Kiedy pakiet ( assembly ) jest wywoływany, automatycznie wczytywany jest mscoree.dll, który z kolei wczytuje do pamięci potrzebny pakiet. Mechanizm uruchomieniowy jest odpowiedzialny za wykonanie szeregu zadań. Pierwszym i najważniejszym jest określenie położenia pakietu i znalezienie wymaganego typu ( np. klasy, interfejsu, struktury itp. ) w kodzie binarnym przez odczytanie dostarczonych metadanych. Mechanizm wykonawczy kompiluje zasocjowany IL ( Intermediate Language ) do instrukcji specyficznych dla danej platformy. Biblioteka klas podstawowych. Składa się z kilku oddzielnych pakietów, najważniejszym jest mscorlib.dll. Zawiera dużą liczbę podstawowych typów, które hermetyzują dużą różnorodność najczęściej spotykanych zadań programistycznych. Każde rozwiązanie oparte na platformie.NET, zawsze wykorzystuje się ten pakiet i czasem kilka innych.NET ( zarówno oferowanych przez system jak i przygotowanych przez użytkownika ). Common Language Specification – specyfikacja wspólnego języka. Jest zbiorem zasad definiujących podzbiór wspólnych typów (dla różnych języków), który daje pewność, że kod binarny.NET może zostać bez klejenia wykorzystany przez wszystkie języki współpracujące na platformie.NET.

93 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Common Type System – zbiór wbudowanych podstawowych i wspólnych typów. Zawiera pełny opis wszystkich możliwych typów danych, obsługiwanych przez środowisko uruchomieniowe. Zawiera także informacje, o tym, jakie interakcje mogą zachodzić między nimi, oraz określa szczegóły ich reprezentacji w formie metadanych.NET. Managed Code - Kompilatory zgodne z CLR zamieniają kod źródłowy aplikacji na kod wykonywalny, zapisany w standardowym języku pośrednim MSIL, oraz na metadane informacje na temat kodu wykonywalnego oraz danych wykorzystywanych przez ten kod. Platforma.NET umożliwia pisanie aplikacji w wielu językach, ale dzięki MC kompilator zamienia wszystkie operacje na typach danych, to jest klasach, strukturach, liczbach całkowitych, łańcuchach znaków na język MSIL i metadane. W czasie wykonywania aplikacji, CLR tłumaczy kod MSIL na kod maszynowy (natywny) procesora, na którym wykonywana jest aplikacja. Taka konwersja kodu z MSIL na kod maszynowy daje możliwość zarządzania wykonywaniem aplikacji, co pozwala uniknąć wielu problemów stąd nazwa kod zarządzany. Garbage Collection –.NET Compact Framework zapewnie zwalnianie wszystkich zasób, z jakich korzysta aplikacja, po jej zakończeniu. W tym celu wykorzystywany jest mechanizm o nazwie Garbate Collection. Compact Framework decyduje kiedy powinien zostać uruchomiony proces Garbate Collection. Może on zostać uruchomiony w pojedynczej domenie aplikacji bądź też we wszystkich dostępnych. Pozwala to zapobiegać sytuacją, gdy jedna aplikacja zużywa zbyt dużo pamięci w porównaniu z innymi.

94 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Class Library Support Klasy są zorganizowane hierarchicznie wewnątrz przestrzeni nazw ( namespace )..NET Compact Framework współdzieli około 2/3 klas z pełną wersją.NET Framework. Mimo to występują pomiędzy nimi pewne istotne różnice, i trzeba być tego świadom podczas tworzenia aplikacji z wykorzystaniem.NET Compact Framework. Klasy współdzielone:.NET Compact Framework dostarcza szeroki podzbiór klas i metod do budowania aplikacji, które są później uruchamiane na urządzeniach z ograniczonymi zasobami. Wszystkie te klasy są semantycznie kompatybilne z klasami o tych samych nazwach w.NET Framework..NET Compact Framework posiada wsparcie dla istotnych elementów takich jak: · Usługi sieci Web oparte na XML · Zarządzanie relacyjnymi danymi · Rozbudowana funkcjonalność XML · Rozbudowane klasy do rysowania, takie jak Image Controls · Potężne możliwości budowania interfejsu użytkownika..NET Compact Framework nie wspiera klas ASP.NET.

95 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Klasy tylko dostępne w Compact Framework: Podczas tworzenia aplikacji z wykorzystaniem.NET Compact Framework należy pamiętać o klasach dostępnych jedynie w tym środowisku. Chodzi np. o klasę Infrared Data Association ( IrDA ) do nawiązywania połączeń do serwera i dostarczania informacji o porcie podczerwieni. Kolejnym przykładem jest klasa SQL Server CE, która pozwala na pracę z lokalnym serwerem bazy danych SQL Server CE. Narzędzie Class Library Comparison Tool – pozwala na przeglądanie różnic między klasami dostępnymi w.NET Framework i Compact Framework. Dla każdej klasy można sprawdzić, które pola, metody i właściwości są dostępne w obydwu lub też w jednym z nich. Wiele z klas dostępnych w.NET Framework nie jest dostępnych w Compact Framework. Powodem tego są ograniczenia co do zasobów i wydajności urządzeń mobilnych. CLR dla.NET Compact Framework stanowi około 12 % rozmiaru całego.NET Compact Framework. Rozmiar ten jest ograniczony, po to aby zwiększyć wydajność. Pomimo braku wsparcia dla GDI+ Compact Framework obsługuje podstawowe rysowanie GDI takie jak: bitmapy, pędzle, pióra, czcionki i ikony. Compact Framework nie pozwala na tworzenie nowych usług sieci Web, ale umożliwia wykonywanie istniejących usług sieci Web.

96 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Dalsze różnice: · - COM Interop – nie wspierane, należy wykonywać funkcje DLL, które wywołują obiekty COM - Data – podzbiór implementacji ADO.NET oraz SQL Server CE - ASP.NET – nie wspierany. Należy używać ASP.NET Mobile Web Controls do tworzenia stron sieci WWW dla urządzeń przenośnych - XML – ze względu na rozmiar brak obsługi walidacji XML schema lub zapytań XPath w dokumentach XML. - Aby zmniejszyć rozmiary środowiska zrezygnowano z wielu przeładowanych metod - Brak niektórych kontrolek ( np. wsparcia dla drukowania ) - Ze względu na wydajność brak klas BinaryFormatter i SoapFormatter - Bezpieczeństwo – brak zabezpieczenia dostępu do kodu niezarządzanego. Dowolna aplikacja może wywołać dowolny system lub nie systemowe API. Brak systemu bezpieczeństwa opartego na rolach

97 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ W tablicach.NET Compact Framework nie zwraca wyjątku MissingMethodException; Możliwość pisania aplikacji ASP.NET za pomocą kontrolek przeznaczonych dla urządzeń mobilnych; Możliwość stosowania assemblies (bez używania wielu modułów w.NET Compact Framework); Common Language Runtime oraz kompilacja Just-In-Time (JIT) są używane przed obydwa frameworki;.NET Compact Framework dziedziczy większość kontrolek używanych do pisania aplikacji Windows Forms;.NET Compact Framework nie ma metod GetCurrentDirectory oraz SetCurrentDirectory. Zamiast tego programista powinien używać właściwości WorkingDirectory oraz obiektu ProcessStartInfo; Aplikacje na.NET Compact Framework można pisać z wykorzystaniem C# lub Visual Basic. Aktualnie C++ nie jest wspierany;

98 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Platformy, narzędzia i technologie Narzędzia: Smart Device Extensions (SDE) for Microsoft Visual Studio.NET – tworzenie aplikacji, które w całości działają na urządzeniach przenośnych. SDE rozszerza funkcjonalność Microsoft Visual Studio o tworzenie aplikacji na różnego rodzaju urządzenia mobilne przy czym pozwala wykorzystać praktycznie wszystkie dostępne możliwości Visual Studio. Stwarza to jedno środowisko do tworzenia aplikacji na urządzenia przenośne, komputery PC i serwery. SDE pozwala na projektowanie, debugowanie i wykonywanie aplikacji na wielu z dzisiejszych urządzeń mobilnych. SDE zawiera ponadto kilka dobrym, ekranowych emulatorów dla urządzeń przenośnych. Dostępne są emulatory dedykowane dla Pocket PC, Pocket PC 2002, Smart phones i dla urządzeń działających pod kontrolą systemu Windows CE.NET. Microsoft Mobile Internet Toolkit (MMIT) – służy do tworzenia aplikacji, których kod wykonywany jest na serwerze. W takich aplikacjach po stronie serwera mamy Microsoft SQL Server oraz Microsoft Information Services ( IIS ). MMIT pozwala na łatwe tworzenie złożonych aplikacji Webowych, których docelową (kliencką) platformę stanowią urządzenia mobilne. Dzięki temu rozwiązaniu pisanie oprogramowanie na urządzenia mobilne staje się proste i wydajne.

99 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ MMIT dostarcza wszelkich korzyści projektowania aplikacji z pomocą ASP.NET. Ponadto MMIT posiada następujące udogodnienia: - Wsparcie dla szerokiej gamy urządzeń. Pozwala na używanie ASP.NET na wielu urządzeniach mobilnych, począwszy na telefonach komórkowych, skończywszy na urządzeniach Pocket PC. - Strony WWW stworzone z wykorzystaniem MMIT są tak samo prezentowane na wszystkich wspieranych urządzeniach, nie trzeba jej dostosowywać do poszczególnych urządzeń. Można tworzyć złożoną aplikację wykorzystując zbiór mobilnych kontrolek serwerowych bez żadnej wiedzy na temat WML-a lub innych podobnych języków. Środowisko uruchomieniowe bierze na siebie odpowiedzialność za różnice w implementacjach pomiędzy różnymi przeglądarkami, urządzeniami i bramkami sieciowymi. - Możliwość personalizacji i rozszerzania funkcjonalności. MMIT dostarcza takie same możliwości personalizacji i rozszerzalności jak ASP.NET. W dodatku narzędzie pozwala na dodawanie obsługi nowych urządzeń, bez konieczności jakiejkolwiek zmiany w kodzie aplikacji. Dzięki temu można mieć pewność, że aplikacja stworzona dzisiaj będzie w przyszłości działała na nowej generacji urządzeń.

100 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Możliwości programistyczne w Windows Mobile 5.0 Windows Mobile 5.0 zapewnia programistom nowe, liczne interfejsy programistyczne. Dzięki nim, programista może się skupić na konkretnych celach aplikacji, a nie sposobach ich realizacji. Elementy wspomaganie przez interfejsy to np.: rysowanie 2D i 3D, dostarczają nowych możliwości komunikacyjnych oraz ułatwiają obsługę elementów sprzętowych takich jak kamera czy też system nawigacji satelitarnej. Inne usprawnienia to m. in. : 1.Nowe interfejsy API dostarczają wielu nowych możliwości np.: zarządzanie obrazami, kontaktami, 2.Większa przenośność kodu i aplikacji pomiędzy urządzeniami Pocket PC a Smartphone. 3.Nowe API do śledzenia aktywności systemu takich jak: zmiany w połączeniu z siecią, odbiór wiadomości SMS lub nadejście połączenia telefonicznego; 4.Rozbudowane narzędzia do testowania aplikacji w zależności od orientacji ekranu, rozdzielczości czy też rodzaju urządzenia – przyspieszają tworzenie aplikacji w Visual Studio. 5.API do obsługi wbudowanego aparatu. 6.Windows Media Player 10Mobile pozwala na łatwa dołączenie multimediów do tworzonej aplikacji (np. wbudowanie odtwarzacza multimedialnego). 7.Obsługa Direct3D dostarcza możliwości tworzenia aplikacji trójwymiarowych. 8.Obsługa DirectDraw zapewnia większą kontrolę i elastyczność w aplikacjach 2D.

101 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Windows Mobile 5.0 posiada zainstalowane domyślnie w pamięci ROM środowisko.NET Compact Framework 1.0 wraz z SP3. Możemy wyróżnić trzy rodzaje API: - Nowo dodane API kierowane do programistów tworzących aplikacje w kodzie natywnym; - Istniejące wcześniej natywne API, ale teraz dodatkowo dostępne dla programistów kodu zarządzanego; - Nowo dodane API dostępne zarówno dla programistów kodu natywnego jak i zarządzanego.

102 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Podstawy działa Garbage collection Garbage collection (zbieranie nieużytków) to architektura zarządzania pamięcią, w której proces zwalniania nieużywanych jej obszarów odbywa się automatycznie. Mechanizm taki stosuje się na przykład w wysokopoziomowych językach programowania, przy czym za jego obsługę nie odpowiada sam język, lecz wirtualna maszyna. Garbage collection zostało wymyślone przez Johna McCarthy'ego około roku 1959 do rozwiązania problemu ręcznego zarządzania pamięcią w Lispie. Był to pierwszy język obsługujący ten mechanizm. Przykładowymi językami obsługującymi ten mechanizm są Smalltalk, Python, Ruby, Java, C#. Istnieje co najmniej kilka metod pracy GC. Liczenie odnośników (reference counting) W tej metodzie każda jednostka zarezerwowanej pamięci ma licznik, w którym jest zapisana liczba odwołań do tej jednostki. Za każdym razem, kiedy dodajemy odwołanie, zwiększamy licznik we wskazywanej jednostce, a kiedy odwołanie usuwamy, zmniejszamy licznik. Jeśli wartość licznika osiągnęła zero, to usuwamy wszystkie odnośniki wychodzące z tego obszaru pamięci i zwalniamy go. Metoda ta nie gwarantuje zwolnienia wszystkich niepotrzebnych obszarów w sytuacji, gdy występują tzw. wzajemne (cykliczne) odwołania. Przykładowo, jeśli X zawiera wskaźnik na Y, a Y zawiera wskaźnik na X (np. są to dwa komunikujące się ze sobą obiekty), licznik w żadnym z nich nigdy nie osiągnie zera.

103 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ W liczeniu odnośników dodatkowe obliczenia związane z pracą kolektora nieużytków są rozłożone w czasie, gdyż wszystkie operacje muszą dbać o liczniki, co może skutkować znacznie mniejszym - lub też przeciwnie - znacznie większym, obciążeniem w porównaniu z innymi metodami. Mark and Sweep. W tej metodzie każda jednostka pamięci zawiera pojedynczy bit, który jest na początku czysty. Kiedy maszyna wirtualna przechodzi w fazę "garbage collection", zaczyna sprawdzać obiekty, o których wie, że istnieją do nich odwołania, zaznacza w nich ten bit i rekursywnie przechodzi przez wszystkie komórki przez nie wskazywane. Kiedy już wszystko zostało oznaczone, komórki bez znacznika są zwalniane, bo na pewno nic na nie nie wskazuje, po czym znacznik jest czyszczony wszystkim komórkom. Mark and Sweep jest obecnie najpopularniejszą metodą. Garbage collection przez kopiowanie Ta metoda polega na tym, że wszystko zostaje rekursywnie przekopiowane do innego obszaru w pamięci - najpierw kopiowany jest początkowy zestaw danych, potem wszystko co było przez niego wskazywane, itd. Na końcu zwalniamy początkową pamięć. W ten sposób przez odsiew usuwane zostają elementy, na które nic nie wskazuje. I w ten sposób oszczędza się na konieczności ustawiania bitów w "mark and sweep", dodatkowo, regularnie defragmentuje się pamięć. Problemy jakie mogą wystąpić to konieczność poniesienia kosztu kopiowania oraz konieczność posiadania dużej ilości wolnej pamięci. Ten sposób byłby bardziej praktyczny na systemach, na których możliwa jest tymczasowa alokacja dużej ilości pamięci.

104 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Programowanie i testowanie w Microsoft Mobile ASP.NET - przykłady

105 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Tabela 1. Kontrolki dostępne w środowisku.NET Compact Framework

106 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Przykład Tworzenia aplikacji, spełniającej funkcje klienta poczty elektronicznej (Outlook). Co będzie potrzebne ? Visual Studio środowisko programistyczne, które jest także platformą do rozwijania aplikacji mobilnych wykorzystujących biblioteki i narzędzia Microsoftu. Niestety do naszych potrzeb jest wymagana wersja minimum Standard i nie wystarczy nam darmowa Express Edition. Windows Mobile 5.0 SDK - zestaw bibliotek i narzędzi do tworzenia aplikacji na urządzenia mobilne wyposażone w systemy operacyjne firmy Microsoft.

107 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ using Microsoft.WindowsMobile.PocketOutlook;(1) public static OutlookSession outlook = new OutlookSession();(2) foreach (Contact contact in outlook.Contacts.Items)(3) { lstAll.Items.Add(contact); } Pocket Outlook. Zawiera w sobie zarządzanie kontaktami, notatkami i zadaniami, jest to usługa, która działa w tle. Pełni ona tutaj rolę serwera danych, udostępniającego je na życzenie innych, korzystających z nich aplikacji. Jedną z nich będzie, ta, którą zaraz przygotujemy. (1)dodanie na przestrzeni nazw pakietu Outlook (2)dodanie zmienną statyczną "outlook. (3)kod wypełniający naszą listę kontaktami otrzymanymi od Outlooka (umieszczony jest on w konstruktorze naszej aplikacji). lstAll - kontrolka listy (ListBox), znajduje się w zasobniku, w grupie Common Device Controls.

108 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Klasa OutlookSession jest głównym interfejsem do komunikacji z programem Pocket Outlook i pobierania wszystkich udostępnianych przez niego danych. Wystarczy zatem jeden obiekt tego typu, ale musi być on udostępniony dla wszystkich komponentów aplikacji. Dlatego też udostępniliśmy go jako publiczną zmienną statyczną w klasie, która reprezentuje główna formę aplikacji. Windows Mobile pozwala na przechowanie prawie czterdziestu różnych informacji o pojedynczej osobie – Jest to zadanie klasy Contact. if(!string.IsNullOrEmpty(textBox1.Text))(4) { Contact newContact = new Contact(); newContact.FirstName = textBox1.Text; newContact.MobileTelephoneNumber = textBox2.Text; Form1.outlook.Contacts.Items.Add(newContact); Close(); } (4)Metoda dodająca nowy kontakt.

109 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ private void ReadContacts()(5) { lstAll.Items.Clear(); foreach (Contact contact in outlook.Contacts.Items) { lstAll.Items.Add(contact); } (5) Metoda odczytująca zapisane kontakty. Należy te operacje powtarzać po dodaniu każdego nowego rekordu, jeśli chcemy zobaczyć nowy rekord. Dzięki gotowej bibliotece Microsoft Telephony API nawiązanie polaczenia jest czynnością bardzo prostą. Przedstawiona aplikacja pokazuje zaledwie mały procent możliwości, jakie daje nam to środowisko.

110 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ private void lstAll_SelectedIndexChanged(object sender, EventArgs e)(7) { if(lstAll.SelectedItem != null) { Contact selected = (Contact)lstAll.SelectedItem; // ustanowienie połączenia Phone phone = new Phone(); phone.Talk(selected.MobileTelephoneNumber); } (7) Metoda nawiązująca połączenie. Uruchomiona zostanie, gdy wystąpi zdarzenie SelectedValueChanged. Środowisko stworzy szkielet metody do obsługi zdarzenia, a nam pozostanie wypełnić ją treścią. Funkcja najpierw sprawdza, czy element listy został zaznaczony (użytkownik mógł go również "odznaczyć"), potem zamienia element listy na obiekt typu Contact w celu wyłuskania z niego numeru telefonicznego, po czym wykonuje faktyczne połączenie Obiekt typu Phone pozwala na nawiązywanie połączeń. Można to zrobić wywołując jego metodę Talk() i podając jako parametr żądany numer telefonu. Warto zauważyć, że parametr ten jest literałem i można go podać w postaci alfanumerycznej, jak często podaje się numery telefonów w Stanach Zjednoczonych - na przykład MY-APPLE.

111 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ using Microsoft.WindowsMobile.Telephony; (8) private void lstAll_SelectedIndexChanged(object sender, EventArgs e)(9) { if(lstAll.SelectedItem != null) { Contact selected = (Contact)lstAll.SelectedItem; SmsMessage sms = new SmsMessage(selected.MobileTelephoneNumber, "Cześć!"); //wysłanie SMS-a outlook.SmsAccount.Send(sms); } (8) – potrzebne, aby móc nawiązywać połączenia telefoniczne. (9) – Metoda wysyłająca sms. Ponieważ rozmowy i wysyłanie krótkich wiadomości tekstowych SMS są funkcjami dostępnymi tylko w fizycznych urządzeniach i nie działają w emulatorze, to aby przetestować pełne działanie naszej aplikacji, trzeba użyć fizycznego urządzenia. Cała pozostała funkcjonalność może być jednak bez żadnych problemów testowana w emulatorze, jednak kiedy wywołamy funkcję połączenia, czy wysłania widomości, skończy się to błędem. Przykład pochodzi z :

112 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Dalsze możliwości: Phone telefon = new Phone(); telefon.Talk("112"); telefon.Talk("112", true); using Microsoft.WindowsMobile.PocketOutlook; // Dodajemy nowe spotkanie I ustawiamy mu szczegóły Appointment spotkanie = new Appointment(); spotkanie.Subject = "Nowe spotkanie testowe"; // Ustawiamy temat naszego spotkania // Ustawiamy początek spotkania na 21 luty 2006 o // 18:30 spotkanie.Start = new DateTime(2006, 02, 21, 18, 30, 00); spotkanie.Duration = new TimeSpan(01, 00, 00); // Długość trwania spotkania ustalamy na 1 godz. spotkanie.ReminderVibrate = true; // Jako przypomnienie ustawiamy wibrację using (OutlookSession sesja = new OutlookSession()) // Tworzymy sesję Outlooka i dodajemy nasze nowe spotkanie { sesja.Appointments.Items.Add(spotkanie); }

113 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ using Microsoft.WindowsMobile.PocketOutlook; Message wiadomosc = new Message(); //tworzymy nową wiadomość wiadomosc.To.Add(new //dodajemy adresata naszej wiadomości wiadomosc.Subject = "temat"; //ustawiamy temat wiadomości wiadomosc.BodyText = "Przykładowy z jakimś załącznikiem"; //wpisujemy treść wiadomości wiadomosc.Attachments.Add(new //dodajemy załącznik do naszego -a using (OutlookSession sesja = new OutlookSession()) //wysyłamy wiadomość przy użyciu domyślnego konta pocztowego { sesja. Accounts[0].Send(wiadomosc); }

114 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Przykład wykorzystania Bluetooth using InTheHand.Net.Bluetooth; using InTheHand.Net.Sockets; using InTheHand.Net.Ports; using InTheHand.Net; BluetoothClient BClient = new BluetoothClient(); BluetoothDeviceInfo[] DevicesInfo = BClient.DiscoverDevices(); StringBuilder Info = new StringBuilder(); ClassOfDevice Class; DeviceClass Device; ServiceClass Service; // uslugi, oddzielone przecinkiem foreach (BluetoothDeviceInfo device in DevicesInfo) { Info.Append("Class of device: " + Class.ToString() + "\r\n"); Info.Append("Device: " + Device.ToString() + "\r\n"); Info.Append("Service: " + Service.ToString() + "\r\n"); } InTheHand – bibioteka dla platformy.NET, dostepna pod adresem:

115 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ private void ConnectBT(String Adres) { try { bluetoothClient.Connect(new BluetoothEndPoint((BluetoothAddress)Adres); } catch (Exception ex) { MessageBox.Show(ex.Message); } }

116 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Programowanie i testowanie w Adroid OS

117 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Historia Historia Androida rozpoczyna się w lipcu 2005 roku, kiedy to Google zakupiło Android Inc., niewielką firmę z Kalifornii. Założyciele firmy, którzy zaczęli pracę w Google to m.in. Andy Rubin (współzałożyciel firmy Danger), Rich Miner (współzałożyciel Wildfire), Nick Sears (T-Mobile) i Chris White (jeden z pierwszych inżynierów w WebTV). Wtedy o Android Inc wiedziano tylko tyle, że produkuje oprogramowanie dla urządzeń mobilnych. Już w Google zespół pod kierownictwem Rubina stworzył system operacyjny dla urządzeń mobilnych, oparty na Linuksie, z myślą o wytwórcach sprzętu mobilnego i operatorach telefonii komórkowej. Google już wtedy dobrał sobie partnerów w świecie sprzętu komputerowego i oprogramowania oraz zasygnalizował operatorom komórkowym gotowość do współpracy. 5 listopada 2007 roku powstło Open Handset Alliance, konsorcjum w którego skład wchodzą Google, HTC, Intel, Motorola, Qualcomm, T-Mobile, Sprint Nextel oraz NVIDIA. Powstało z myślą o rozwoju otwartych standardów dla telefonii mobilnej. Wraz z ogłoszeniem powstania OHA zaprezentowano platformę Android. 12 listopada 2007 roku OHA opublikowało pierwszą wersją Android SDK, w którego skład wchodzą narzędzia programistyczne, debugger, biblioteki, emulator, dokumentacja, przykładowe projekty, tutoriale, FAQ i inne. Programiści muszą zainstalować Android SDK na komputerze kompatybilnym z x86 z systemem Windows XP lub Vista, Mac OS X (lub późniejszym), bądź Linux (testowane na Ubuntu Linux Dapper Drake). SDK wymaga także Java Development Kit, Apache Ant i Pythona 2.2 (bądź późniejszego). Eclipse 3.2 (bądź późniejsze) jest jedynym oficjalnie obsługiwanym IDE dzięki wtyczce Android Development Tools Plugin, ale programiści mogą także używać narzędzi konsolowych w celu tworzenia i debugowania aplikacji na Androida.

118 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Pierwszym telefonem wyposażonym w ten system operacyjny stał się HTC Dream, w Polsce sprzedawany pod marką Era G1 przez sieć Era od lutego 2009 roku. Kolejne telefony z Androidem to HTC Magic, (W Polsce sprzedawany od czerwca 2009), oraz Samsung I7500 Galaxy. W czerwcu 2009 HTC zaprezentowało telefon HTC Hero który został wyposażony w HTC Sense, autorski interfejs użytkownika, wdrożony do platformy Android przez producenta telefonu. W związku z warunkami licencji telefon z HTC Sense nie może posiadać znaczka "with Google" nadrukowanego na obudowie, gdyż HTC wprowadziło daleko idące zmiany w platformie Android. Architektura Systemu System Android oparty jest o system Linux, posiada jadro w wersji 2.6, dostarcza ono podstawowy system usług takich jak ochrona, zarządzanie pamięcią, zarządzanie procesem, obsługa sieci itp. Jądro również służy jako warstwa komunikacji między hardwar'em a softwar'em. Wyższa warstwa zawiera biblioteki systemowe zapewniające obsługę m. in. Bazy danych SQLlite Protokołu SSL Multimediów (MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, gif) Grafiki 2D / 3D, grafika 3D oparta na OpenGL ES 1.0 (przyśpieszenie sprzętowe jako opcja) System C library Inne

119 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Architektura Systemu Android Źródło:

120 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Linux Kernel Linux Kernel for ARM bezpieczeństwo, zarządzanie pamięcią, zarządzanie procesami, obsługa sieci i sterowniki. Wspiera architekturę ARM od wersji V5T Do obsługi androida wykorzystuje się szereg rozszerzeń: alarm, ashmem, binder, power management, low memory killer, kernel degugger, and logger. Obsługa systemu plików FAT32 Obsługa TCP/IP (TCP, UDP, etc)

121 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Cechy systemu: 1.Platforma aplikacji umożliwiająca ponowne wykorzystanie i wymianę modułów 2.Dalvik maszyna wirtualna zoptymalizowana dla urządzeń mobilnych 3.Zintegrowana przeglądarka oparta na wolnym oprogramowaniu WebKit 4.Zoptymalizowana grafika wykorzystująca grafikę 2D; grafika 3D oparta na OpenGL ES 1.0 (przyśpieszenie sprzętowe jako opcja) 5.SQLite dla przechowywania danych 6.Obsługa formatów multimedialnych audio, wideo, obraz (MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, gif) 7.Obsługa GSM 8.Obsługa Bluetooth, EDGE, 3G, i WiFi, CDMA. 9.Obsługa aparatu fotograficznego, GPS, kompas, and accelerometr 10.Przyjazne środowisko programistyczne z możliwością emulacji urządzenia, narzędzie do usuwania usterek, ustawienia wydajności oraz wykorzystania pamięci, plugin dla środowiska Eclipse 11.Wsparcie dla XML.

122 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Framework Aplikacji Programiści mają dostęp do tego samego API z jakich korzystają podstawowe aplikacje. Pod spodem działających aplikacji znajduje się szereg aplikacji, usług i podsystemów: Zestawi Widoków, które można używać do budowania aplikacji (listy, siatki, kontenery tekstowe, przyciski, wbudowana przeglądarka) "Content Providers", czyli system umożliwiający dostęp do danych innych aplikacji (np. Kontaktów), lub do ich współdzielenia. Menedżer Zasobów zapewniający dostęp do zasobów takich jak lokalizacje, grafika i pliki layoutów Menedżer Powiadomień pozwalający wyświetlać własne powiadomienia w pasku stanu Menedżer Aktywności zarządzający cyklem życia aplikacji i udostępniający standardową nawigację

123 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Biblioteki Android zawiera zbiór bibliotek C/C++ używanych przez różne componenty systemu. Te funkcje są prezentowane dla programistów poprzez "Android application framework". Niektóre z głównych bibliotek są wymienione poniżej: - System C - pochodzaca z BSD implementacja standardowej biblioteki C (libc), przystosowana do urządzeń bazujących na Linuxie - Media Libraries- oparta na PacketVideo's OpenCORE; biblioteki wspierają odtwarzanie i nagrywanie wielu popularnych formatów audio i video tak jak i statycznych plików graficznych: MPEG4, H.264, MP3, AAC, AMR, JPG, PNG - Surface Manager- zarządza dostępem do podsystemu wyświetlania aby bezkolizyjnie tworzyć ramki grafiki 2D i 3D z wielu aplikacji - LibWebCore - nowoczesny silnik przeglądarki sieciowej, ktory zasila zarówno przeglądarkę Androida jak i wbudowaną przeglądarkę internetową - SGL - silnik grafiki 2D - 3D libraries - implementacja bazująca na OpenGl ES 1.0 API; biblioteka używa zarówno sprzetowej alceleracji 3D (tam gdzie to możliwe) jak i włączonego w nią wysoko zoptymalizowanego programowego rasterizera 3D - FreeType - renderowanie bitmap i grafiki vektorowej - SQLite - potężna i lekka relacyjna baza danych dostępna dla wszystkich aplikacji

124 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Przykłady urządzeń z zainstalowanych systemem Android

125 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Dalvik virtual machine Językiem, w którym pisane są aplikacje na Androida jest Java. Zwykle pliki z kodem źródłowym napisanym w Javie kompilowane są do plików.class, zawierających instrukcje dla wirtualnej maszyny. Instrukcje te nazywa się bytecode em Javy (Java Bytecode). W momencie uruchomienia aplikacji wirtualna maszyna (JVM) ładuje owe pliki do pamięci i uruchamia zawarty w nich kod. Android nie posiada JVM! Zamiast JVM, Google zdecydował się wyposażyć Androida w technologię Dalvik. Dlaczego powstał Dalvik? Java nie jest już nową technologią, także od dłuższego czasu znajduje zastosowanie w urządzeniach mobilnych, pozwoliło to znaleźć pewne (choć) nieliczne, słabe punkty JVM. Jednakże Sun nie zdecydował się na radykalne zmiany, zatem Google postanowił takowych dokonać. Tak właśnie powstał Dalvik – nowoczesna wirtualna maszyna, przystosowana specjalnie do urządzeń mobilnych, gdzie szczególną uwagę należy zwrócić na małe zasoby pamięci, energii i niewielką prędkość procesorów. Wśród narzędzi zawartych w SDK znajduje się kompilator. Kompilator ten nie tworzy jednak plików.class z bytecodem Javy, lecz pliki.dex z bytecodem Dalvika. Następnie skompilowane pliki, wraz ze strukturą katalogów i znajdującymi się w nich multimediami, zostają spakowane – zamiast do pliku.jar - do pliku.apk (Android Package). Tak przygotowana aplikacja uruchamiana jest przez wirtualną maszynę Dalvika.

126 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Podstawowe różnice pomiędzy JVM Javy i DVM. Lepsza obsługa pamięci, Lepszy Garbage Collector, Większą wydajność. Aplikacje pobierają mniej energii. Bytecode Dalvika nie jest w 100% kompatybilny z bytecodem Javy. Nie zadziałają więc na Adnroidzie bardziej wyrafinowane sztuczki programistyczne, korzystające z Class Loaderów czy Java Reflection API. Powoduje to także problemy z uruchomieniem na Androidzie projektów korzystających np. z języków takich jak Groovy, JRuby czy Jython. Brak wsparcia dla niektórych klas znanych z J2ME, np. AWT czy Swing. Brak JIT (ang. just-in-time compilation) Niekompatybilność Darvick VM jest jednak pewną wadą – dlatego Google rozważa możliwość pewnego upodobnienia DVM do JVM, m. in.: wprowadzenie ClassLoaderów takie jak w Javie, a także pełne wsparcie dla Reflection API.

127 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Programowanie aplikacji dla platformy Android Co będzie potrzebne? Abyśmy mogli programować, musimy najpierw pobrać odpowiednie SDK ze strony Należy także spełnić stosowne wymagania systemowe – SDK zadziała na Windows XP lub Vista, MacOS X lub nowszy (tylko na platformie x86)), Linux, będziemy potrzebować także JDK w wersji 5 lub 6. Wskazane jest zainstalowanie również środowiska Eclipse, ze względu na prostotę zarządzania projektami, nad którymi będziemy pracować.

128 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Model aplikacji Pakiet android (.apk) Plik zawierający kod i ewentualne zasoby aplikacji, Task Jest to ta cześć pakietu, która użytkownik uważa za aplikację Proces proces jadra, w którym uruchamiana jest aplikacja, zwykle cały kod.apk uruchamiany w jednym procesie, Watek w ramach procesu jeden lub więcej wątków. Android unika tworzenia własnych dodatkowych wątków, dopóki nie jest to konieczne

129 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Cykl życia aplikacji Tworząc nową aktywność (Activity) wywoływana jest metoda onCreate(), a następnie onStart() i onResume(). Dziedzicząc po klasie Activity, nie jest konieczne implementowanie każdej z tych metod. Najczęściej nadpisuje się metodę onCreate(), zawierając w niej kod, który jest uruchamiany podczas uruchomienia aktywności. W chwili gdy użytkownik uruchomi nową aktywność czy wręcz aplikację, poprzednia jest wstrzymywana, co objawia się wywołaniem metod onPause() oraz onStop(). W przypadku gdy użytkownik powróci do ekranu, system wywołuje metodę onRestart(), a gdy aplikacja jest zamykana - onDestroy(). W przypadku tworzenia rozbudowanego systemu z dużą liczbą klas dziedziczących po Activity, należy mieć na uwadze cykl ich życia. W przeciwnym wypadku łatwo można pogubić się w całym procesie, co może skutkować np. niemożnością zamknięcia całej aplikacji przez użytkownika.

130 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Programowanie i testowanie w Android OS - przykłady

131 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Adroid rozdziela tworzenie Gui od logiki programu. W klasie MainActivity zawarta jest logika programu, Natomiast w plikach main.xml i strings.xml znajdują się elementy GUI.

132 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ public class HelloAndroid extends Activity { /** Called when the activity is first created. public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); s etContentView(R.layout.main); } Klasa Activity Do metody onCreate przekazywany jest stan Activity z poprzedniego uruchomienia. Na początku trzeba wywołać metodę onCreate klasy Activity po której dziedziczymy (super.onCreate – żeby pojawiło się czarne okienko, które będziemy mogli wypełnić). Podstawową jednostką w aplikacji jest Activity, czyli aktywność z którą użytkownik ma do czynienia, pojedyncza strona aplikacji. Aplikacja może mieć wiele Activity.

133 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Android rozdziela funkcje logiki programu, od jego części wizualnej. Ta bowiem zapisana jest w dwóch plikach, w formacie XML-a – main.xml oraz Strings.xml main.xml opisuje wygląd pierwszej strony naszej aplikacji. LinearLayout to kontener na elementy, który automatycznie ustawia je obok siebie w ustalonej orientacji (android:orientation=vertical/horizontal), wypadałoby, żeby główny kontener zajmował całą dostępną przestrzeń ekranu, więc mamy android:layout_width=fill_parent android:layout_height=fill_parent. TextView to normalny element tekstowy (takij jak JLabel, albo normalny tekst w HTML) jako wartość parametru android:text podawana jest otwartym tekstem zawartość, która ma zostać wyświetlona. lub referencję do wartości podanej w pliku res/values/strings.xml Hello Android Hello World, HelloAndroid!>/string> Przykładowy plik main.xml Przykładowy plik Strings.xml

134 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ ?xml version="1.0" encoding="utf-8"?> Przykład pliku Main.xml – GUI będzie zawierał tylko jedno pole tekstowe o id label

135 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Definicja dwóch pól tekstowych, w których można zapisać dwie liczby

136 Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ


Pobierz ppt "Programowanie urządzeń mobilnych © 2009 mgr inż. Łukasz Jopek Katedra Informatyki Stosowanej PŁ Wykład 1 Wprowadzenie."

Podobne prezentacje


Reklamy Google