Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Unidad 2
Unidad 2
dispositivos móviles
Tema 6: Programación de
dispositivos móviles
1.Programación de dispositivos móviles
2.Limitaciones de los dispositivos móviles
3.Sistemas operativos móviles
4.Desarrollo de aplicaciones móviles
5.Java 2 Mobile Edition
6.Configuración CDC
7.Configuración CLDC
8.Paquetes opcionales en J2ME
9.MIDP: MIDlets
10.MIDP: Interfaces Gráficas de Usuario
11.MIDP: Persistencia
12.MIDP: Conexión por red
13.Persistencia II: Ficheros
14.Para terminar
Programación de
dispositivos móviles
Programación de dispositivos móviles
●
La generalización en los últimos años de teléfonos
móviles, smartphones, PDAs, etc. ha generado un
importante necesidad de aplicaciones para este tipo
de dispositivos
●
Las prestaciones de los dispositivos móviles se
incrementan día a día, posibilitando la implementación
de aplicaciones muy interesantes
●
Acceso a Internet y conectividad mediante Bluetooth
●
Envío de mensajes cortos
●
Aceleración 2D y 3D
●
Reproducción de video y sonido
●
Cámara integrada
●
Información de localización GPS
●
Sensores de orientación
Programación de
●
etc. dispositivos móviles
Programación de
dispositivos móviles
Limitaciones de los dispositivos móviles
●
La necesidad de ahorrar energía obliga a utilizar
procesadores con una capacidad de cómputo limitada
y baja frecuencia de reloj
●
El uso intensivo de cálculos, gráficos, sonido,
conexiones inalámbricas etc. limita la vida de la
bateria
●
La memoria disponible es muy limitada en
comparación con la de un ordenador ordinario
●
El almacenamiento de datos persistente también es
muy limitado: memoria interna + tarjetas SD o similar
Limitaciones de los
dispositivos móviles
Programación de
dispositivos móviles
Sistemas operativos móviles
●
Son sistemas operativos específicos para este tipo de
dispositivos, que tienen en cuenta las limitaciones que
hemos visto antes
●
Symbian es el S.O. instalado en mayor número de
dispositivos móviles en la actualidad, sobre todo
teléfonos móviles
●
Dos plataformas: S60 y UIQ
Sistemas operativos
S60 UIQ
móviles
Programación de
dispositivos móviles
●
Windows Mobile, con mayor difusión en el mercado
de PDAs
●
Palm OS, utilizado por el fabricante de PDAs Palm
Inc.
Sistemas operativos
móviles
Programación de
dispositivos móviles
●
Android, es un S.O. para móviles presentado
recientemente por Google. Utiliza un kernel Linux
●
Otros S.O. móviles: RIM Blackberry y otros S.O.
basados en kernel linux
Sistemas operativos
móviles
Programación de
dispositivos móviles
Desarrollo de aplicaciones móviles
●
Gran disparidad de plataformas de desarrollo
●
Symbian (S60 y UIQ): C++ con librerías nativas
●
Windows Mobile: .NET Compact Framework, una
versión limitada de .NET
●
PalmOS: C/C++, con librerías nativas
●
Android: Java con librerías nativas (no J2ME)
●
Java Mobile Edition (J2ME) para múltiples
plataformas, especialmente Symbian
●
Otras: Python
Sistemas operativos
móviles
Java 2 Mobile Edition
Java 2 Mobile Edition
●
La única opción real que permite un desarrollo
multiplataforma para dispositivos móviles
●
Tiene una estructura altamente modular para
adaptarse a las características de cada dispositivo
Sistemas operativos
móviles
Java 2 Mobile Edition
●
Las configuraciones (CDC y CDLC) definen el
entorno mínimo necesario para la ejecución de
aplicaciones java en un grupo amplio de dispositivos
móviles (JVM/KVM+paquetes básicos)
●
Los perfiles definen paquetes adicionales para
soportar funcionalidades básicas imprescindibles de
cada familia de dispositivos
●
Los paquetes opcionales sirven para cubrir
funcionalidades específicas: Bluetooth, soporte 3D,
etc.
Sistemas operativos
móviles
Configuración CDC
Configuración CDC
●
CDC (Connected Device Configuration). Para PDAs
de última generación o smartphones avanzados
●
Requiere una máquina virtual java compatible con
J2SE 1.4.2 y los siguientes paquetes:
●
java.lang ●
java.util
●
java.lang.ref ●
java.util.zip
●
java.lang.reflect ●
java.util.jar
●
java.math ●
java.net
●
java.text ●
java.security
●
java.io ●
java.security.cer
●
javax.microedition.io
Sistemas operativos
móviles
Configuración CDC
●
Los dispositivos que utilizan el CDC admiten tres
perfiles: Foundation Profile, Personal Basis Profile y
Personal Profile
●
El Foundation Profile proporciona soporte básico de
red y E/S
●
El Personal Basis Profile contiene todas las clases del
Foundation Profile más soporte limitado de Javabeans
y AWT
●
El Personal Profile incluye los dos perfiles anteriores
más soporte completo de AWT y Javabeans
●
Una aplicación J2SE implementada cuidadosamente
puede ser ejecutable en la configuración CDC
Sistemas operativos
móviles
Configuración CLDC
Configuración CLDC
●
CLDC (Connected Limited Device Configuration).
Para dispositivos con potencia de cálculo, memoria,
batería y acceso a red limitados
●
Incluye una máquina virtual java reducida (KVM) y los
siguientes paquetes:
●
java.lang (reducida)
●
java.lang.ref (reducida)
●
java.util (reducida)
●
java.io (reducida)
●
java.microedition.io
●
Sólo incluye las clases básicas
●
EEDDs: Vector, Hashtable y Stack
Sistemas operativos
móviles
Configuración CDLC
●
Mobile Information Device Profile (MIDP) es el perfil
más común con CLDC
●
MIDP permite la implementación de aplicaciones con
la siguiente funcionalidad:
●
Interfaz de usuario sencilla, adaptada a móviles
●
API especializado para juegos
●
Persistencia básica
●
Conexión por red
●
Sonido
●
La mayoría de los móviles actuales soportan CLDC
+MIDP. Mucho éxito por la implementación de juegos
●
La programación MIDP para configuración CLDC
requiere la instalación del Sun Java Wireless Toolkit
●
Netbeans proporciona soporte mediante el Mobility
Pack
Sistemas operativos
móviles
Paquetes opcionales
en J2ME
Paquetes opcionales en J2ME
●
Permiten extender la funcionalidad básica de los
perfiles para aprovechar todas las posibilidades del
dispositivo
●
Wireless Messaging API (WMA) JSR120, JSR205.
Envío de mensajes SMS.
●
Mobile Media API (MMAPI) JSR135. Soporte de
audio y video, tanto reproducción como captura
●
Location API JSR179. Localización geográfica del
dispositivo, mediante GPS u otros mecanismos
Sistemas operativos
móviles
Paquetes opcionales
en J2ME
●
Personal Information Management and File
Connection API JSR 75. Acceso a la lista de contactos
del teléfono móvil y al sistema de ficheros
●
Security and Trust Services API JSR 177.
Tratamiento de información privada, ejecución segura,
identificación y autentificación etc.
●
Mobile 3D Graphics JSR 184. Soporte de gráficos 3D
●
J2ME Web Services API (WSA) JSR172. Soporte de
servicios web en dispositivos móviles
●
Bluetooth API JSR 82
●
J2ME RMI JSR 66. Llamada a operaciones de
objetos remotos
Sistemas operativos
móviles
MIDP: Midlets
MIDP: MIDlets
●
Una aplicación MIDP requiere la implementación de
un MIDlet, cuya estructura recuerda los Applets y
Servlets de J2SE
import javax.microedition.midlet.MIDlet;
Sistemas operativos
móviles
MIDP: Midlets
●
De manera similar a un Applet, un MIDlet requiere la
implementación de tres operaciones de la clase
MIDlet:
●
startApp(). Es llamada automáticamente cuando la
aplicación debe comenzar su ejecución
●
pauseApp(). El dispositivo puede solicitar la parada
temporal de la aplicación en cualquier momento. La
reanudación implicará una nueva llamada a
startApp() o la terminación definitiva mediante la
llamada a destroyApp()
●
destroyApp(). Es invocada para solicitar la
liberación de los recursos del MIDlet y cualquier
tarea necesaria antes de su eliminación de memoria
Sistemas operativos
móviles
MIDP: Midlets
●
Un conjunto de MIDlets se distribuye en un fichero jar
●
El MANIFEST del fichero jar es más complicado que
los que conocemos
●
Primero se indica el nombre global del conjunto de
MIDlets del fichero jar, su versión, author y las
versiones de CLDC y MIDP necesarias
●
Después cada MIDlet se describe mediante un
nombre, el icono correspondiente y el nombre de la
clase que lo implementa
MIDlet-Name: EjemplosMIDP
MIDlet-Version: 1.0
MIDlet-Vendor: ajrueda
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.0
MIDlet-1: Ejemplo,ejemplo.png,EjemploMidlet
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
MIDP: Interfaces Gráficas de Usuario
●
MIDP proporciona una forma sencilla de construir
interfaces de usuario adaptada a las limitaciones de
pantalla, potencia de cálculo y batería de los
dispositivos móviles
●
En comparación con toolkits como Swing, la variedad
y número de componentes existentes es muy pequeño
●
La interfaz se construye a base de distintas pantallas,
en lugar de ventanas o diálogos
●
Las acciones del usuario definen la transición de una
pantalla a otra
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
●
Es importante tener en cuenta el pequeño tamaño de
la pantalla del dispositivo a la hora de diseñar la
interfaz
●
La mayoría de los dispositivos dispone de un par de
botones de acción cuyo efecto se puede programar
para cada pantalla
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
●
Para empezar hay que obtener el objeto Display que
permite manejar la pantalla del dispositivo
●
La operación estática getDisplay() de esta clase
devuelve el objeto
Display d = Display.getDisplay()
●
A continuación podemos establecer la pantalla actual
mediante:
d.setCurrent(Displayable pantalla)
●
Una vez obtenido el display, el MIDlet sigue el
siguiente esquema de funcionamiento:
1. Crear una pantalla
2. Mostrarla mediante setCurrent()
3. Esperar las acciones del usuario
4. Elegir otra pantalla en función de estas acciones (volver a 1)
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
●
Las clases que implementan la interfaz Displayable
son las siguientes:
Sistemas operativos
Canvas móviles
MIDP: Interfaces Gráficas
de Usuario
Crear y activar una pantalla TextBox es muy sencillo:
●
d.setCurrent(t);
●
Un Alert es similar a un messageBox de Swing,
admitiendo distintos tipos.
●
El tiempo de visualización del Alert es configurable
mediante setTimeout()
●
Al llamar a setCurrent() es necesario indicar el
siguiente displayable a mostrar tras el Alert
Alert a = new Alert( Error , Error al salvar la información ,
null, AlertType.ERROR);
a.setTimeout(5000);
d.setCurrent(a, siguienteDisp);
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
El displayable Form permite definir una pantalla con
●
múltiples Item (o componentes):
●
StringItem. Similar a un label de Swing
●
Spacer. Un espacio con un ancho y alto determinado. Útil para distribuir los
componentes
●
TextField. Un editor de texto con una etiqueta asociada
●
ImageItem. Una imagen con una etiqueta
●
DateField. Un editor que permite introducir una fecha/hora
●
Gauge. Sirve para representar de manera gráfica un valor entero
●
ChoiceGroup. Sirve para seleccionar valores de una lista predeterminada. Puede
ser múltiple, exclusiva o popup
●
Cualquier Item definido por el usuario
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
Los Form permiten crear interfaces mucho más ricas:
●
d.setCurrent(f);
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
●
Para asociar acciones a los botones del dispositivo se
utiliza la clase Command
●
Las activación de un comando es capturada por un
CommandListener, cuya única operación es
commandAction()
class listenerTextBox implements CommandListener {
public commandAction(Command cm, Displayable ds) {
if (cm == cFin) {
// Procesar el comando
}
}
}
d.setCurrent(t);
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
Siguiendo el ejemplo que hemos desarrollado en la asignatura, vamos a crear un
visor móvil de nuestra cuenta
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;
private Display d;
private TextField tCodigo;
private Command cEntrar, cSalir, cVolver, cMovimientos;
public MidletCuenta() {
d = null;
}
void crearComandos() {
cEntrar = new Command("Entrar", Command.OK, 0);
cSalir = new Command("Salir", Command.EXIT, 1);
cVolver = new Command("Volver", Command.BACK, 0);
cMovimientos = new Command("ver Mov.", Command.SCREEN, 0);
}
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
void crearFormPeticionCodigo() {
fPeticionCodigo = new Form("Información de cuentas");
fPeticionCodigo.append(tCodigo = new TextField("Código de cuenta ",
null, 10, TextField.NUMERIC));
fPeticionCodigo.addCommand(cEntrar);
fPeticionCodigo.addCommand(cSalir);
fPeticionCodigo.setCommandListener(new listenerPeticionCodigo());
tCodigo.setLayout(Item.LAYOUT_2 | Item.LAYOUT_CENTER);
}
crearFormInformacionCuenta();
d.setCurrent(fInfoCuenta);
} else if (cm == cSalir) {
destroyApp(true);
notifyDestroyed();
}
}
}
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
void crearFormInformacionCuenta() {
// Crear formulario de información dae la cuenta
fInfoCuenta = new Form("Información de cuenta");
fInfoCuenta.append(new StringItem("Código:",
Long.toString(c.leerNumero())));
fInfoCuenta.append(new StringItem("Titular:",
c.leerTitular()));
fInfoCuenta.append(new StringItem("Interés:",
Float.toString(c.leerInteres())));
fInfoCuenta.append(new StringItem("Saldo:",
Float.toString(c.leerSaldo())));
fInfoCuenta.addCommand(cMovimientos);
fInfoCuenta.addCommand(cVolver);
fInfoCuenta.setCommandListener(new listenerInformacionCuenta());
lMovCuenta.addCommand(cVolver);
lMovCuenta.setCommandListener(new listenerInformacionMovimientos());
}
Sistemas operativos
móviles
MIDP: Interfaces Gráficas
de Usuario
Sistemas operativos
móviles
MIDP: Persistencia
MIDP: Persistencia
●
La capacidad de almacenamiento persistente de un
dispositivo móvil puede ser muy limitada
●
El soporte de tarjetas de memoria, cada vez más
común, ha aumentado mucho las prestaciones (8Gb
en iPhone o Nokia N95) posibilitando una estructura
de ficheros similar a la de un ordernador convencional
●
Sin embargo el perfil MIDP es conservador y
proporciona un soporte sencillo de persistencia a
través de registros de bloques de bytes
Sistemas operativos
móviles
MIDP: Persistencia
●
Un MIDlet puede abrir un almacén de registros con un
nombre arbitrario mediante:
RecordStore RecordStore.openRecordStore(“nombre”, true);
●
El segundo parámetro indica que el almacén debe
abrirse si no existe
●
A través de las operaciones del objeto RecordStore
podremos manejar los registros
●
Normalmente un almacén no se comparte con otros
MIDlets, aunque puede habilitarse este acceso
●
El almacén de registros se cierra mediante:
closeRecordStore()
Sistemas operativos
móviles
MIDP: Persistencia
●
El acceso a los registros se realiza a través de un
identificador numérico, que es devuelto al añadir un
registro:
int addRecord(byte[] datos, int offset, int numBytes)
●
Para recuperar un registro debemos indicar su
identificador:
int getRecord(int id, byte[] buffer, int offset)
Modificar un registro ya existente:
●
void setRecord(int id, byte[] nuevosDatos, int offset, int numBytes)
Eliminar un registro:
●
void deleteRecord(int id)
Sistemas operativos
móviles
MIDP: Persistencia
●
Es posible recorrer los registros de un almacén
creando una enumeración:
RecordStore rs = RecordStore.openRecordStores( ejemplo , true);
re.destroy();
rs.closeRecordStore();
●
La operación enumerateRecords() admite la
especificación de clases de filtrado y ordenación de
los registros del almacén
Sistemas operativos
móviles
MIDP: Persistencia
Vamos a crear un gestor de persistencia para las cuentas corrientes mediante un
almacén de registros
import java.io.*;
import java.util.*;
import javax.microedition.rms.*;
private DAOCuentaRS() {}
Sistemas operativos
móviles
MIDP: Persistencia
try {
rs = RecordStore.openRecordStore("cuentas", true);
return c;
}
Sistemas operativos
móviles
MIDP: Persistencia
try {
rs = RecordStore.openRecordStore("cuentas", true);
dos = new DataOutputStream(bos = new ByteArrayOutputStream());
dos.writeLong(c.leerNumero()); dos.writeUTF(c.leerTitular());
dos.writeFloat(c.leerInteres()); dos.writeFloat(c.leerSaldo());
Movimiento m;
int nMov = c.numMovimientosHistorico();
dos.writeInt(nMov);
for (int nm = 0; nm < nMov; nm++) {
m = c.leerMovimientoHistorico(nm);
dos.writeLong(m.fecha.getTime()); dos.writeChar(m.tipo);
dos.writeFloat(m.importe); dos.writeFloat(m.saldo);
}
try {
re = rs.enumerateRecords(null, null, false);
while (re.hasNextElement()) {
id = re.nextRecordId();
dis = new DataInputStream(new ByteArrayInputStream(rs.getRecord(id)));
recNum = dis.readLong();
if (recNum == numero) {
return id;
}
dis.close();
dis = null;
}
} finally {
if (dis != null) dis.close();
if (re != null) re.destroy();
}
return -1;
}
}
Sistemas operativos
móviles
MIDP: Persistencia
En el MIDlet debemos crear un atributo para referenciar el gestor de persistencia,
y realizar su inicialización en startApp()
public void startApp() {
if (d == null) {
d = Display.getDisplay(this);
}
if (dc == null) {
try {
dc = DAOCuentaRS.obtenerInstancia();
}
catch(Exception e) {
d.setCurrent(new Alert("Error",
"No es posible abrir el almacén de registros",
null, AlertType.ERROR));
destroyApp(true);
notifyDestroyed();
return;
}
}
crearComandos();
crearFormPeticionCodigo();
d.setCurrent(fPeticionCodigo);
}
Sistemas operativos
móviles
MIDP: Persistencia
crearFormInformacionCuenta();
d.setCurrent(fInfoCuenta);
} else if (cm == cSalir) {
destroyApp(true);
notifyDestroyed();
}
}
}
Sistemas operativos
móviles
MIDP: Conexión por red
MIDP: Conexión por red
●
MIDP es especialmente potente en lo que se refiere a
la conexión por red mediante sockets, http y otros
protocolos
●
La clase Connection representa una conexión
genérica y es extendida a tres conexiones que
admiten E/S mediante streams: InputConnection,
OutputConnection y StreamConnection
●
La clase StreamConnection es extendida a varias
clases que representan distintos tipos de conexiones:
CommConnection, HttpConnection, httpsConnection,
SocketConnection, etc.
Sistemas operativos
móviles
MIDP: Conexión por red
●
La clase Connector es una factoría que a partir de un
url devuelve la clase de conexión correspondiente:
Connection Connector.open(String url)
HttpConnection con1;
con1 = (HttpConnection) Connector.open( http://www.google.es/search?hl=es&q=j2me );
SocketConnection con2;
con2 = (SocketConnection) Connector.open( socket://miservidor:79 );
●
La conexión debe cerrarse al final con close()
●
A partir de la conexión podemos obtener un stream
de lectura o escritura
HttpConnection con1;
con1 = (HttpConnection) Connector.open( http://www.google.es/search?hl=es&q=j2me );
InputStream is = con1.openInputStream();
// Utilizar el stream
con1.close();
Sistemas operativos
móviles
MIDP: Conexión por red
El siguiente gestor de persistencia obtiene los datos de la cuenta desde un
servidor web
import java.io.*;
import java.util.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;
private DAOCuentaNC() {
}
try {
ic = (InputConnection) Connector.open(urlCuenta(numero));
dis = ic.openDataInputStream();
c = new Cuenta(dis.readLong(), dis.readUTF(), dis.readFloat());
c.saldo = dis.readFloat();
return c;
}
Persistencia II: Ficheros
●
El File Connection and PIM API (JSR 75) define un
nuevo tipo de conexión denominado FileConnection
que permite trabajar con ficheros de manera similar a
un ordenador convencional
●
Este API no está disponible en todos los dispositivos
●
El acceso al sistema de ficheros requiere permisos
especiales si la aplicación no está certificada, para
evitar daños en el mismo
Sistemas operativos
móviles
Persistencia II: Ficheros
El siguiente ejemplo lee una imagen guardada en el dispositivo
FileConnection fc;
InputStream is;
is.close();
●
La clase FileConnection permite abrir un stream de
E/S al fichero pero también contiene operaciones para
la creación, renombrado y borrado de ficheros y
directorios
Sistemas operativos
móviles
Persistencia II: Ficheros
●
No obstante existe un problema importante: la
estructura del sistema de ficheros de cada dispositivo
no es estándar
●
Cada dispositivo contiene una raíz para cada uno de
los medios de almacenamiento: memoria interna
(/root, /internal, /InternalMemory) y tarjetas de
memoria (/SDCard1, /MemoryCard)
●
Es posible enumerar las distintas raices existentes
mediante el registro del sistema de ficheros:
Enumeration raicesSF = FileSystemRegistry.listRoots();
while (raicesSF.hasMoreElements()) {
raizSF = (String) raicesSF.nextElement();
// Hacer algo con la raiz encontrada
}
Sistemas operativos
móviles
Persistencia II: Ficheros
Este gestor de persistencia utiliza el API JSR 75
import java.io.*;
import java.util.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;
private DAOCuentaFC() {
obtenerRaizSistemaFicheros();
}
Sistemas operativos
móviles
Persistencia II: Ficheros
try {
fc = (FileConnection) Connector.open(urlCuenta(numero), Connector.READ);
if (!fc.exists()) {
return null;
}
dis = fc.openDataInputStream();
c = new Cuenta(dis.readLong(), dis.readUTF(), dis.readFloat());
c.saldo = dis.readFloat();
Sistemas operativos
móviles
Persistencia II: Ficheros
return c;
}
try {
fc = (FileConnection) Connector.open("file:///" + raizSF +
"cuentas", Connector.READ_WRITE);
if (!fc.exists()) {
fc.mkdir();
}
fc.close();
fc = (FileConnection) Connector.open(urlCuenta(c.leerNumero()),
Connector.READ_WRITE);
if (!fc.exists()) {
fc.create();
}
Sistemas operativos
móviles
Persistencia II: Ficheros
dos = fc.openDataOutputStream();
dos.writeLong(c.leerNumero());
dos.writeUTF(c.leerTitular());
dos.writeFloat(c.leerInteres());
dos.writeFloat(c.leerSaldo());
Movimiento m;
int nMov = c.numMovimientosHistorico();
dos.writeInt(nMov);
for (int nm = 0; nm < nMov; nm++) {
m = c.leerMovimientoHistorico(nm);
dos.writeLong(m.fecha.getTime());
dos.writeChar(m.tipo);
dos.writeFloat(m.importe);
dos.writeFloat(m.saldo);
}
} finally {
if (fc != null) fc.close();
}
}
●
Otro problema adicional son las restricciones de
seguridad existentes en algunos dispositivos, que sólo
permiten el acceso a determinados directorios
públicos (/Imagenes, /Sonidos, etc.)
Sistemas operativos
móviles
Para terminar
Para terminar
●
Hemos estudiado MIDP a nivel básico
●
En función de las necesidades de la aplicación móvil
a implementar será necesario estudiar con mayor
profundidad algunos de los APIs que hemos visto y
otros nuevos
●
PIM API JSR 75
●
API MIDP para juegos
●
Mobile Media API JSR JSR 184
●
Wireless Messaging API JSR 135
●
Bluetooth API JSR 82
Sistemas operativos
móviles