Tehnici avansate de programare
Curs -
Cristian Fr ˘asinaru
acf@infoiasi.ro
Facultatea de Informatic ˘a Universitatea ”Al. I. Cuza” Ias¸i
Platforma Java Micro Edition
Cuprins
Introducere
Arhitectura general ˘a Java ME Crearea unui MIDlet simplu
Dezvoltarea suitelor de midlet-uri Interfa¸ta grafic ˘a cu utilizatorul
Tratarea evenimentelor
Crearea jocurilor (Game API)
Asigurarea persisten¸tei datelor (RMS) Distribu¸tia unei suite de midlet-uri
Introducere
Comunica¸tii Wireless
Domeniu extrem de vast
Comunica¸tiile pot fi de naturi diferite:
Radio-Televiziune Telefonie mobile ...
Comunica¸tiile pot fi:
locale
la distan¸t˘a
Exist ˘a o serie protocoale standard Complexitate, fragmentare
Ce este Java ME ?
Java ME reprezint ˘a un set de tehnologii ¸si specifica¸tii concepute pentru dispozitive mobile cu capabilit ˘a¸ti
limitate, cum ar fi pagere, telefoane mobile, sisteme de navigare, PDA-uri, etc.
Java ME aduce conceptul de portabilitate la nivelul
dispozitivelor mobile, oferind un mediu optimizat, bazat pe Java, de dezvoltare a aplica¸tiilor pentru acest
segment software.
JSR + JCP
Specifica¸tiile pentru Java ME (dar ¸si pentru EE, SE) sunt create sub egida Java Comunity Process (JCP), primul pas în în dezvoltarea acestora fiind o cerere de tip Java Specification Request (JSR), venit ˘a din partea
comunit ˘a¸tii Java. Ulterior, acestea sunt analizate de un grup de exper¸ti ¸si rafinate pân ˘a la forma lor final ˘a.
Specifica¸tiile Java ME sunt referite adeseori sub forma num ˘arului corespunz ˘ator JSR, exper¸tii care contribuie la standardizarea lor fiind firme ca Sun, Nokia, Motorolla, Ericsson, Fujitsu, Siemens, Samsung, Vodafone, France Telecom, Orange, etc.
Arhitectura general˘a Java ME
Platforme java
Configura¸tii ¸si profile
Java ME are o arhitectur ˘a modular ˘a ¸si ierarhic ˘a:
Configura¸tii
Specifica¸tii ce detaliza ˘a o ma¸sina virtual ˘a Java ¸si un API restrâns ce st ˘a la baza dezvolt ˘arii de aplica¸tii pentru o anumit ˘a categorie de dispozitive.
Profile
Profilele sunt ata¸sate configura¸tiilor, ad ˘augând API-ul specific necesar cre ˘arii efective a unei aplica¸tii.
Pachete op¸tionale
Privire general˘a
Dezvoltarea de aplica¸tii wireless
Categorii de aplica¸tii
Aplica¸tii locale (independente) - nu necesit ˘a surse externe de date sau comunica¸tii prin re¸tea (jocuri, programe utilitare: agend ˘a, calculator, etc)
Aplica¸tii de re¸tea - con¸tin atât componente locale cât ¸si la distan¸t˘a, aflate pe servere Web (client de email).
Considera¸tii generale
Crearea unei aplica¸tii performante Java ME este o "art ˘a"
ce trebuie s ˘a ¸tin ˘a cont de:
Memoria (volatil ˘a sau persistent ˘a) este limitat ˘a drastic
Procesoare lente
Lipsa unui sistem de fi¸siere clasic
Limit ˘ari, eventual severe, ale conectivit ˘a¸tii Modalitatea de instalare a aplica¸tiei
...
Diferen¸te fa¸t˘a de Java SE
Nu sunt permise opera¸tii în virgul ˘a mobil ˘a Nu mai exist ˘a finalizarea obiectelor
Diferen¸te în modul de tratare a excep¸tiilor
Nu exist ˘a suport pentru JNI, introspec¸tie, serializare Nu exist ˘a grupuri de fire de execu¸tie, demoni.
Nu pot fi definite class loader-e proprii
Verificarea claselor este realizat ˘a diferit (dup ˘a compilare are loc etapa de preverificare)
MIDlet-uri
Aplica¸tii create pentru:
Configura¸tia CLDC (Connected Limited Device Configuration)
Profilul MIDP (Mobile Information Device Profile) Midlet-urile sint distribuite sub forma unor suite.
fie ofer ˘a o serie de func¸tii similare (cum ar fi o colec¸tie de jocuri), sau
fie lucreaz ˘a împreun ˘a, fiind module ale unui sistem mai complex
au acces la acelea¸si resurse (imagini, date, etc.)
MIDlet API
Pachete CLDC
java.lang ⊂ J2SE java.io ⊂ J2SE java.util ⊂ J2SE
javax.microedition.io Pachete MIDP
javax.microedition.midlet javax.microedition.lcdui javax.microedition.rms ...
Crearea unui midlet simplu
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class Hello extends MIDlet implements CommandListener { public void startApp() {
Display display = Display.getDisplay(this);
Form mainForm = new Form("Hello");
mainForm.append("Hello world!");
Command exitCommand = new Command("Exit", Command.EXIT, 0);
mainForm.addCommand(exitCommand);
mainForm.setCommandListener(this);
display.setCurrent(mainForm);
}
public void pauseApp () {}
public void destroyApp(boolean unconditional) {}
public void commandAction(Command c, Displayable s) { if (c.getCommandType() == Command.EXIT)
notifyDestroyed();
Compilarea ¸si execu¸tia
Compilarea presupune:
Apelul compilatorului javac din kitul standard Java.
Preverificarea claselor rezultate cu utilitarul preverify
Execu¸tia
Va fi realizat ˘a folosind un emulator. Acesta va afi¸sa lista midleturilor disponibile in suita selectat ˘a.
Dezvoltarea suitelor de midlet-uri
Modul de lucru
Un midlet este format din unul sau mai multe ecrane (screens). Acestea pot fi
structurate - au o anumit ˘a func¸tionalitate, sunt portabile, nu permit accesul direct la acran sau la mecanisme low-level.
nestructurate (canvas-uri) - permit controlul
ecranului la nivel de pixel, tratarea evenimentelor generate de ap ˘asarea tastelor, etc.
Fiecare ecran are asociat ˘a o serie de comenzi
(abstract commands). Acestea permit utilizatorului navigarea între ecrane ¸si execu¸tia unor ac¸tiuni
specifice.
Ciclul de via¸t˘a
Structura unui midlet
public class MyMIDlet extends MIDlet { public MyMIDlet() {
// Crearea de ecrane
// Crearea si asocierea de actiuni ecranelor
// Stabilirea claselor de tip listener pentru actiuni }
public void startApp() {
// Setarea eranului initial/curent // Pornirea unor fire de executie }
public void pauseApp () {
// Eliberarea temporara a unor resurse // Oprirea unr fire de executie
}
public void destroyApp(boolean unconditional) { // Eliberarea tuturor resurselor
// Salvarea starii persistente a aplicatiei }
}
Interfa¸ta grafic˘a
Interfa¸ta grafic ˘a cu utilizatorul a fost implementat ˘a ¸tinând cont de particularit ˘a¸tile fizice ale dispozitivelor mobile.
Specifica¸tiile CLDC nu au nici o referire la GUI, ele fiind definite în MIDP.
Pachetele care ofer ˘a suport pentru crearea GUI:
javax.microedition.lcdui
javax.microedition.lcdui.game
Gestiunea ecranului propriu-zis ¸si a celorlalte
mecanisme fizice accesibile ale dispozitivului se face prin intermediul clasei Display, aceasta fiind
responsabil ˘a ¸si de gestiunea screen-urilor aplicatiei.
Clasa Displayable
Este supeclasa abstract ˘a a ecranelor, definind func¸tionalitatea comun ˘a a acestora:
pot avea un titlu
pot avea un ticker (un text ce se deplaseaz ˘a în mod continuu pe ecran)
pot avea zero sau mai multe comenzi pot avea un CommandListener
Implement ˘arile de baz ˘a ale acestei clase sunt:
Screen - ecrane structurate Canvas - ecrane nestructurate
Clasa Screen
Este superclasa abstract ˘a a ecranelor structurate, implement ˘arile directe fiind:
Alert - Mesaje de avertizare, erori, etc.
Form - Permite crearea de ecrane compuse din alte componente, cum ar fi imagini (Image) sau articole derivate din Item:
ChoiceGroup, CustomItem, DateField, Gauge, ImageItem, Spacer, StringItem, TextField
List - Ecran pentru selectarea unei op¸tiuni dintr-o mul¸time prestabilit ˘a.
TextBox - Ecran pentru introducerea unui text.
Crearea form-urilor
Articolele unui ecran Form sunt referite prin indexul lor (un num ˘ar între 0 ¸si size() - 1), gestiunea lor fiind realizat ˘a prin intermediul metodelor: append, insert, set, delete.
Pozi¸tionarea articolelor se face pe linii, dup ˘a un algoritm prestabilit. In cazul in care articolele nu incap in ecran, va fi creat ˘a automat o bar ˘a vertical ˘a de derulare.
mainForm.append("Introduceti datele:");
mainForm.append(new TextField("Nume", "", 50, TextField.ANY));
mainForm.append(new DateField("Data", DateField.DATE));
Tratarea evenimentelor generate de modificare
con¸tinutului unui articol se face prin implementarea interfe¸tei ItemStateListener.
Interfa¸ta ItemStateListener
Metoda interfe¸tei este: itemStateChanged(Item item).
Form mainForm = new Form("Hello");
StringItem s = new StringItem(null, "Hello world");
TextField tf = new TextField("Nume", "", 50, TextField.ANY);
...
mainForm.append(s);
mainForm.append(tf);
mainForm.setItemStateListener(new ItemStateListener() { public void itemStateChanged(Item item) {
s.setText("Hello " + tf.getString());
} });
Clasa Canvas
Este clasa de baz ˘a pentru aplica¸tii care necesit ˘a
desenare la nivel de pixel ¸si tratarea unor evenimente low-level (→ jocuri !!)
Desenarea se face în metoda paint
Tratarea evenimentelor se face în metode specifice cum ar fi: keyPressed, keyRepeated,
keyReleased, etc.
Derivat ˘a din Canvas, este GameCanvas care ofer ˘a facilit ˘a¸ti suplimentare pentru dezvoltarea de jocuri.
Definirea comenzilor
Comenzi abstracte - high-level: Command Etichet ˘a: nume scurt / lung
Tip: BACK, CANCEL, EXIT, HELP, ITEM, OK, SCREEN, STOP
Prioritate: num ˘ar întreg; cel mai mic num ˘ar - cea mai important ˘a comand ˘a.
Dispunerea comenzilor pe ecran va ¸tine cont de tipurile
¸si priorit ˘a¸tile acestora.
Ad ˘augare de comenzi pentru un ecran: addCommand.
Tratarea evenimentelor generate de ac¸tionarea comenzilor: CommandListener.
Interfa¸ta CommandListener
Metoda interfe¸tei este:
commandAction(Command c, Displayable s).
public class MyListener implements CommandListener { public void commandAction(Command c, Displayable s) {
if (c.getCommandType() == Command.EXIT) notifyDestroyed();
if (c.getLabel().equals("Play")) letsPlayTheGame();
...
}
Imagini
Imaginile sunt utilizate prin intermediul clasei Image.
Formatul admis este PNG (Portable Network Graphics) Crearea se realizeaz ˘a prin metoda: Image.createImage, con¸tinutul imaginii putând fi:
preluat din resursele midletului (imutable) creat explicit din program (mutable)
Folosirea imaginilor
componente în cadrul form-urilor
Form mainForm = new Form("Hello");
Image img = Image.createImage("/Taz.png");
mainForm.append(img) ; // sau
ImageItem item = new ImageItem("Poza", img, Item.LAYOUT_CENTER, "Taz")) mainForm.append(item) ;
desenare în canvas-uri
public void paint(Graphics g) {
Image img = Image.createImage("/Taz.png");
g.drawImage(0, 0, HCENTER | VCENTER); }
double-buffering
Image img = Image.createImage(width, height);
Graphics gmem = img.getGraphics();
gmem.drawLine(0, 0, 10, 10);
Crearea jocurilor de "ac¸tiune"
Varianta veche
public void MyGameCanvas extends Canvas implements Runnable {
public void run() { while (true) {
// Actualizeaza starea jocului repaint();
// Pauza }
}
public void paint(Graphics g) { // Desenare
}
protected void keyPressed(int keyCode) { // Tratare apasare taste
} }
Varianta nou˘a
public void MyGameCanvas extends GameCanvas implements Runnable {
public void run() {
Graphics g = getGraphics();
while (true) {
// Actualizeaza starea jocului int keyState = getKeyStates();
// Tratare apasare taste // Desenare
flushGraphics();
// Pauza }
}
"Planurile" unui joc
Reprezentarea unui joc de "ac¸tiune" la un moment dat const ˘a în suprapunerea unor desene, fiecare aflat într-un anumit plan (layer), unele dintre ele fiind statice iar altele mobile. Stratificarea aplica¸tiei în acest fel permite
manevrarea mai u¸soar ˘a ¸si independent ˘a a planurilor.
Suportul pentru crearea planurilor este oferit de clasele:
Layer
TiledLayer Sprite
LayerManager
Definirea componentelor tile
Crearea fundalului
Definirea "spiridu¸silor"
Definirea anima¸tiei
Crearea jocului propriu-zis
Asigurarea persisten¸tei datelor
Record Management System
Prin clasele sale, RMS ofer ˘a suportul pentru asigurarea persisten¸tei unor informa¸tii între dou ˘a execu¸tii succesive ale unui midlet.
Memorarea datelor este realizat ˘a într-o tabel ˘a de
persisten¸t ˘a, format ˘a din articole. Fiecare articol este compus din:
ID - valoare asignat ˘a automat ce identific ˘a în mod unic articolele din tabela de persisten¸t˘a.
con¸tinut - un tablou de octe¸ti, lungimea acestuia putând varia de la un articol la altul.
Tabele de persisten¸t˘a
javax.microedition.rms.RecordStore
Un midlet poate crea oric ˘ate tabele de persisten¸t˘a,
fiecare fiind identificat ˘a prin numele s ˘au care trebuie s ˘a fie unic în cadrul suitei.
Fiecare midlet dintr-o suit ˘a poate avea acces la tabelele celorlalte. Aceeas¸si tabel ˘a poate fi utilizat ˘a concurent de mai multe midleturi, implementarea clasei RecordSet asigurând sincronizarea accesului.
Detectarea modific ˘arilor:
Ob¸tinerea num ˘arului de versiune Setarea unui RecordListener.
Gestiunea tabelelor
Opera¸tiile ce pot fi efectuate: creare / ¸stergere, deschidere / închidere, etc.
import javax.microedition.rms.*;
RecordStore rs = null;
try {
boolean createIfNecessary = true;
rs = RecordStore.openRecordStore("mydata", createIfNecessary);
...
rs.closeRecordStore();
}
catch( RecordStoreNotFoundException e ){
// tabela nu exista
catch( RecordStoreNotOpenException e ){
// tabela nu este deschisa
} catch( RecordStoreException e ){
// alta eroare (spatiu insuficient, etc.)
Gestiunea articolelor
ID (autoincrement) Con¸tinut (buffer de octet¸ti)
byte[] data = {0, 1};
try {
int id = rs.addRecord( data, 0, data.length );
...
int numBytes = rs.getRecord(id, data, 0 );
rs.deleteRecord(id);
}
catch( RecordStoreFullException e ){
// spatiu insuficient
} catch( InvalidRecordIDException e ){
// id-ul specificat nu exista } catch( RecordStoreException e ){
// general error }
Scrierea/Citirea tipurilor primitive
Scrierea
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(baos);
out.writeUTF("Hello");
out.writeInt(123);
byte data[] = baos.toByteArray();
rs.addRecord( data, 0, data.length );
Citirea
byte data[];
rs.getRecord(id, data, 0);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
DataInputStream in = new DataInStream(bais);
String s = in.readUTF();
int n = in.readInt(123);
Enumerarea articolelor
Enumerarea articolelor unei tabele de persisten¸t˘a:
public RecordEnumeration enumerateRecords(
RecordFilter filter,
RecordComparator comparator, boolean keepUpdated)
RecordEnumeration - interfa¸t˘a ce descrie un enumerator bidirec¸tional pentru parcurgerea enumer ˘arii.
RecordFilter - interfa¸t˘a pentru filtrarea enumer ˘arii conform unor criterii proprii.
RecordComparator - interfa¸t˘a pentru compararea / sortarea articolelor din enumerare.
Programare de re¸tea folosind
MIDP
Generic Connection Framework
GCF define¸ste fundamentele pentru dezvoltarea
aplica¸tiilor de re¸tea pentru dispozitive mobile, oferind
suport pentru toate tipurile de comunicare fie pe baz ˘a de pachete, fie pe baz ˘a de fluxuri.
Ini¸tial, modelul GFC a fost definit în configura¸tia CLDC (Connected Limited Device Configuration), în pachetul javax.microedition.io.
Ierarhia claselor ¸si interfe¸telor
Formatul geneal al unui URL
protocol:adresa;parameteri
protocol - metoda de acces: ftp, http, etc
adresa - numele complet sau IP-ul resursei, portul, utilizator, parola, calea local ˘a, etc.
parameteri - perechi de forma ;nume=valoare.
Exemple
http://java.sun.com/developer datagram://address:port#
comm:0;baudrate=9600 file:/myFile.txt
...
Tipuri de conexiuni
btl2cap Bluetooth L2CAPConnection
datagram Datagram DatagramConnection
file File Access FileConnection, InputConnection http HyperText Transport Protocol HttpConnection
https Secure HTTP HttpsConnection
comm Serial I/O CommConnection
sms Short Messaging Service MessageConnection mms Multimedia Messaging Service
cbs Cell Broadcast SMS
apdu Security Element APDUConnection,
jcrmi JavaCardRMIConnection
socket Socket SocketConnection,
serversocket ServerSocketConnection
datagram UDP Datagram UDPDatagramConnection
Crearea unei conexiuni
Se realizeaz ˘a cu clasa Connector.
Aceasta este o clas ˘a de tip Factory, în sensul c ˘a va instan¸tia un obiect func¸tie de schema (protocolul) specificat în URL.
Metoda Connector.open
String url = "socket://www.j2medeveloper.com:80";
c = (SocketConnection)Connector.open(url);
s = c.openInputStream();
Metode de crearea direct ˘a a unor fluxuri specifice
String url = "socket://www.j2medeveloper.com:80";
s = (InputStream)Connector.openInputStream(url);
Conexiuni suportate de MIDP
HttpConnection
HTTP este un protocol bazat pe paradigma
cerere-r ˘aspuns, în care parametrii cererii trebuie trimi¸si înaintea cererii propriu-zise. Conexiunea poate exista în una din st ˘arile:
Setup - In aceast ˘a stare pot fi apelate doar metodele setRequestMethod ¸si setRequestProperty
Connected - Mtode cum ar fi openInputStream, openDataInputStream determin ˘a tranzi¸tia din starea Setup în starea Connected
Closed
Citirea unui fi¸sier
String url = "http://www.infoiasi.ro/˜acf/hello.txt"
StreamConnection c = null;
InputStream s = null;
StringBuffer b = new StringBuffer();
try {
c = (StreamConnection)Connector.open(url);
s = c.openInputStream();
int ch;
while((ch = s.read()) != -1) { b.append((char) ch);
}
System.out.println(b.toString());
} finally {
if(s != null) s.close();
if(c != null) c.close();
}
Programare low-level
Incepând cu MIDP 2.0 a fost introdus suport pentru programare de re¸tea low-level, folosind socket-uri ¸si datagrame. Interfe¸tele ad ˘augate în
javax.microedition.io sunt:
pentru protoculul socket: SocketConnection, ServerSocketConnection
Connector.open("socket://host:port") -> SocketConnection
Connector.open("socket://:port") -> ServerSocketConnection
pentru protoculul datagram:
UDPDatagramConnection
Connector.open("datagram://host:port") -> UDPDatagramConnection
Interfa¸ta ServerSocketConnection
...
ServerSocketConnection server =
(ServerSocketConnection) Connector.open("socket://:2500");
SocketConnection client =
(SocketConnection) server.acceptAndOpen();
client.setSocketOption(DELAY, 0);
client.setSocketOption(KEEPALIVE, 0);
DataInputStream dis = client.openDataInputStream();
DataOutputStream dos = client.openDataOutputStream();
String result = is.readUTF();
os.writeUTF(...);
is.close();
os.close();
client.close();
Interfa¸ta SocketConnection
...
SocketConnection client =
(SocketConnection) Connector.open("socket://" + hostname + ":" + port);
client.setSocketOption(DELAY, 0);
client.setSocketOption(KEEPALIVE, 0);
InputStream is = client.openInputStream();
OutputStream os = client.openOutputStream();
os.write("some string".getBytes());
int c = 0;
while((c = is.read()) != -1) {
// do something with the response }
is.close();
os.close();
client.close();
...
Wireless Messaging API (WMA)
Ce este WMA ?
WMA ofer ˘a suport pentru trimiterea / recep¸tionarea de mesaje text sau binare, cum ar fi SMS-uri (Short
Message Service).
WMA este un pachet op¸tional
(javax.wireless.messaging), bazat pe Generic
Connection Framework (GCF) ce extinde profile create pe configura¸tia CLDC.
Componentele WMA
WMA API
Message getAddress(), getTimestamp(), setAddress() BinaryMessage getPayloadData(), setPayloadData()
TextMessage getPayloadText(), setPayloadText() MessageConnection newMessage(), receive(), send(),
setMessageListener(), numberOfSegments() MessageListener notifyIncomingMessage()
Crearea unei conexiuni
Modul client - doar pentru a trimite mesaje
(MessageConnection)Connector.open("sms://+5121234567:5000");
Modul server - pentru a trimite / recep¸tiona mesaje
(MessageConnection)Connector.open("sms://:5000");
Tipuri de protocoale sms
sms cbs
Trimiterea unui mesaj text
public void sendTextMessage(MessageConnection mc, String msg,
String url) { try {
TextMessage tmsg =
(TextMessage)mc.newMessage(MessageConnection.TEXT_MESSAGE);
tmsg.setAddress(url);
tmsg.setPayloadText(msg);
mc.send(tmsg);
}
catch(Exception e) {
System.out.println("sendTextMessage " + e);
} }
Trimiterea unui mesaj binar
public void sendBinaryMessage(MessageConnection mc, byte[] msg,
String url) { try {
BinaryMessage bmsg =
(BinaryMessage)mc.newMessage(MessageConnection.BINARY_MESSAGE);
bmsg.setAddress(url);
bmsg.setPayloadData(msg);
mc.send(bmsg);
}
catch(Exception e) {
System.out.println("sendBinaryMessage " + e);
} }
Recep¸tionarea mesajelor
Implementarea interfe¸tei MessageListener
public class WMAMIDlet extends MIDlet implements MessageListener { ...
public void notifyIncomingMessage(MessageConnection conn) { // Procesare mesaj
} }
Inregistrarea ascult ˘atorului
public void startApp() { ...
MessageConnection mc = (MessageConnection)Connector.open("sms://:
mc.setMessageListener(this);
...
}
Procesarea mesajelor
Este realizat ˘a uzual într-un fir de execu¸tie.
public void run() { ...
Message msg = mc.receive();
if (msg instanceof TextMessage) {
TextMessage tmsg = (TextMessage)msg;
String data = tmsg.getPayloadText();
}
if (msg instanceof BinaryMessage) {
BinaryMessage bmsg = (BinaryMessage)msg;
byte[] data = bmsg.getPayloadData();
} }
Segmentarea ¸si reasamblarea
Segmentarea ¸si reasamblarea (SAR) este o
caracteristic ˘a a unor protocoale de transport care permite divizarea unui mesaj mare într-o secven¸t˘a
ordonat ˘a de mesaje de dimensiuni mai mici (unit ˘a¸ti de transmisie). Exemplu: 1 segment SMS - 160 caractere.
Pot exista limit ˘ari asupra dimensiunii unui mesaj sau a num ˘arului de segmente. Standard: 3 segemente.
MessageConnection mc = ... ; TextMessage tmsg = ... ;
int segcount = mc.numberOfSegments(tmsg);
if (segcount == 0) { // alert the user }
Bluetooth
Bluetooth reprezint ˘a o tehnologie wireless pentru
distan¸te scurte, cu costuri reduse, pentru crearea de
re¸tele personale (PAN - Personal Area Network). O astfel de re¸tea (piconet) este creat ˘a dinamic într-un spa¸tiu
restrâns în care devine automat posibil ˘a comunicarea
între diferite dispozitive mobile (telefoane, PDA-uri) - unul din ele va fi master, celelalte (cel mult 7), fiind de tip
slave. De asemenea, Bluetooth permite conectarea mai multor piconet-uri.
Java APIs for Bluetooth Wireless Technology (JABWT) permite dezvoltarea de aplica¸tii Java bazate pe
tehnologia Bluetooth.
JXTA
JXTA reprezint ˘a un set de protocoale de re¸tea open-source peer-to-peer (P2P) care permit
comunicarea între orice tipuri de dispozitive conectate în re¸tea: sta¸tii PC, servere, telefoane, PDA-uri, etc.
JXTA poate fi utilizat din orice limbaj, sistem de operare, dispozitiv fizic sau protocol de transport.
Comunicarea este realizat ˘a prin mesaje XML.
JXME (JXTA - J2ME) reprezint ˘a setul de protocoale
JXTA destinat J2ME pentru configura¸tia CLDC ¸si profilul MIDP.
Push Registry
Conceptul de "Push"
Conceptul de "Push" se refer ˘a la mecanismul sau abilitatea unei aplica¸tii de a primi ¸si procesa asincron informa¸tii, având avantajul de a reduce substan¸tial utilizarea resurselor dispozitivului pe care ruleaz ˘a
programul respectiv. Folosind regi¸stri de tip "Push" este posibil ˘a activarea midlet-urilor:
pe baza unui timer prin re¸tea
Utilitatea: aplica¸tii pentru e-mail, agenda, etc.
Elementele Push Registry
Activarea midlet-urilor
Inregistrarea
Static ˘a - în fi¸sierul descriptor (.jad) al suitei de
midleturi pot fi înregistrate doar activ ˘ari prin re¸tea.
MIDlet-Push-<n>: <ConnectionURL>, <MIDletClassName>,
<AllowedSender>
MIDlet-Push-1: socket://:79, com.sun.example.SampleChat, *
MIDlet-Push-2: datagram://:50000, com.sun.example.SampleChat, *
Dinamic ˘a - folosind Push Registry API pot fi
înregistrate la momentul execu¸tiei (runtime) atât activ ˘ari prin re¸tea cât ¸si pe baz ˘a de timer.
PushRegistry.registerAlarm
PushRegistry.registerConnection
Activarea pe baz˘a de timer
private void scheduleMIDlet(long deltatime) throws ClassNotFoundException,
ConnectionNotFoundException, SecurityException {
String midlet = this.getClass().getName();
Date alarm = new Date();
long t = PushRegistry.registerAlarm(midlet, alarm.getTime() + deltatime);
} ...
public void destroyApp(boolean uc) throws MIDletStateChangeException {
// Eliberare resurse ...
// Inregistrarea activarii
scheduleMIDlet(defaultDeltaTime);
display = null;
}
Activarea prin re¸tea
...
String midletClassName = this.getClass().getName();
String url = "socket://:5000";
String filter = "*";
try {
ServerSocketConnection ssc =
(ServerSocketConnection)Connector.open(url);
PushRegistry.registerConnection(url, midletClassName, filter);
SocketConnection sc =
(SocketConnection)ssc.acceptAndOpen();
InputStream is = sc.openInputStream();
...
}
catch(SecurityException e) { ... }
catch(ClassNotFoundException e) { ... } catch(IOException e) { ... }
...