PUM

Transkrypt

PUM
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
Podstawy tworzenia aplikacji z wykorzystaniem języka Java ME
ćwiczenia 3
Wykorzystanie klasy List do tworzenie menu
•
•
Klasa List - tworzenie list wyboru (EXCLUSIVE, MULTIPLE, IMPLICIT)
Dodatkowe możliwości (dodatkowe komendy, pliki graficzne itp.)
Przykładowa aplikacja
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.*;
import java.io.*;
public class MenuLista extends MIDlet implements CommandListener {
private Display dp;
// wykorzystanie klasy List (3 listy: menu główne + listy wyboru)
private List mainMenu, samochodyLista, plytyLista;
// wykorzystanie klasy Form (formularz w ustawieniach)
private Form formularz;
// wykorzystanie klasy TextField (pole tekstowe w formularzu)
private TextField tf;
1
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
// wykorzystanie klasy Alert (informacje o programie)
private Alert info;
// wykorzystanie klasy Command (polecenie OK na ekranach)
private Command oKCommand;
// wykorzystanie klasy Image (obrazki w menu głównym i na listach);
private Image samochod, plyta, konfiguracja, informacja, wyjscie;
public MenuLista() {
// utworzenie menu głównego aplikacji (wykorzystanie listy typu IMPLICIT)
mainMenu = new List("Menu aplikacji", List.IMPLICIT);
// utworzenie obrazków z plików znajdujących się w katalogu res
try {
samochod = Image.createImage("/car.png");
plyta = Image.createImage("/cd.png");
konfiguracja = Image.createImage("/settings.png");
informacja = Image.createImage("/info.png");
wyjscie = Image.createImage("/exit.png");
}
catch (IOException e) {
System.out.println("Brak obrazka!");
}
// dodanie kolejnych pozycji menu (drugi parametr obiekt klasy Image)
mainMenu.append("Samochody", samochod);
mainMenu.append("Płyty CD", plyta);
mainMenu.append("Konfiguracja", konfiguracja);
mainMenu.append("Informacja o programie", informacja);
mainMenu.append("Wyjście", wyjscie);
// ustawienie nasłuchiwacza (bieżąca klasa)
mainMenu.setCommandListener(this);
// utworzenie polecenia OK
oKCommand = new Command("OK", Command.OK, 0);
// utworzenie listy samochodów (wykorzystanie listy typu EXCLUSIVE) i dodanie
// pozycji
samochodyLista = new List("Wybierz samochód", List.EXCLUSIVE);
samochodyLista.append("Fiat Panda", samochod);
samochodyLista.append("Ford Mondeo", samochod);
samochodyLista.append("Seat Leon", samochod);
samochodyLista.append("Skoda Fabia", samochod);
// dodanie do listy samochodów polecenia OK
samochodyLista.addCommand(oKCommand);
// ustawienie nasłuchiwacza (bieżąca klasa)
samochodyLista.setCommandListener(this);
// utworzenie listy płyt CD (wykorzystanie listy typu MULTIPLE) i dodanie pozycji
plytyLista = new List("Zaznacz płyty", List.MULTIPLE);
plytyLista.append("Dire Straits - Brothers in Arms", plyta);
plytyLista.append("Pink Floyd - Dark Side of The Moon", plyta);
plytyLista.append("Guns n' Roses - Use your Illusion", plyta);
plytyLista.append("Queen - Innuendo", plyta);
plytyLista.append("Led Zeppelin - IV", plyta);
// dodanie do listy płyt CD polecenia OK
2
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
plytyLista.addCommand(oKCommand);
// ustawienie nasłuchiwacza (bieżąca klasa)
plytyLista.setCommandListener(this);
// utworzenie formularza
formularz = new Form("Konfiguracja");
// utworzenie pola tekstowego
tf = new TextField("Załóż hasło", null, 20, TextField.ANY);
// dodanie pola tekstowego
formularz.append(tf);
// dodanie do formularza polecenia OK
formularz.addCommand(oKCommand);
// ustawienie nasłuchiwacza (bieżąca klasa)
formularz.setCommandListener(this);
// pobranie referencji do obiektu Display
dp = Display.getDisplay(this);
}
public void startApp() {
// ustawienie ekranu głównego (menu główne)
dp.setCurrent(mainMenu);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command c, Displayable d) {
// sprawdzenie czy wystąpiło polecenie wyboru z listy i jesteśmy w głównym menu
if (c == List.SELECT_COMMAND && d == mainMenu) {
// pobranie indeksu wybranej pozycji
int indeks = mainMenu.getSelectedIndex();
// pobranie tekstu związanego z wybraną pozycją
String akcja = mainMenu.getString(indeks);
// obsługa pozycji menu (sprawdzanie akcji ze Stringiem)
if (akcja.equals("Wyjście")) {
// zakończenie pracy midletu
destroyApp(true);
notifyDestroyed();
}
else if (akcja.equals("Samochody")) {
// ustawienie głównego ekranu na listę samochodów
dp.setCurrent(samochodyLista);
}
else if (akcja.equals("Płyty CD")) {
// ustawienie głównego ekranu na listę płyt CD
dp.setCurrent(plytyLista);
}
else if (akcja.equals("Konfiguracja")) {
// ustawienie głównego ekranu na formularz
dp.setCurrent(formularz);
}
else if (akcja.equals("Informacja o programie")) {
3
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
// utworzenie obiektu klasy Alert
Alert al = new Alert("Informacje","Autor: Jan Kowalski\nWersja: 0.666alfa\n",
informacja, AlertType.INFO);
// czas na jaki ma się wyświetlić okno alertu (milisekundy)
al.setTimeout(3000);
// ustawienie głównego ekranu na nasz alert, a po upływie czasu na menu
// główne
dp.setCurrent(al, mainMenu);
}
}
// obsługa polecenia OK (powrót do menu głównego)
else if (c == oKCommand) {
dp.setCurrent(mainMenu);
}
}
}
Zapis danych w pamięci urządzeń mobilnych
•
•
Wykorzystanie RMS (Record Management System)
o pakiet javax.microedition.rms
o klasa RecordStore (zarządzanie zbiorami i rekordami)
utworzenie obiektu klasy RecordStore
RecordStore rs = RecordStore.openRecordStore("baza", true);
•
•
operacje na zbiorze (dodawanie rekordów, modyfikacja, usuwanie)
zamknięcie otwartego zbioru
rs.closeRecordStore();
Przykładowa aplikacja
Zadaniem aplikacji ma być tworzenie i przechowywanie notatek tekstowych.
import
import
import
import
javax.microedition.midlet.MIDlet;
javax.microedition.lcdui.*;
javax.microedition.rms.*;
java.io.*;
public class Kajet extends MIDlet implements CommandListener {
// wykorzystanie klasy Display
private Display dp;
// wykorzystanie klasy List (menu główne, menu z notatkami)
private List mainMenu, listaNotek;
// wykorzystanie klasy TextBox (dodawanie i wyświetlanie notatek)
private TextBox tb, tbf;
// wykorzystujemy klasę RecordStore do zapisu danych w pamięci urządzenia
private RecordStore rs;
// wykorzystanie klasy Command (polecenie powrotu i zapisywania)
4
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
private Command backCommand, saveCommand, backListCommand;
// tablica przechowująca notki
String[] notki;
// konstruktor
public Kajet() {
try {
// otwieramy zbiór z rekordami (jeśli nie istnieje zostanie utworzony)
rs = RecordStore.openRecordStore("Notatki", true);
} catch (RecordStoreException e) {
System.out.println ("Problem z RMS");
}
mainMenu = new List("Kajet", List.IMPLICIT);
mainMenu.append("Nowa notka", null);
mainMenu.append("Lista notek", null);
mainMenu.append("Wyjście",null);
mainMenu.setCommandListener(this);
backCommand = new Command("Wróć", Command.BACK, 0);
backListCommand = new Command("Wróć", Command.BACK, 0);
saveCommand = new Command("Dodaj", Command.SCREEN, 1);
tb = new TextBox("Nowy wpis", null, 320, TextField.ANY);
tb.addCommand(backCommand);
tb.addCommand(saveCommand);
tb.setCommandListener(this);
dp = Display.getDisplay(this);
}
public void startApp() {
dp.setCurrent(mainMenu);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
try {
// zamknięcie zbioru z danymi
rs.closeRecordStore();
} catch (RecordStoreException e) {
System.out.println ("Nie można zamknąć RMS");
}
}
5
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
public void commandAction(Command c, Displayable d) {
// sprawdzenie czy wystąpiło polecenie wyboru z listy i jesteśmy w głównym menu
if (c == List.SELECT_COMMAND && d == mainMenu) {
// pobranie indeksu wybranej pozycji
int indeks = mainMenu.getSelectedIndex();
// pobranie tekstu związanego z wybraną pozycją
String akcja = mainMenu.getString(indeks);
// obsługa pozycji menu (sprawdzanie akcji ze Stringiem)
if (akcja.equals("Wyjście")) {
// zakończenie pracy midletu
destroyApp(true);
notifyDestroyed();
}
else if (akcja.equals("Nowa notka")) {
// wyczyszczenie zawartości pola tekstowego
tb.setString(null);
// ustawienie głównego ekranu na nowy wpis
dp.setCurrent(tb);
}
else if (akcja.equals("Lista notek")) {
// utworzenie listy notek
listaNotek = new List("Lista notek", List.IMPLICIT);
try {
// wyliczenie wszystkich rekordów
RecordEnumeration re = rs.enumerateRecords(null, null, false);
// zmienna pomocnicza
int i = 0;
// tworzymy tablicę Stringów z notkami o rozmiarze takim jak
// liczba rekordów
notki = new String[re.numRecords()];
// przechodzimy przez wszystkie rekordy w naszym zbiorze
while(re.hasNextElement()){
// odczytujemy rekord
byte[] record = re.nextRecord();
// tworzymy strumien danych wejściowych
ByteArrayInputStream raw = new ByteArrayInputStream(record);
DataInputStream in = new DataInputStream(raw);
// odczytujemy notkę
String notka = in.readUTF();
// wpisujemy notkę do tablicy
notki[i] = notka;
i++;
// tworzymy krótką wersję notki do pokazania na liście
notka = notka.substring(0, (notka.length()) > 40 ? 40 :
notka.length()) + "...";
listaNotek.append(notka, null);
6
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
// zamykamy strumień danych wejściowych
in.close();
}
} catch (IOException e) {
System.out.println ("Bład wejścia/wyjścia");
} catch (RecordStoreException e) {
System.out.println ("Błąd zapisu RMS");
}
// dodajemy polecenie powrotu do głównego menu
listaNotek.addCommand(backCommand);
// ustawiamy nasłuchiwacza na bieżącą klasę
listaNotek.setCommandListener(this);
// ustawienie głównego ekranu na listę notek
dp.setCurrent(listaNotek);
}
}
// obsługa listy notek, po wybraniu notki pokazujemy jej całą treść
else if (c == List.SELECT_COMMAND && d == listaNotek) {
// tworzymy pole tekstowe z zawartością odpowiedniej notki pobranej z tablicy
// notek
tbf = new TextBox("Pełny tekst", notki[listaNotek.getSelectedIndex()], 320,
TextField.UNEDITABLE);
// dodajemy polecenie powrotu na listę notek
tbf.addCommand(backListCommand);
// ustawiamy nasłuchiwacz
tbf.setCommandListener(this);
// ustawiamy bieżący ekran na nasze pole z pełną treścią notki
dp.setCurrent(tbf);
}
// obsługa polecenia BACK (powrót do menu głównego)
else if (c == backCommand) {
dp.setCurrent(mainMenu);
}
// obsługa polecenia BACK (powrót do menu z listą notek)
else if (c == backListCommand) {
dp.setCurrent(listaNotek);
}
// obsługa polecenia zapisz
else if (c == saveCommand) {
// tworzymy strumień danych wyjściowych
ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(arrayStream);
try {
// wpisujemy dane pobrane z pola tekstowego do strumienia
out.writeUTF(tb.getString());
// tworzymy tablice bajtów
byte[] data = arrayStream.toByteArray();
// dodajemy rekord
rs.addRecord(data, 0, data.length);
7
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
// zamykamy strumień
out.close();
} catch (IOException e) {
System.out.println ("Bład wejścia/wyjścia");
} catch (RecordStoreException e) {
System.out.println ("Błąd zapisu RMS");
}
// ustawiamy bieżący ekran na główne menu
dp.setCurrent(mainMenu);
}
}
}
Połączenie z internetem
Wszystkie aplikacje mobilne umożliwiają obsługę połączeń sieciowych za pomocą
prostego API będącego składową GFC (Generic Connection Framework). Obsługiwane
protokoły to http oraz https. Pakiet javax.microedition.io zawiera większość klas
związanych z GFC. Nawiązanie połączenia to wykorzystanie jednej z metod open
dostępnych w klasie Connector. Dostęp do danych z sieci jest możliwy w następujący
sposób:
String url = "http://strona.pl/index.html";
HttpConnection c = (HttpConnection) Connector.open(url);
InputStream in = c.openInputStream();
// in.read() ...odczyt danych
8
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
Przykładowa aplikacja (pobieranie kursu USD z witryny NBP)
import
import
import
import
javax.microedition.lcdui.*;
javax.microedition.midlet.MIDlet;
javax.microedition.io.*;
java.io.*;
public class PobieranieDanych extends MIDlet implements CommandListener {
// wykorzystanie klasy TextBox (okno tekstowe)
private TextBox tb;
// wykorzystanie klasy Command (obsługa komend)
private Command exitCommand;
// wykorzystanie klas HttpConnection (połączenie po http) oraz InputStream (obsługa
// strumienia wejściowego)
private
HttpConnection c;
private
InputStream is;
// wykorzystanie klasy StringBuffer (dynamiczny łańcuch tekstowy)
private StringBuffer sb;
public PobieranieDanych () {
// tworzymy obiekt klasy StringBuffer
sb = new StringBuffer();
try {
// łączymy się ze stroną NBP
c = (HttpConnection) Connector.open("http://nbp.pl/Kursy/KursyA.html",
Connector.READ, true);
// otwieramy strumień danych wejściowych
is = c.openInputStream();
int ch=0;
// odczytujemy wszystkie dane (-1 koniec danych) oraz dodajemy je do
// łańcucha tekstowego
while ((ch = is.read()) != -1) {
sb.append((char) ch);
}
}
catch (IOException x){
System.out.println ("Błąd wejścia wyjścia");
}
finally {
try {
is.close();
c.close();
} catch (IOException x) {
System.out.println ("Błąd wejścia wyjścia");
}
}
9
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
// zamieniamy obiekt klasy StringBuffer na String (potrzebujemy kilku metod)
String wyn = sb.toString();
// wyszukujemy ciągu znaków USD
int i = wyn.indexOf("USD");
// szukamy aktualnegoo kursu USD
i = i + 26;
// wycinamy kurs (ciągle będzie to łańcuch tekstowy)
String wartosc = wyn.substring(i, i + 6);
// zamieniamy , na .
wartosc = wartosc.replace(',','.');
// konwertujemy String z kursem na zmienną typu float
float kurs = Float.parseFloat(wartosc);
// tworzymy nowy obiekt klasy TextBox wraz z aktualnym kursem
tb = new TextBox("Aktualny kurs USD", "USD: " + kurs, 100, TextField.ANY);
// 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);
}
public void startApp() {
// ustawiamy ekran poczatkowy
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) {
// obsluga polecenia exitCommand (kończymy działanie aplikacji)
if (c == exitCommand) {
destroyApp(true);
notifyDestroyed();
}
}
}
Wysyłanie tekstu
Java ME udostępnia prostą komunikację tekstową i multimedialną za pomocą Wireless
Messaging API (WMA). WMA bazuje na GFC (Generic Connection Framework). Pakiet
javax.wireless.messaging zawiera większość klas i metod potrzebnych do takiej
10
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
komunikacji. Wysłanie bądź też odebranie połączenia to utworzenie obiektu klasy
MessageConnection oraz wypełnienie treści wiadomości i jej wysłanie. Poniżej prosty
przykład wysyłania wiadomości tekstowej (SMS):
import
import
import
import
import
javax.microedition.lcdui.*;
javax.microedition.midlet.MIDlet;
javax.microedition.io.*;
java.io.*;
javax.wireless.messaging.*;
/**
* MIDlet: WysylanieSMS
* Klasy główne: TextBox, Alert (dziedziczące z klasy Screen)
*/
public class WysylanieSMS extends MIDlet implements CommandListener, Runnable {
// wykorzystanie klasy TextBox (okno tekstowe)
private TextBox tb;
// wykorzystanie klasy Command (obsługa komend)
private Command exitCommand, sendCommand;
// wykorzystanie klasy Display
private Display dp;
public WysylanieSMS() {
tb = new TextBox("Wpisz tekst", null, 160, TextField.ANY);
// tworzymy nowe polecenia (polecenia związane z aplikacją mają typ
// Command.SCREEN)
exitCommand = new Command("Zakończ", Command.EXIT, 0);
sendCommand = new Command("Wyślij SMS", Command.SCREEN, 1);
// dodajemy polecenia do pola tekstowego
tb.addCommand(exitCommand);
tb.addCommand(sendCommand);
// wskazujemy obiekt obslugujacy zdarzenia
tb.setCommandListener(this);
dp = Display.getDisplay(this);
}
public void startApp() {
dp.setCurrent(tb);
}
public void pauseApp() {
}
public void destroyApp(boolean u) {
}
// ciało metody z interfejsu CommandListener
public void commandAction(Command c, Displayable d) {
// obsluga polecenia exitCommand (kończymy działanie aplikacji)
if (c == exitCommand) {
destroyApp(true);
notifyDestroyed();
11
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
}
// obsluga polecenia infoCommand (wyświetlenie informacji użytkownikowi)
if (c == sendCommand) {
// tworzymy nowy wątek
Thread t = new Thread(this);
// startujemy wątek
t.start();
// tworzymy obiekt klasy Alert wraz z odpowiednimi danymi
Alert al = new Alert("Informacja", "Wysłałeś SMS", null,
AlertType.INFO);
// ustawiamy czas (podany w ms) przez jaki Alert ma być
// wyświetlany
al.setTimeout(2000);
// wyświetlamy Alert oraz wskazujemy na ekran, który ma zostać
// wyświetlony po zamknięciu Alerta
dp.setCurrent(al, tb);
}
}
public void run() {
MessageConnection mc = null;
// Inbox telefonu komórkowego nie podajemy portu
String cs = "sms://+5550001";
try {
// tworzymy połączenie
mc = (MessageConnection) Connector.open(cs);
// tworzymy nową wiadomość tekstową
TextMessage tm = (TextMessage)
mc.newMessage(MessageConnection.TEXT_MESSAGE);
// ustawiamy treść wiadomości
tm.setPayloadText(tb.getString());
// wysyłamy
mc.send(tm);
} catch (IOException ioe) {
System.out.println ("Bład wejścia/wyjścia");
}
// sprawdzamy czy połączenie zostało otwarte
if (mc != null) {
try {
// zamykamy połaczenie
mc.close();
} catch (IOException ioe) {
System.out.println ("Błąd wejścia/wyjścia");
}
}
}
}
12
Programowanie urządzeń mobilnych
Podst a wy t wo rzen ia a pl ik acj i
Zadania
1. Uruchom MIDlet z listą jako menu. Zmień pliki graficzne, dodaj nowe pozycje w
poszczególnych listach.
2. Zapoznaj się z działaniem MIDletu Kajet. Dodaj ikony do poszczególnych pozycji
menu. Zastanów się jak rozbudować funkcjonalność aplikacji (usuwanie notek,
aktualizacja). Wprowadź modyfikacje.
3. Uzupełnij MIDlet PobieranieDanych o nowe waluty (EUR, GPB itd.). Zastanów się
jak przechowywać dane w pamięci urządzenia. Zaprojektuj MIDlet przechowujący
kursy kilku walut wraz z ich datami.
4. Napisz aplikację umożliwiającą wysyłanie SMS'ów, ich archiwizację (folder
wysłane). Program ma mieć możliwość tworzenia SMS'ów przeznaczonych do
wysłania później (folder wersje robocze/do wysłania).
13