Programowanie urządzeń mobilnych LAB1

advertisement
Programowanie urządzeń mobilnych
LAB1
Paweł Fiderek
Cel laboratorium
Celem laboratorium jest zapoznanie się z możliwościami programowania urządzeń mobilnych
w technologii Java MicroEdition.
Część teoretyczna - wprowadzenie
Urządzenia przenośne o małej mocy obliczeniowej możemy podzielić na klasy w zależności
od dostępnej u nich mocy obliczeniowej, pamięci, rodzaju wyświetlacza (rozdzielczość,
liczba dostępnych kolorów), sposobu wprowadzania danych (klawiatura telefonu, pełna
klawiatura, rysik). J2ME zbudowana jest na zasadzie zbioru specyfikacji konfiguracji, z
których każda zawiera minimalny zbiór pakietów i klas przeznaczonych dla konkretnej klasy
urządzeń przenośnych. W specyfikacji J2ME zdefiniowane są dwie konfiguracje CDC oraz
CLDC.
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. 2048 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.
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.
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 i uruchamiane są
w środowisku K virtual machine.
Profil MIDP zawiera bardziej rozbudowaną obsługę platformy Java niż sama konfiguracja
CLDC. MIDP wymagają 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.
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.
Instalacja środowiska.



Java Platform Micro Edition Software Development Kit 3.0 wraz z podstawową
dokumentacją
oraz środowisko programistyczne np.
o NetBeans w wersji „Java”
o Eclipse wraz z odpowiednią wtyczką EclipseME
i utworzeniu w danym środowisku nowego projektu odpowiedzialnego za budowanie
aplikacji na urządzenia mobilne.
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.
Budowa aplikacji MIDP
Główna klasa aplikacji (Midlet) to klasa dziedzicząca po klasie
java.microedition.midlet.MIDlet. Klasa ta musi posiadać definicje
przynajmniej trzech metod:

startApp() odpowiedzialnej za inicjalizację MIDlet’u lub powrót jego ze stanu
zatrzymania
o
o
o
o

pauseApp() odpowiedzialnej za wstrzymanie działania aplikacji (np. podczas
odbierania rozmowy)
o
o

Program staje się aktywny
Dokonać inicjalizacji, wczytać zasoby, pokazać coś na ekranie
Jeśli nie udaje się uaktywnić, rzucić wyjątek MIDletStateChangeException
Jeśli nieodwracalny błąd, wywołać notifyDestroyed
Program staje się nieaktywny
Zwolnić wszystkie zasoby zajmujące dużo procesora lub pamięci
destroyApp() odpowiedzialnej za zamykanie aplikacji
o
o
o
Program zostaje wyłączony
Zapisać trwałe dane
Jeśli odmawia wyłączenia, rzucić wyjątek MIDletStateChangeException
(tylko jeśli unconditional == false)
Zatem szkielet najprostszego midletu powinien wyglądać następująco:
import javax.microedition.midlet.MIDlet;
public class PierwszyMIDlet extends MIDlet {
public void startApp(){
}
public void pauseApp(){
}
public void destroyApp(boolean unconditional){
}
}
Wyświetlanie dowolnej informacji na ekranie można zrealizować za pomocą:

obiektu TextBox i wstawieniu go na pulpit wyświetlacza.
Konstruktor klasy TextBox przyjmuje trzy parametry:
public TextBox(String title, String text, int maxSize, int constraints);
tj. tytuł kontrolki komunikatu, treść komunikatu oraz długość i ewentualne
ograniczenia
Z kolei referencja Display do obiektu wyświetlacza jest dziedziczona po klasie
MIDlet i referencję do pulpitu wyświetlacza można uzyskać korzystając z metody
getDisplay. Następnie za pomocą metody setCurrent ustawiamy kontrolkę
jako ekran bieżący np.
tb = new TextBox("Tytuł", "Treść komunikatu", 80,
TextField.UNEDITABLE);
Display.getDisplay(this).setCurrent(tb);

obiektu Alert
Konstruktor klasy Alert przyjmuje 1 lub 4 parametry
public Alert(String title,
AlertType
String
alertText,
Image
alertImage,
alertType)
tj. tytuł alertu, jego komunikat, ewentulana referencja do obrazka i rodzaj.
Dodatkowo można ustawić mu czas życia w milisekundach lub zdecydować, że ma
być wyświetlany do czasu zamknięcia go przez użytkownika
al.setTimeout(Alert.FOREVER);
i podobnie wyświetlić go na ekranie.
Poniżej zamieszczone są gotowe fragmenty kodu ilustrujące metody wyświetlania informacji.
Wyświetlanie informacji na ekranie
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class PierwszyMIDlet extends MIDlet {
// wykorzystanie klasy TextBox (okno tekstowe)
private TextBox tb;
public void startApp() {
// tworzymy obiekt klasy TextBox
tb = new TextBox("Tytuł", "Treść komunikatu",
80, TextField.UNEDITABLE);
// ustawiamy ekran poczatkowy
Display.getDisplay(this).setCurrent(tb);
}
public void pauseApp() {
}
public void destroyApp(boolean u) {
}
}
Przykładowa aplikacja wykorzystująca klasę Alert
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class PierwszyMIDlet extends MIDlet {
public void startApp() {
Alert al = new Alert("Tytuł", "Treść informacji", null, AlertType.INFO);
al.setTimeout(Alert.FOREVER);
Display.getDisplay(this).setCurrent(al);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
W dalszej części kursu zostanie pokazane obsługa komend w MIDletach, która związana jest
z implementacją interfejsu CommandListener oraz definicją metody
public void commandAction(Command c, Displayable d);
Przykładowa aplikacja z obsługą komendę (zamykanie MIDletu)
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class WyswietlanieTekstu extends MIDlet
implements CommandListener {
private TextBox tb;
private Command exitCommand;
public void startApp() {
tb = new TextBox("Tytuł", "Komunikat", 80,
TextField.UNEDITABLE);
// tworzymy nowe polecenie
exitCommand = new Command("Zakończ", Command.EXIT, 0);
// dodajemy polecenie do pola tekstowego
tb.addCommand(exitCommand);
// wskazujemy obiekt obslugujacy zdarzenia
tb.setCommandListener(this);
Display.getDisplay(this).setCurrent(tb);
}
public void pauseApp() {
}
public void destroyApp(boolean u) {
}
// ciało metody z interfejsu CommandListener
public void commandAction(Command c, Displayable d) {
// obsługa polecenia exitCommand (kończy działanie aplikacji)
if (c == exitCommand) {
destroyApp(true);
notifyDestroyed();
}
}
}
Telefon sam określa rozmieszczenie i sposób uruchamiania poleceń
Kiedy poleceń jest dużo, zapewnia menu
Część 2.
Należy skorzystać z implementacji klasy Canvas oraz przesłonić jej kilka kluczowych metod.
Wywołanie metody repaint() powoduje wymuszenie odrysowania ekranu i wywołanie
metody paint().
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Wskaznik extends MIDlet{
private Display display;
public void startApp(){
display = Display.getDisplay(this);
display.setCurrent (new MyCanvas());
}
public void pauseApp(){}
public void destroyApp (boolean forced){}
}
class MyCanvas extends Canvas {
String akcja = "Naciśnij";
int x;
int y;
public MyCanvas() {
setFullScreenMode(true);
}
public void pointerPressed (int x, int y) {
akcja = "Naciśnięty";
this.x = x; this.y = y; repaint ();
}
public void pointerReleased (int x, int y) {
akcja = "Zwolniony";
this.x = x; this.y = y; repaint ();
}
public void pointerDragged (int x, int y) {
akcja = "Przenoszenie";
this.x = x; this.y = y; repaint ();
}
public void paint (Graphics g) {
g.setGrayScale (255);
g.fillRect (0, 0, getWidth(), getHeight());
g.setGrayScale (0);
g.drawString (akcja + " " + x + "/" + y, 0, 0,
Graphics.TOP|Graphics.LEFT);
g.drawLine (x-4, y, x+4, y);
g.drawLine (x, y-4, x, y+4);
}
}
Uwaga!
Aby poprawnie działał w symulatorze ekran dotykowy, należy we właściowościach projektu
w części Platform zmienić rodzaj symulowanego urządzenie.
1. Rysowanie po ekranie
Do rysowania należy utworzyć własną klasę dziedzicząca po znanej już klasie Canvas i
dodać jej instancję do obiektu Display. Metoda paint() odrysowuje ekran zgodnie z jej
definicją.
Przykład kodu:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class RysowaniePoEkranie extends MIDlet{
private Display display;
public void startApp(){
Canvas plotno = new Plotno();
display = Display.getDisplay(this);
display.setCurrent(plotno);
}
public void pauseApp(){}
public void destroyApp(boolean unconditional){}
}
class Plotno extends Canvas {
public Plotno() {
setFullScreenMode(true);
}
public void paint(Graphics g) {
int width = getWidth();
int height = getHeight();
g.setColor(255, 162, 117);
g.fillRect(0, 0, width, height);
g.setColor(0, 0, 255);
g.drawLine(0, height/2, width - 1, height/2);
g.setStrokeStyle(Graphics.DOTTED);
g.setColor(0xFFFF00);
g.drawLine(0, height/4, width - 1, height/4);
g.setColor(0, 0, 255);
g.setStrokeStyle(Graphics.SOLID);
g.drawLine(0, 0, width - 1, height - 1);
}
}
Zadania:
1.Stworzyć midlet w którym użytkownik będzie miał możliwość wypełnienia kwestionariusza
osobowego. Użytkownik powinien zobaczyć następujące pola:
Imię – typ string;
Nazwisko – typ string;
Data urodzin – typ date;
Płeć – dwa pola jednokrotnego wyboru;
Stan cywilny – dwa pola jednokrotnego wyboru;
Miejsce urodzenia – typ string;
Numer telefonu – typ całkowity;
Po wypełnieniu kwestionariusza aplikacja ma sprawdzić czy wszystkie pola zostały wypełnione i w
zależności od rezultatu wyświetlić odpowiedni komunikat (alert)
Jeśli jakieś pole niewypełnione: „proszę uzupełnić kwestionariusz”, alert powinien czekać na
odpowiedź użytkownika (na wybranie przycisku ok.);
Jeśli wszystkie wypełnione alert ma wyglądać następująco : „imię nazwisko, płeć stan cywilny,
urodzony w miasto, w wieku wiek lat o numerze telefonu prawidłowo wypełnił kwestionariusz”
Np.: „ Paweł Fiderek, mężczyzna żonaty, urodzony w Tomaszów, w wieku 25 lat o Umerze telefonu
555444111 prawidłowo wypełnił kwestionariusz”
Uwaga!
Ważne jest obliczenie wieku w latach na podstawie daty urodzin.
Powodzenia!
Download