Programación en red en MIDP2.0
El soporte que da MIDP2.0 a la programación en red se basa, como en MIDP1.0, en el Generic Connection Framework de CLDC. CLDC Generic Connection Framework
define una serie de interfaces para dar soporte a la variedad de tipos
de conexiones que nos podemos encontrar en dispositivos móviles, pero
no implementa ninguna de ellas. Es en los perfiles donde se debe
realizar esta implementación. En MIDP1.0, se daba soporte únicamente a
conexiones HTTP, a través de la implementación del interfaz HttpConnection.Sin
embargo, MIDP2.0 ofrece nuevas interfaces de conexión de red, lo que
supone un conjunto de abstracciones más completo que es de gran
utilidad para el programador.
Este cambio sustancial de MIDP2.0 respecto a MIDP1.0 surge como
respuesta a la constante evolución que experimentan tanto los
terminales móviles (tecnologías GPRS y UMTS) como las aplicaciones que
se diseñan para dichos terminales. Se imponen nuevos requisitos a los
mecanismos de conexión que se traducen en la necesidad de un nuevo
conjunto de abstracciones que pueda ser utilizado a nivel de
programador.
- Los dispositivos que trabajan en conmutación de circuitos
necesitan conexiones basadas en flujo de bits, como por ejemplo el
protocolo TCP.
- Los dispositivos que trabajan en conmutación de paquetes necesitan
conexiones basadas en datagramas así que requerirán conexiones como las
que ofrece el protocolo UDP.
- Habrá dispositivos con mecanismos específicos de conexión.
Como consecuencia MIDP2.0 responde al reto planteado ofreciendo
multitud de formas de conexión manejables a nivel del programador y que
no introducen un mayor grado de complejidad ya que todas ellas están
englobadas dentro del mismo conjunto de abstracciones mencionado
anteriormente. |
|
En el CLDC Generic Connection Framework, todas las conexiones se crean utilizando el método estático open de la clase Connector. Si no se produce ningún error, este método devuelve un objeto que implementa una de las interfaces definidas en el CLDC Generic Connection Framework e implementadas por MIDP2.0:
Figura 1: Jeraquía de Intefaces del CLDC Generic Connection Framework
|
La interfaz Connection es el nodo raíz en este arbol de jerarquía por
lo que el resto de interfaces serán subinterfaces de Connection. En la
figura, los interfaces en un recuadro amarillo son parte de CLDC 1.0.
El interfaz HttpConnection fue añadido por MIDP 1.0. Los interfaces
dentro de los recuadros azules son interfaces añadidos por MIDP 2.0.
Todas estas interfaces estan contenidas en el paquete javax.microedition.io
Como vemos hay un número considerable de interfaces y cada una de
ellas nos permite establecer un tipo de conexión específico y con un
protocolo determinado. Sin embargo J2ME nos permite trabajar con estas
interfaces de la manera más sencilla posible. Para ello utilizaremos la
clase Connector. |
|
Esta clase nos ofrece un conjunto de métodos que permiten abrir
los distintos tipos de conexiones que definen los interfaces de los
que hablamos anteriormente.
- open(String name): crea y abre una conexión con la URL especificada.
- open(String name,int mode): crea y abre una conexión con la URL especificada con un determinado modo de acceso.
- open(String name,int mode,boolean timeouts):
crea y abre una conexión con la URL especificada con un determinado
modo de acceso y especificando si el usuario desea que se produzcan
excepciones de timeout.
- openDataInputStream(String name)/ openDataOutputStream(String name): crea y abre una conexión para un flujo de datos de entrada / salida.
- openInputStream(String name)/ openOutputStream(String name): crea y abre una conexión para un flujo de datos de entrada / salida.
El parámtero String name que aparece en la definición de los métodos tiene el formato "protocol:address;parameters".
Algunos ejemplos de utilización de estos métodos:
- Conexión HTTP:
Connector.open("http://www.it.uc3m.es/pervasive");
- Conexión por datagramas:
Connector.open("datagram://address:port#");
- Conexión por Sockets:
Connector.open("socket://address:port#");
- Conmunicación con puerto serie:
Connector.open("comm:0;baudrate=9600");
- Acceso a ficheros:
Connector.open("file:/miFichero.txt");
El objetivo de tener esta sintaxis, es abstraer al programador de las
diferencias que existen entre los diferentes protocolos, de manera que
la mayoría del código de una aplicación no se modifica cuando se cambia
el protocolo que se está usando.
IMPORTANTE: Los ejemplos de conexiones anteriores son sólo
ilustrativos. CLDC en sí mismo no proporciona ninguna implementación de
ningún protocolo, éstas deben de proporcionarse a nivel de perfil.
Además un determinado perfil no tiene porque implementar todos los
protocolos. Así por ejemplo MIDP 1.0 sólo proporcionaba una
implementación del protocolo HTTP, pero no implementaba ni sockets, ni
datagramas (aunque algunos fabricantes pudieran incorporar esta
posibilidad).
MIDP 2.0 en cambio añade la implementación de protocolos para
establecer conexiones HTTP seguras, por Datagramas y mediante Sockets.
A continuación vemos los distintos interfaces que implementa MIDP 2.0. |
|
HTTP puede implementarse utilizando protocolos
IP (como TCP/IP) o protocolos no-IP (como WAP o i-mode), por este
motivo se seleccionó como uno de los protocolos para comunicaciones de
red en MIDP (en MIDP 1.0 era el único implementado). Todas las
implementaciones de MIDP (tanto 1.0 como 2.0) deben soportarlo,
garantizando de esta manera la portabilidad de las aplicaciones, que
utilizan este protocolo, entre diferentes dispositivos.
Se define un nuevo interfaz dentro de la jerarquía del CLDC Generic Connection Framework, el interfaz HttpConnection para el soporte a conexiones HTTP. Este interfaz extiende del interfaz ContentConnection.
El protocolo HTTP es un protocolo a nivel de aplicación del tipo
petición/respuesta, en el que los parámetros de una petición deben
establecerse antes de que se envíe la petición. La conexión puede estar
en uno de los siguientes tres posibles estados:
- "Setup": No se ha establecido todavía la conexión.
- "Connected": Se ha establecido la conexión, la petición se ha enviado y se está esperando por una respuesta.
- "Closed": La conexión se ha cerrado.
En el interfaz HttpConnection se proporcionan una serie de métodos que pueden invocarse en cada uno de los estados anteriores:
En el estado "setup" se pueden invocar los siguientes métodos:
- setRequestMethod(String method) que establece el método de la petición, que puede ser POST, GET o HEAD. El método por defecto es GET y si el método no es HTTP o la implementación de HTTP está recortada y no lo soporta, se produce una IOException.
- setRequestProperty(String key, String value)
que permite indicar el valor de algunas propiedades HTTP antes de
enviar la petición, la propiedad que se quiere establecer se indica en
el parámetro key y su valor se establece en el parámetro value.
Por ejemplo, en el código siguiente se crea una conexión HTTP a la URL http://www.it.uc3m.es/pervasive y se indica que el método de la petición es POST, y que la propiedad HTTP User-Agent tiene el valor Profile/MIDP-2.0 Configuration/CLDC-1.0:
HttpConnection c = (HttpConnection)Connector.open("http://www.it.uc3m.es/pervasive");
c.setRequestMethod(HttpConnection.POST);
c.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.0");
La transición entre el estado "setup" y el estado "connected" se
produce cuando se invoca algún método que precisa enviar o recibir datos
al servidor con el que se establece la conexión. Algunos de los
métodos que proporciona la implementación del interfaz HttpConnection y que provocan esta transición, son:
Cuando la conexión está abierta (se ha pasado al estado de "connected"), se pueden invocar los siguientes métodos:
A continuación se muestra un ejemplo de código en el que se utiliza la implementación de HttpConnection para leer el contenido de la página http://www.it.uc3m.es/celeste/docencia/cr/hola.txt y mostrarselo al usuario (MIDletHTTPExample.java):
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
/**
* Un ejemplo de MIDlet para visualizar el contenido de una URL
* utilizando la implementación del interfaz HttpConnection.
*/
public class MIDletHTTPExample extends MIDlet {
private Display display;
private String url = "http://www.it.uc3m.es/celeste/docencia/cr/hola.txt";
public MIDletHTTPExample() {
display = Display.getDisplay(this);
}
/**
* Método startApp()
*/
public void startApp() {
// Llama al método download para descargar el contenido de la URL
try {
download(url);
} catch(IOException e) {
System.out.println("IOException: " + e);
}
}
private void download (String url) throws IOException {
StringBuffer b = new StringBuffer();
InputStream is = null;
HttpConnection c = null;
TextBox t = null;
try {
long len = 0 ;
int ch = 0;
// Abre una conexión del tipo HttpConnection
c = (HttpConnection)Connector.open(url);
// Obtiene un stream de entrada, para leer el contenido de la url
// con la que establece la conexión
is = c.openInputStream();
// Lee hasta que se cierra la conexión
while ((ch = is.read()) != -1) {
b.append((char)ch);
}
// Se contruye un TextBox con el contenido de la URL
t = new TextBox("Hola...", b.toString(), 1024, 0);
} finally {
// Se cierra tanto el stream de entrada
if (is != null)
is.close();
// Se cierra la conexión
if (c != null)
c.close();
}
// Se visualiza el TextBox en el Display
display.setCurrent(t);
}
/**
* pauseApp
*/
public void pauseApp() {
}
/**
* destroyApp
*/
public void destroyApp(boolean unconditional) {
}
}
|
|
HTTPS es la versión segura del protocolo HTTP y consiste básicamente en establecer conexiones HTTP sobre SSL (Secure Sockets Layer). Para poder establecer este tipo de conexiones MIDP 2.0 implementa el interfaz HttpsConnection, que es un subinterfaz de HttpConnection. Por tanto, el interfaz HttpsConnection implementa, además de los métodos y constantes que hereda de HttpConnection, nuevos métodos y constantes que permiten establecer conexiones de red seguras.
La manera de trabajar con este interfaz es idéntica a la que vimos en el
apartado anterior para conexiones HTTP convencionales. La única
diferencia es que en este caso utilizaremos un objeto HttpsConnection.
Los métodos adicionales que aporta el interfaz HttpsConnection son los siguientes:
- getPort(): devuelve el puerto utilizado por una HttpsConnection.
- getSecurityInfo(): devuelve la información de seguridad (objeto javax.microedition.io.SecurityInfo )asociada a una conexión establecida correctamente.
Si la conexión se encuentra en el estado setup será
inicializada para establecer una conexión segura con el servidor. El
método devolverá el resultado cuando la conexión haya sido establecida y
se haya validado el certificado dado por el servidor.
Otra novedad que introducen las conexiones HTTP seguras son las excepciones CertificateException. Son un subtipo de la IOException
y ocurren en la transición al estado "connected". Están relacionadas
específicamente con errores ocurridos en el establecimiento de
conexiones seguras.
Ejemplo de utilización del interfaz HttpsConnection: EjemploHttpSeguro.java
Cabe en este punto introducir un nuevo interfaz especificado por MIDP 2.0 : SecurityInfo. Este interfaz, que veremos a continuación, permite acceder a información relativa a conexiones seguras. |
|
El interfaz SecurityInfo
implementa, como ya se ha dicho, una serie de métodos que permiten
acceder a la información asociada a conexiones seguras. Cualquiera de
los protocolos que MIDP 2.0 implementa para establecer estas conexiones
seguras (Https o sockets seguros sobre ssl) pueden utilizar estos
métodos para conocer los parámetros de seguridad de estas conexiones.
El API del interfaz SecurityInfo se muestra a continuación:
Ejemplo:
// obtener el objeto SecurityInfo asociado a una conexion segura
SecurityInfo secInfo = conexionSegura.getSecurityInfo();
// Extraer informacion de seguridad
String cipherSuite = secInfo.getCipherSuite();
String protocol = secInfo.getProtocolName();
String version = secInfo.getProtocolVersion();
Certificate certificado = secInfo.getServerCertificate();
|
|
El interfaz CommConection
define una conexión lógica con un puerto serie. El puerto en cuestión
no tiene por qué corresponder a un puerto serie físico sino que puede
ser un puerto lógico definido por el sistema operativo. Como
corresponde a este tipo de conexiones la información se transmitirá
como un flujo de bits en serie.
Como ya se dijo anteriormente todos los tipos de conexión existentes se abren utilizando el método open(String URL) de la clase Connector. En este caso el String que debemos pasar como parámetro debe tener el siguiente formato:
comm:< identificador del puerto >[< parámetros opcionales >]
Los parámetros opcionales son los que definen como será la
conexión. Habrá definidos unos valores por defecto que serán aplicados
en caso de que no se especifiquen a la hora de establecer la conexión.
Los parámetros son los siguientes:
Parametro | Valor por
defecto | Descripción |
baudrate | depende de
la plataforma | Define la velocidad de transferencia de bits. |
bitsperchar | 8 | Numero de bits por caracter (7 ó 8 ). |
stopbits | 1 | Numero de bits de parada por caracter (1 ó 2 ) |
parity | ninguna | Control de errores por paridad. Puede ser par(even) , impar(odd) , o ninguna(none) |
blocking | on | Se espera (on ) o no (off ) a tener el fuffer de entrada lleno para leer |
autocts | on | Se espera (on ) o no (off ) a que la línea CTS esté activada antes de escribir |
autorts | on | Con on actviva la línea RTS cuando el buffer de entrada no está lleno.
Con off la línea RTS está siempre activada. |
Tanto para establecer la conexión como para especificar los parámetros opcionales que se deseen utilizaremos el método open() de la clase Connector. Para ello el String que pasaremos como argumento debe tener el formato adecuado o de lo contrario se producirá una IllegalArgumentException.
Para trabajar con conexiones por puerto serie se implementan, además de los métodos heredados de las interfaces Connection, InputConnection y OutputConnection, dos métodos adicionales:
- getBaudRate(): devuelve la tasa de transferencia de la conexión.
- setBaudRate(int baud_rate): permite fijar la tasa de transferencia de la conexión. Si el valor especificado no es válido el sistema fijará un valor.
|
|
Este interfaz define la abstracción de sockets
lo que nos permitirá comunicar distintos procesos entre sí incluso
cuando estos se estén ejecutando en distintos dispositivos. Para poder
crear un socket necesitaremos un String de conexión genérico que
especifique explicitamente un host y un puerto con los que establecer
el socket mediante la expresión ya conocida Connector.open(...).
Ejemplo:
SocketConnection socket = (SocketConnection)Connector.open("socket://< host >:< port >");
El interfaz SocketConnection implementa StreamConnection que a su vez proporciona un objeto Connection a la vez que objetos de I/O (un InputStream y un OutputStream) que permiten trabajar con la conexión socket.
Cada uno de estos interfaces tiene su propio método close().
Así pues, en sistemas que soporten comunicación duplex, debe ser
posible cerrar uno de los sentidos de la comunicación si afectar al
otro.
La implementación del interfaz SocketConnection define los siguientes métodos:
En este enlace puede ver un ejemplo (EjemploClient.java)
de un cliente que conecta con un terminal remoto a través de sockets.
En dicho terminal remoto (que se supone está ejecutando en el mismo
ordenador) estará ejecutando un socket servidor. Este MIDlet podrá ser
descargado en el siguiente apartado. |
|
Este interfaz define una conexión mediante
sockets seguros que consiste en una conexión basada en SSL (Secure
Socket Layer). Esta conexión segura se establece utilizando Connector.open(..)
con un String de conexión genérico que especifique, además de un host y
un puerto destino, que dicha conexión debe apoyarse en el protocolo
SSL.
Ejemplo:
SecureConnection secureSocket =
(SecureConnection)Connector.open("ssl://< host >:< port >");
Si tras llamar al método open no se pudo establecer la conexión debido a algún error relacionado con los certificados de seguridad se lanzará una CertificateException
Como subinterfaz de SocketConnection, el interfaz SecureConnection implementará todos los métodos que se expusieron en el apartado anterior. Además de estos implementa el siguiente método:
- getSecurityInfo(): devuelve un objeto SecurityInfo con la información relativa a la seguridad asociada a una conexión segura.
|
|
El interfaz ServerSocketConnection
define un socket servidor o pasivo. La finalidad de este tipo especial
de sockets es el poder conectar dos sockets establecidos en distintas
máquinas de manera que éstas puedan comunicarse entre sí. De no
disponer de un socket servidor ambos terminales deberían establecer un
socket genérico de forma simultánea, produciéndose un error en caso
contrario. Gracias a ServerSocketConnection
dispondremos de un servidor que facilita esta labor. El servidor
permanecerá escuchando las peticiones de conexión de los clientes (se
tratará simplemente del establecimiento de sockets genéricos). Cuando
reciba estas peticiones devolverá una instancia de un SocketConnection y la comunicación entre ambos terminales estará establecida.
La forma en que el objeto ServerSocketConnection lleva a cabo lo anteriormente explicado es muy sencillo: utiliza el método acceptAndOpen() heredado de la clase javax.microedition.io.StreamConnectionNotifier.
Ejemplo:
SocketConnection socket = (SocketConnection)serverSocket.acceptAndOpen();
En el ejemplo anterior el servidor permanecerá a la espera hasta recibir una petición de conexión SocketConnection
dirigida a la máquina y puerto en los que esté escuchando. Una vez
recibida la petición el método terminará su ejecución devolviendo la
instancia que representa la conexión mediante sockets.
El único dato que nos queda por conocer para poder implementar lo hasta ahora visto es cómo crear una instancia de ServerSocketConnection. Para ello utilizaremos, igual que en todos los tipos de conexión vistos hasta ahora, el metodo open() de la clase Connector. La única diferencia respecto a lo visto hasta ahora es que al crear una conexión ServerSocketConnection no se debe especificar el host con el que establecerla ya que será siempre la máquina local:
ServerSocketConnection serverSocket = (ServerSocketConnection)Connector.open("socket://:< port number >");
Al igual que en los demas tipos de conexiones vistos hasta ahora,
podemos omitir el puerto para conseguir una asignación dinámica de un
puerto disponible (el sistema gestionará dicha asignación): ServerSocketConnection serverSocket = (ServerSocketConnection)Connector.open("socket://");
En este último caso, para conocer el puerto sobre el que se ha establecido la conexión, debemos ejecutar el método getLocalPort() que veremos más adelante.
Los métodos disponibles en el interfaz ServerSocketConnection son:
- getLocalAddress(): devuelve la dirección local en la que se ha establecido el socket.
Esta es la dirección IP a la que otros terminales deben solicitar el
establecimiento de un socket tal y como se explicó anteriormente. Dado
que las direcciones IP pueden ser asignadas dinámicamente habrá que
prestar atención en este aspecto e implementar aplicaciones robustas
frente a cambios de la dirección IP del socket servidor.
ATENCIÓN: Para acceder a la dirección IP de la máquina local se puede utilizar System.getProperty("microedition.hostname").
- getLocalPort(): devuelve el número de puerto local en el que se ha establecido el socket.
EjemploServer.java,
MIDlet ejemplo en el que se establece un socket servidor esperando
peticiones de establecimiento de sockets por parte de los clientes
(MIDlet que puede ser descargado en el apartado anterior). |
|
El interfaz UDPDatagramConnection
define una conexión por datagramas de la que se conoce la dirección
del punto de terminación ("end point") local. Las características de
este tipo de conexión no varían por tratarse de terminales móviles. Al
trabajar con el protocolo UDP nos enfrentamos a dos limitaciones
inherentes a éste: no se garantiza la entrega y no existe protección
frente a duplicados. En comunicaciones sencillas, sin fuertes
requisitos de pérdidas o duplicados, las conexiones por datagramas UDP
representan un modo eficiente de establecer la comunicación. Sin
embargo, en aplicaciones no resistentes frente a pérdidas o duplicados,
será necesario trabajar con sockets TCP(utilizando el interfaz ServerSocketConnection
que acabamos de ver), penalizando en la cantidad de recursos
consumidos (las cabeceras TCP tienen un gran tamaño por lo que el ancho
de banda utilizado es mucho menor). Habrá que tener en cuenta entonces
cuales son los requisitos de nuestra aplicación para decidirnos por un
protocolo u otro estableciendo un compromiso entre fiabilidad y
consumo de recursos (en dispositivos limitados como los terminales
móviles nos enfrentaremos a nuevas limitaciones).
Para obtener una instancia de UDPDatagramConnection recurriremos, como ya es habitual, al método open() de la clase Connector.
El formato en el que se debe especificar la dirección para establecer
la conexión UDP es el mismo que el utilizado para especificar la
dirección destino de un datagrama (utilizando Datagram.setAddress()): Ejemplo:
UDPDatagramConnection UDPDat = (UDPDatagramConnection)Connector.open("datagram://< host >:< port >");
Los métodos disponibles en el interfaz UDPDatagramConnection son:
- getLocalAddress(): devuelve la dirección local en la que se ha establecido la conexión por datagramas.
- getLocalPort(): devuelve el puerto local sobre el que se ha establecido la conexión por datagramas.
|
|
Esta clase constituye una novedad de MIDP 2.0 respecto a la versión 1.0 y se encuentra también en el paquete
javax.microedition.io.
El push registry permite que los MIDlets puedan ser lanzados
automáticamente sin necesidad de ser inicializados por el usuario. El
concepto de push registry no modifica el ciclo de vida del MIDlet,
simplemente introduce dos nuevas vías por las que un MIDlet puede ser
activado:
- Activación causada por conexiones de red entrantes (gracias a
que MIDP 2.0 implementa nuevos interfaces de conexión como TCP,
datagramas UDP e incluso SMS).
- Activación causada por temporizadores.
Será el push registry el que gestione la activación de estos
MIDlets almacenando las conexiones o alarmas temporales que
"despertarán" a un determinado MIDlet.
Figura 2: Modelo de ciclo de vida de un MIDlet |
El push registry es parte del sistema gestor de aplicaciones
(Application Management System o AMS), que es el software residente en
el dispositivo móvil que es responsable del ciclo de vida de cada
aplicación (instalación, activación, ejecución y eliminación). Sin
embargo, a nivel de programación, es decir, en el propio código del
MIDlet, también podremos llevar a cabo actuaciones sobre el push
registry. Para ello utilizaremos el API de la clase PushRegistry.
Figura 3: Elementos típicos del Push Registry |
CONEXIONES ESTÁTICAS Y DINÁMICAS.
Para habilitar la activación "push" los MIDlets deben utilizar el push
registry como ya vimos anteriormente. Se pueden llevar a cabo dos tipos
de registros:
- Registros estáticos - Registrar
conexiones estáticas, es decir, las que sabemos con toda seguridad que
se producirán y que son imprescindibles para el buen funcionamiento del
MIDlet.
- Registros dinámicos - Registrar conexiones dinámicas (las que
pueden establecerse, o no, a lo largo de la ejecución del MIDlet) y
alarmas. Ésta es la única manera de registrar los temporizadores
asociados a un MIDlet.
Cada uno de estas dos maneras de registrar "eventos activadores" del MIDlet son tratadas con más detalle a continuación.
REGISTRO DE CONEXIONES ESTÁTICAS.
El registro de conexiones estáticas ocurre durante la instalación del
MIDlet suite. Para ello se deben especificar todas las conexiones a
registrar mediantes los atributos
MIDlet-Push en el fichero JAD o en el Manifiesto. Cada entrada tendrá el siguiente formato:
MIDlet-Push-< n >: < ConnectionURL >, < MIDletClassName >, < AllowedSender >
Ejemplo:
MIDlet-Push-1: socket://:79, com.sun.example.SampleChat, *
MIDlet-Push-2: datagram://:50000, com.sun.example.SampleChat, *
Éstas son dos entradas del fichero descriptor que reservarían una
conexión socket en el puerto 79 y una conexión por datagramas en el
puerto 5000. Si todas las entradas que incluyamos en
el descriptor no pueden ser satisfechas (errores de sintaxis en la
declaración, reserva de un puerto o una conexión ya ocupados,
declaración de un protocolo no registrable ...) se informará al usuario
y se le recomendará no instalar el MIDlet suite. Sin embargo si, aún
sin poder llevar a cabo todos los registros en el push registry la
aplicación puede funcionar de manera aceptable deberá registrar
dinámicamente (utilizando el API de la clase PushRegistry) las
conexiones que no pudieron ser registradas estáticamente con sus
entradas correspondientes en el fichero descriptor.
Por último, hay que tener en cuenta que la instalación del MIDlet suite
con declaraciones como las anteriores en el fichero descriptor reserva
las conexiones solicitadas para uso exclusivo de los MIDlets dentro de
dicho suite. Mientras que éste esté instalado, cualquier intento por
parte de otras aplicaciones de abrir una de las conexiones reservadas
será rechazado produciendo uno
IOException.
Si dos MIDlet suites tienen una conexión "push" estática en común no
podrán ser instalados simultáneamente y si así sucediera su
funcionamiento no sería correcto.
REGISTRO DE CONEXIONES DINÁMICAS.EL API DE LA CLASE PushRegistry
Para el registro de conexiones "push" dinámicas utilizaremos los métodos de la clase
javax.microedition.io.PushRegistry. Son los siguientes:
getFilter(String connection):
recupera el filtro asociado a la conexión que se pasa como parámetro.
Devuelve un String indicando que conexiones entrantes pueden activar la
ejecución del MIDlet o null si esta conexión no fue registrada en el
push registry por el correspondiente MIDlet suite.
getMIDlet(String connection):
recupera el MIDlet al que está asociada la conexión especificada,
devolviendo un String con el nombre de clase del MIDlet o null si no
hay ningún MIDlet asociado.
registerAlarm(String midlet,long time): registra un temporizador para que el MIDlet se ejecute automáticamente.
NOTA: El PushRegistry acepta sólo un temporizador por MIDlet. La
aplicación debe tener un "TimerTask" para notificar a la aplicación
los eventos del temporizador en tiempo. Si intentamos registrar un
temporizador que ya está registrado el método devolverá el valor
anterior de dicho temporizador, es decir, el instante para el que
estaba programada la ejecución del MIDlet.
Si es la primera vez que se hace el registro devolverá cero.
listConnections(boolean available):
devuelve una lista (String[]) con los nombres de las conexiones
registradas por el MIDlet suite instalado. Los Strings devueltos tendrán
el formato de una conexión genérica: protocolo, host y puerto .
registerConnection(String connection, String midlet, String filter):
registra una conexión dinámica que una vez registrada funcionará igual
que una conexión pre-alojada por el fichero descriptor. Los atributos
son los mismos que en el Push Registration Atribute que se utiliza para registrar conexiones estáticas.
unregisterConnection(String connection): elimina del registro la una conexión dinámica, devolviendo el resultado de la operación.
NOTA IMPORTANTE: Cuando se implemente un MIDlet que al terminar
su ejecución registre una alarma para ser activado tras un cierto
tiempo, dicho registro debe ser gestionado por un nuevo hilo de
ejecución para evitar "dead lock". El motivo es que existe el riesgo de
que la ejecución del MIDlet llegue a su fin sin que se haya podido
llevar a cabo el proceso de registrar la alarma de activación.
Ejemplo de MIDlet que registra una alarma para su activación pasado un tiempo determinado: EjemploPush.java
|