Mobileszközök programozása Java nyelven

Kiegészítő szabványos könyvtárak

RMS | Record Management System

Egy J2ME alkalmazás esetén az adatok kétféle módon tárolhatók: fájlok vagy ún. rekordtárak segítségével. A mobileszközök történetének korai szakaszában a fájlkezelés még nem volt elérhető funkció, helyette a rekordkezelő rendszer (Record Management System - röviden: RMS) biztosította az adatok perzisztens tárolásához szükséges eszközöket. Ezeket az eszközöket a javax.microedition.rms csomag tartalmazza.

Az RMS rekord-alapú adatbázist használ, mely rekordtárakból (RecordStore) áll. Egy MIDlet által létrehozott rekordtár csak a MIDlet által érhető el, kivétel, ha több MIDlet van egy csomagon belül, ekkor mindegyik használhatja ugyanazt a rekordtárat. (Azonban az utóbbi esetben a programozónak kell gondoskodnia a közösen használt rekordtár konzisztenciájának megmaradásáról, ugyanis ezt az RMS alapból nem biztosítja.) Egy MIDlet több rekordtárat is használhat, ekkor azonban a rekordtárak nevének különböznie kell az azonosítás véget. Ha a rekordtárhoz tartozó MIDlet alkalmazást törlik, akkor az ahhoz tartozó rekordtárak is automatikusan törlődnek.

Egy rekordtár rekordok gyűjteménye. Egy rekord tulajdonképpen egy bájt tömb, a rekordtáron belül egyértelműen azonosítja egy egész szám. Új rekord beszúrása esetén az azonosítókat az RMS automatikusan osztja ki egytől kezdve folytonosan. (Tehát az n-edikként beszúrt rekord azonosítója n lesz.) Viszont arra oda kell figyelni, hogy egy rekord törlése esetén az azonosítók nem változnak, így egy rekortáron belül azok nem feltétlenül egyesével követik egymást. Éppen ezért a rekordtár bejerását egy RecordEnumeration típusú objektummal lehet megtenni.

További információk és példakód:

Példakód

Rekordtár megnyitása:
Ha a második paraméter értéke igaz, amennyiben a megadott névvel rekordtár még nem létezik, az RMS létrehoz egy újat.

RecordStore rs = RecordStore.openRecordStore("MyRecordStore", true);

Új rekord beszúrása:
A paraméterek: mit, mettől, meddig.

String data = "New Record";
byte[] bytes = data.getBytes();
rs.addRecord(bytes, 0, bytes.length());

Rekord frissítése:
Az első paraméter adja meg a felülírandó rekord rekordtár beli indexét, ha nem létezik ilyen indexű rekord, kivételt dob.

String newData = "Updeted Record";
byte[] bytes = newData.getBytes();
rs.setRecord(1, bytes, 0, bytes.length());

Rekordtár törlése és bezárása:
Egy rekordtárat használat után mindig be kell zárni.

rs.deleteRecordStore();
rs.closeRecordStore();

JSR-75 | Fájlkezelés

A javax.microedition.io.file és a javax.microedition.pim package-eket tartalmazza. Bevezeti a Fileconnection fogalmát, ami lehetővé teszi a programozók számára a kényelmes fájlkezelést. Statikus adattagjai révén szabványosítja a telefonok fájlstruktúráját, vagyis a programozónak nem kell keresgélnie a készüléken például a fényképeket tartalmazó mappát, hanem elérheti azt a fileconn.dir.photos adattagon keresztül.

További információk

Példaprogram

FileConnection fconn = (FileConnection) (Connector.open(fileDirectory, Connector.READ_WRITE));

if (!fconn.exists()) {
fconn.create();
}

OutputStream ops = fconn.openOutputStream();
ops.write(data);
ops.close();

fconn.close();

Példakód

FileConnection fconn = (FileConnection) (Connector.open(toFileUrl, Connector.READ_WRITE));

if (!fconn.exists()) {
fconn.create();
}

OutputStream ops = fconn.openOutputStream();
for (int i = 0; i < byteData.length; i++) {
ops.write(byteData);
}

ops.close();
fconn.close();

JSR-82 | Bluetooth

A Bluetooth egy alacsony költségű, kis teljesítményű, rádióhullámokra épülő vezeték nélküli adatátviteli technológia. Az első hivatalos specifikáció (Bluetooth 1.0) 1999-ben jelent meg.

További információk

Protokollok

A Bluetooth specifikációja biztosítja a különböző gyártók Bluetooth eszközeinek kompatibilitását. Emiatt a specifikáció több rétegnyi egymásra épülő protokollból áll.

A Bluetooth technológia protokolljai

A három alsó réteg a Bluetooth technológia hardver részében valósul meg. Ezeket a rétegeket a HCI (Host Controller Interface) kapcsolja össze, a HCI felett található, Bluetooth technológia szoftver részében megvalósuló rétegekkel. A legfelső réteg szabja meg, hogy a fejlesztőknek miként kell használniuk ezeket a protokollokat.
A Bluetooth technológiát a Java ME alkalmazásokkal a JABWT (Java APIs for Bluetooth Wireless Technology) köti össze. Ez tulajdonképpen a HCI feletti protokollokat tartalmazza. Két csomagja van a javax.bluetooth és a javax.obex. Az előbbi tartalmazza azokat az osztályokat, amelyek egy Bluetooth kapcsolat kiépítéséhez szükségesek.

További információk

Alapok

A Bluetooth-on keresztüli kommunikáció programozás technikai szempontból a Java hálózaton keresztül történő kommunikációjára hasonlít, azonban a kapcsolat kiépítésében jelentős különbségek tapasztalhatóak. Szintén van egy szerverre, amelyen a Bluetooth alkalmazás fut, valamint legalább egy kliensre, amely magának a Bluetooth kapcsolatnak a kiépítésért felelős. A Java ME platformon ehhez a javax.bluetooth és a javax.microedition.io csomag elemi nyújtanak segítséget. Általában mind a szerver, mind pedig a kliens megvalósítása két külön alkalmazás keretein belül történik, ám lehetőség van ezek egy alkalmazáson belüli megvalósítására is. Fontos, hogy ilyenkor a szerver és a kliens is külön szálon fusson.

Bluetooth eszközök keresése

A javax.bluetooth csomag DiscoveryListener interfészének és DiscoveryAgent osztályának felhasználásával valósítható meg a Bluetooth eszközök illetve az azon futó alkalmazások utáni keresés. Ehhez az interfész négy absztrakt metódusát kell felül definiálni: a deviceDiscovered(), a serviceDiscovered(), a serviceSearchCompleted() és az inquiryCompleted() függvényeket.
A DiscoveryAgent startInquiry() metódusának meghívásával indítható el a közelben lévő Bluetooth eszközök utáni keresés. (A Bluetooth hatótávolsága 10 méter, tehát csak az ekkora sugarú körben lévő, bekapcsolt Bluetooth-szal rendelkező eszközöket fogja a készülékük felismerni.) A metódusnak paramétereként meg kell adni a DiscoveryListener interfészt implementáló objektumot, és egy egészszámot. Az utóbbi az Inquiry Acces Code-ot tartalmazza, amely kétféle lehet: GIAC (General Inquiry Acces Code) és LIAC (Limited Inquiry Acces Code). Ezek határozzák meg, hogy egy készülék mennyi ideig legyen felfedezhető a többi készülék számára. GIAC esetén ez addig tart, amíg a telefon Bluetooth-sza ki nem kapcsolódik, míg LIAC esetén ez csak egy korlátozott időszak.
A keresés elindítása után, minden egyes alkalommal, amikor a készülék egy Bluetooth eszközt detektál, kiváltódik a deviceDiscovered() függvényhívás, amely paraméterként megkapja a talált eszközt reprezentáló RemoteDevice objektumot. A keresésé befejeztével meghívódik az inquiryCompleted() metódus egy int paraméterrel, amely a keresés végállapotát tartalmazza. A végállapot háromféle lehet: a keresés rendben befejeződött, a keresés során valamilyen hiba lépet fel (például kikapcsolt a Bluetooth), vagy pedig a keresés idő előtt terminált. Az utolsó állapotra abban az esetben kerül sor, ha a keresés közben meghívódik a DiscoveryAgent cancelInquiry() metódusa.

Bluetooth eszközök utáni keresés során fellépő állapotok

A Bluetooth eszközök utáni keresés gyorsítására szolgál a DisoveryAgent beépített retrieveDevices() metódusa, amely egy RemoteDevice típusú tömbbel tér vissza. A tömb a retrieveDevices() metódus paramétere alapján azokat a Bluetooth eszközöket tartalmazza, amelyeket vagy az előző keresés során talált a DiscoveryAgent (DiscoveryAgent.CACHED), vagy az alkalmazás futása során valamikor már a készülék kapcsolódott hozzá(DiscoveryAgent.PREKNOWN).Példakód

Kapcsolódás a Bluetooth szerverhez

Egy adott eszközön futó Bluetooth szerveralkalmazások utáni keresés a DiscoveryAgent searchServices() függvényével indítható el. Az egyes szerveralkalmazásoknak egy-egy ServiceRecord típusú objektum felel meg, mely az alkalmazásról információkat tárol. A különböző információk a ServiceRecord attribútumain keresztül kérdezhetőek le, melyeket egy-egy hexadecimális szám azonosít. (Az attribútumok azonosítóit a ServiceRecord dokumentációja tartalmazza.) Például az alkalmazás nevének lekérdezése egy adott ServiceRecord (serviceRecord) alapján a következőképpen valósítható meg:

DataElement data = serviceRecord.getAttributeValue(0x0100);
String name = data.getValue().toString();

Az egyes szerveralkalmazások azonosítására az UUID (Universally Unique IDentifier) szolgál, mely egy 128 bites előjel nélküli egészszám. Az UUID String formátumban is megadható, azonban ebben az esetben, oda kell arra figyelni, hogy a String hossza pontosan 32 karakter legyen, és csak a hexadecimális számoknál megengedett karaktereket tartalmazza.
A DiscoveryAgent searchServices() metódusa paraméterként a következőket kapja meg:

Az alkalmazások utáni keresés befejeztével meghívódnak a DiscoveryListener servicesDiscovered() és serviceSearchCompleted() függvényei. Az előbbi paraméterként megkapja a keresés során talált alkalmazásokat reprezentáló ServiceRecord-ok tömbjét. (Az egyes rekordok csak a searchServices() metódus paraméterében beállított attribútumokat tartalmazzák.) A tömb elemei közt, az attribútumok alapján meghatározható, hogy melyik ServiceRecord tartozik a keresett Bluetooth alkalmazáshoz.
A serviceSearchCompleted() metódus, az inquiryCompletted() függvényhez hasonlóan, paraméterként megkapja a keresés végállapotát. Öt ilyen állapot lehetséges, melyek közül három, az eszközök utáni keresés végállapotaihoz hasonló. A másik kettő akkor következik be, ha a searchServices() nem talál a paraméterében meghatározott alkalmazásnak megfelelő ServiceRecord-ot, valamint, ha az eszköz, melyen az alkalmazásokat keressük, nem elérhető. Teljes példakód
Bluetooth alkalmazások utáni keresés során fellépő állapotok

További információk

Kommunikáció

A Bluetooth kapcsolat kiépítésének második része, magának a kommunikációs csatornának a létrehozása két készülék között. Az ehhez szükséges osztályok a javax.microedition.io csomag részét képezik. A csomag a különböző típusú külső kapcsolatok kezelésére szolgáló interfészeket tartalmazza, melyek mindegyike egy közös ősből, a Connection interfészből származik. A Connection mindösszesen egyetlen metódust definiál, a kapcsolat lezárására szolgáló close() függvényét. A többi műveletet a származtatott osztályok tartalmazzák.
A kapcsolatot a Connector osztály open() metódusával lehet létrehozni. Ez egy Connection objektummal tér vissza, melyet ezután típuskényszeríteni lehet a megfelelő Connection-ből származtatott osztály objektumára. Az open() paraméterként egy URL-t tartalmazó String-et vár, melynek formátuma a következő:

protokoll:cím:paraméterek

A protokoll határozza meg a kapcsolat típusát (http, ftp, stb.), ezért ezt az URL-ben mindenképpen meg kell adni, ellentétben a címmel és a paraméterrel, melyek opcionálisak. A kapcsolat megnyitása után a Connector osztály metódusainak segítségével megnyithatók a bejövő üzenetek fogadására alkalmas InputStream-ek, illetve a kimenő üzenetek küldésére alkalmas OutputStream-ek. (Az osztályok részletes leírását a javax.microedtion.io csomag dokumentációja tartalmazza.)

További információk

Bluetooth kapcsolat esetén a fenti URL a következőképpen néz ki:

btspp://hostname:UUID;paraméterek

Az UUID a fentebb tárgyaltakkal megegyezik, azaz a Bluetooth alkalmazás azonosítására szolgál. Ezek alapján a Bluetooth kapcsolat szerver oldalának létrehozása a következő módon tehető meg:

String serverURL = ’’btspp://localhost:” + uuidString + ’’;name=MyServer”;
StreamConnectionNotifier notifier = (StreamConnectionNotifier)Connector.open(URL);
StreamConnection connServer = notifier.acceptAndOpen();

A Connection interfészből származtatott StreamConnectionNotifier osztály acceptAndOpen() metódusa fogadja a klienstől beérkező kapcsolódási kérelmet. A metódus a szerver futását addig blokkolja, amíg egy kliens felől kérés nem érkezik a kapcsolat létrehozására. A kliens először elvégezi a Bluetooth eszközök, és a kiválasztott eszközön futó Bluetooth alkalmazások utáni keresését. Mivel a kapcsolat szerver oldala is egy ilyen alkalmazás, ezért a kliens megkeresheti a szerverhez tartozó ServiceRecord-ot a szervert azonosító UUID vagy név alapján. A ServiceRecord-ból megállapítható a szerver URL-je, amellyel a kliens kapcsolódhat hozzá. Ezek alapján, a kapcsolódás a következőképpen valósítható meg:

String clientURL = rec.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
StreamConnection connClient = (StreamConnection)Connector.open(URL);

A fenti kódban a rec a szerverhez tartozó ServiceRecord típusú objektum. A rec.getConnectionUrl() a szerver URL-jét tartalmazó String-et adja vissza, amely jelen példában nem más, mint a serverURL. A függvény első paraméterében megadható, hogy a Bluetooth kapcsolatot kell-e érvényesíteni, valamint hogy az használjon-e a kommunikáció során titkosítást. A legegyszerűbb eset, ha a kapcsolat egyiket sem teszi, tehát az első paraméter a ServiceRecord.NOAUTHENTICATE_NOENCRYPT. A kliens a Connector osztály open() műveletét a getConnectionURL() által visszaadott String-re meghívva kezdeményezheti a kapcsolódást a szerverhez. Amennyiben a szerver a kapcsolódást jóváhagyja, a StreamConnection típusú objektumok segítségével kommunikálhat egymással a kliens és a szerver. Teljes példakód
További információk és példakódok: