Tutorial: conexión a red en dispositivos móviles
Versión: 1.0, Septiembre, 2006

Autor: Manuel Gómez Olmedo
Web: http://decsai.ugr.es/~mgomez, Mail: mgomez@decsai.ugr.es
Decsai

(C) Dpto. de CCIA
Web: http://decsai.ugr.es

Introducción

En este tutorial se explica la forma de conectar un dispositivo móvil con la red. La exposición se basará en la realización de una serie de ejercicios que irán introduciendo los conceptos necesarios. Se incluyen algunos comentarios sobre operaciones de entrada/salida que son necesarias para poder intercambiar datos mediante las conexiones pertinentes.

Índice

  1. Entrada/salida e interconexión
  2. MIDlet para mostrar datos meteorológicos
  3. Ejercicio: MIDlet con información de rutas
  4. Conexión con Servlets

1. Entrada/salida e interconexión

Para quien conozca Java estándar, hay poca diferencia entre la forma de programar la conexión a red en Java para dispositivos móviles. Para apreciar esta semejanza, el primer ejemplo consistirá en el desarrollo completo de un MIDlet que obtendrá datos a partir de una conexión de red y los mostrará por pantalla.

1.1. Clases MIDP para conexión a red

La aproximación a conexión a redes parte de la definición de un marco genérico de conexión (GCF: generic connection framework). El propósito de este marco genérico es ofrecer un nivel de abstracción para los servicios de red, lo que permite que diferentes dispositivos habiliten únicamente los protocolos de red precisos para sus necesidades.

En verdad, el dispositivo no es quien para decidir las características de conectividad que soportará. Esto es responsabilidad de los diferentes perfiles. El marco GCF define una clase genérica, Connector, que está incluida en el paquete javax.microedition.io. Esta clase, junto con un conjunto de interfaces que definen los tipos de conexiones sirven como plataforma de tratamiento de la conexión de los MIDlets con la red. Se exponen algunas de las características relevantes de las clases a usar para ofrecer la conexión a red:

En realidad se trata de un conjunto de interfaces generales que no están próximas a ningún protocolo real de comunicaciones. Ofrecen, por tanto, una arquitectura básica capaz de soportar un amplio rango de características de conexión. Esto tiene la ventaja de conseguir que las aplicaciones de conexión a red tengan una estructura similar independientemente del protocolo de red usado.

Para implementar esta arquitectura general, los perfiles agregarán las clases necesarias para complementar esta plataforma básica. Por ejemplo, el API de MIDP agrega la interfaz HttpConnection, que agrega la posibilidad de establecer conexiones HTTP (conexiones a páginas web). En realidad, la conexión HTTP es la única que obligatoriamente debe incluir la implementación de MIDP. Por tanto, siguiendo de forma estricta el estándar MIDP es el único tipo de conexión posible. Esto es, de alguna forma, una limitación con gran impacto en el diseño de MIDlets.

Siempre se usa la clase Connector para establecer conexiones de red, independientemente del tipo de conexión. Todos los métodos de esta clase son estáticos, siendo el más importante el método open(), con tres versiones diferentes:

El primer parámetro de estos métodos es la cadena de conexión. Se trata del parámetro más importante, ya que determina el tipo de conexión a realizar. La cadena de conexión describe qué tipo de conexión se usará y debe seguir el esquema: Protocolo:Objetivo[;Parámetros]

El parámetro Protocolo es el nombre del protocolo a usar, como http o ftp. El parámetro Objetivo es, típicamente, el nombre de la dirección de red a acceder, pero puede variar según el protocolo usado. El último argumento, Parámetros, es una lista de parámetros asociados a la conexión. Algunos ejemplos de diferentes tipos de conexión se incluyen a continuación:

Hemos de tener en cuenta que el único tipo de conexión que MIDP soporta es la conexión HTTP. Disponer o no de las otras dependerá de la implementación de MIDP que se use.

La segunda y tercera versión del método open() admiten un segundo parámetro relativo al modo. Este argumento describe si la conexión se abre para lectura, escritura o para ambas operaciones. En la clase Connector se definen las siguientes constantes a usar como valores posibles para este parámetro: READ, WRITE y READ_WRITE.

En el caso de la primera versión del método, donde no aparece este argumento, se abrirá una conexión tanto para lectura como para escritura. La última versión del método consta de un único argumento que permite especificar el tiempo límite de espera a establecimiento de la conexión. Si este tiempo se sobrepasa se lanzará una excepción.

En cualquier caso, el método open() devuelve un objeto de la clase Connection, que es la interfaz base de todos los tipos de conexión disponibles. Será necesario hacer una conversión de tipos para convertir este objeto al tipo de conexión que deseemos manejar. Por ejemplo, la siguiente línea de código muestra cómo crear una conexión HTTP mediante la interfaz StreamConnection::

StreamConnection conn = (StreamConnection)Connector.open("http://poldo.ugr.es/frases.txt");

Más adelante se verá la forma de usar este flujo para poder leer datos.

1.2. Entrada/salida en los MIDlets

La clase Connector y los interfaces de conexión asociados se usan para obtener una conexión a red mediante un protocolo específico. Tras el establecimiento de la conexión deben usarse clases que permitan realizar operaciones de entrada salida de la conexión. Estas clases para realizar operaciones de E/S están contenidas en el paquete java.io y son:

Estas clases son similares a las usadas para entrada salida en la plataforma estándar de Java. A continuación se explica cómo usar estas clases para hacer operaciones de entrada y salida. Quizás las clases más importantes sean InputStream y OutputStream, ya que proporcionan la funcionalidad básica de E/S con flujos de datos.

La clase InputStream es una clase abstracta que sirve como clase base para las otras clases de flujos de entrada de MIDP. Esta clase define una interfaz básica para lectura de información de un flujo. El escenario típico de uso de los flujos de entrada consiste en crear un objeto de esta clase a partir de una conexión y después indicar que se desea leer información invocando al método read(). Si no hay información de entrada disponible, entonces el flujo de entrada usa una técnica conocida como bloqueo para esperar hasta la llegada de datos.

Un ejemplo de bloqueo se presenta en el caso de usar un flujo de entrada para leer información de una conexión HTTP. Hasta que el servidor Web no entregue la información no habrá entrada disponible para el objeto de la clase InputStream que hayamos creado. De esta forma. el objeto espera (se bloquea) hasta disponer de información, momento en el que la información se procesa como datos de entrada.

La clase InputStream define los métodos siguientes:

Como se aprecia, hay tres versiones diferentes del método de lectura. El primer método carece de argumentos y simplemente lee un byte de datos del flujo y devuelve un valor entero. Este versión devuelve el valor -1 si se alcanza el final del flujo de entrada. Al devolverse un entero será necesario hacer una conversión a carácter (char) en el caso de leer caracteres.

La segunda versión de read() tiene un array de bytes como único argumento. Esto permite leer varios bytes de datos a la vez, almacenándose los datos leidos en el array. Este método devuelve el número de bytes leidos o bien -1 en caso de alcanzar el final del flujo.

La última versión de read() es similar a la segunda, pero permite especificar las posiciones del array en que se almacenarán los datos leidos. El parámetro off especifica el desplazamiento respecto al inicio del array del lugar de comienzo de almacenamiento. El parámetro len especifica el máximo número de bytes a leer.

El método skip() se usa para saltar bytes del flujo de entrada. El argumento de este método indicará cuántos bytes hay que saltar (ignorar). Devuelve el número de bytes saltados o bien -1 en caso de alcanzarse el final del flujo.

El método available() se usa para determinar el número de bytes de datos de entrada que pueden leerse sin bloquearse. Este méetodo no usa parámetros y devuelve el número de datos disponibles. El método es útil si desea asegurar que hay datos de entrada disponibles antes de llamar al método read() y evitar así el bloqueo.

El método mark() marca la posición actual del flujo. Posteriormente puede volver a esta posición usando el método reset(). Estos métodos son útiles en casos en que se desea leer datos por adelantado, siendo necesario recordar la posición inicial. El método mark() precisa un argumento que especifica el número de bytes que pueden leerse antes de que la marca quede invalidada. Es decir, indica cuántos bytes pueden leerse hacia adelante antes de poder volver atrás. El método markSupported() devulve un valor booleano que indica si un flujo de entrada admite la funcionalidad de establecimiento de marca.

Finalmente, el método close() cierra un flujo de entrada y libera los recursos asociados con el flujo. No es necesario llamar explícitamente al método close() ya que los flujos de entrada se cierran automáticamente al destruirse los objetos de la clase InputStream.

La clase OutputStream es la clase de salida equivalente a InputStream, pero ahora para salida de datos. Sirve como clase base abstracta para todos los flujos de salida de MIDP. Esta clase define el protolo básico para escribir datos en flujos de salida. El uso típico consistirá en crear un objeto de esta clase a partir de la conexión y después llamar al método write() para indicar que se desea escribir información. Esta clase utiliza la técnica de bloqueo similar a la usada por InputStream: el flujo se bloquea hasta haber escrito datos en un dispositivo de salida. Mientras está bloqueado no se admiten nuevas operaciones de escritura. Los métodos soportados por esta clase son los siguientes:

De forma similar a como ocurría con la clase InputStream, esta clase define tres métodos write() diferentes. El primero de ellos escribe un byte en el flujo. Este byte está especificado por el argumento b. La segunda versión de write() toma como argumento un array de bytes, que se escribirán al flujo de salida. La última versión usa tres argumentos: un array, un desplazamiento y una longitud. Es similar a la segunda versión, pero en este caso se define la posición del array a partir de donde empezará la escritura en el flujo y el número de bytes que habrán de enviarse al mismo.

El método flush() se usa para forzar el envío de los datos al flujo.

Por último, el método close() cierra el flujo de salida y libera los recursos que pudieran estar usándose. Como ocurría en el caso de la clase InputStream, no es preciso el cierre explícito del flujo de salida, ya que la destrucción de los objetos de esta clase implica realizar esta operación.

1.3. Comunicación mediante conexiones de red

Tras esta presentación de los aspectos generales de las conexiones a red mediante MIDP y de las clases necesarias para hacer entrada/salida, hay que conjugar ambas cosas para realizar una conexión de red. Esto es más fácil de lo que en principio pudiera parecer. La realización de la conexión consta de los tres pasos básicos indicados a continuación:

  1. Establecer la conexión de red mediante la clase Connector.
  2. Obtener un flujo sobre la conexión, usando los interfaces de conexión disponibles.
  3. Leer o escribir datos en los flujos, según se necesite.

Esto es todo lo necesario. Obviamente, lo realmente importante es lo que luego se hace con los datos enviados, pero esto forma parte de la aplicación a realizar y no tiene que ver con lo considerado en este tema de conexión a redes. A continuación se explicará cómo se realizan los tres pasos básicos descritos previamente.

1. Establecer la conexión

El primer paso necesario consiste en establacer la conexión de red. Esto se consigue mediante el método open() de la clase Connector. La forma más sencilla de este método precisa el uso de un parámetro: la cadena de conexión. El siguiente ejemplo muestra cómo abrir un flujo en una conexión HTTP a una página Web:

StreamConnection conexion = null;
// Como argumento se pasa la dirección URL a acceder
conexion=(StreamConnection)Connector.open("http://www.ugr.es");

El siguiente paso consiste en obtener un flujo de entrada y salida a partir de la conexión. Esto es necesario para poder realizar operaciones de entrada y salida.

2. Obtener el flujo de entrada

Obtener un flujo de entrada es muy sencillo. El código necesario aparece a continuación:

InputStream entrada=conexion.openInputStream();

El método openInputStream() es todo lo que se necesita para obtener el flujo de entrada de la conexión. Una vez obtenido el flujo, puede usarse para leer datos de la conexión HTTP.

3. Leer los datos del flujo

Antes se ha comentado que el método read() es el necesario para poder leer datos de un flujo de entrada. La versión más básica del método lee un byte de entrada, devolviendo su valor como un entero. Las llamadas sucesivas irán devolviendo bytes adicionales de la entrada. La lectura debería seguir hasta agotar los datos disponibles en el flujo (es decir, hasta que una operación de lectura devuelva -1). A continuación se muestra un ejemplo de cómo se haría esto, utilizando un bucle de lectura que muestra por la consola lo que se va leyendo:

StringBuffer datos = new StringBuffer();
// Bucle de lectura hasta que no haya mas datos disponibles
while ((ch = entrada.read()) != -1) {
  if (ch != '\n') {
    // Se lee una linea completa: hasta salto de linea
    datos.append((char)ch);
  }
  else{
    // Ha finalizado la linea y se muestra
    System.out.println(datos.toString());

    // Se limpia el buffer de datos para preparar la lectura
    // de nuevas lineas
    datos = new StringBuffer();
  }
}

En este código la variable datos en un búfer de cadenas de caracteres para mantener una línea de datos cada vez. El método read() se utiliza para ir leyendo caracteres hasta alcanzar el salto de línea. Cuando se alcanza el fin de línea se presenta por pantalla y se limpia el buffer para preparar la recepción de una nueva línea.

Este código representa la premisa básica de cómo deberían leerse datos de un flujo de entrada definido sobre una conexión HTTP. Si se tiene en cuenta la gran cantidad de datos disponibles en páginas Web, la pàrte realmente complicada radica en analizar el texto recibido a través del flujo de entrada para extraer la información necesaria. Se verán algunos ejemplos de cómo hacer esto.

1.4. MIDlet de ejemplo: lectura de archivo ubicado en servidor Web

El MIDlet que realizaremos a continuación tiene como objetivo poner en práctica los conocimientos vistos hasta ahora. Nuestro MIDlet se llamará Frases y tiene como objetivo leer y mostrar, de forma aleatoria, frases localizadas en un archivo ubicado en un servidor Web remoto. Este MIDlet usará una conexión HTTP para abrir el archivo de texto y poder leer de él. El contenido del archivo se volcará en un vector de cadenas de caracteres. Posteriormente, se seleccionará de forma aleatoria una de las frases y se mostrará por pantalla.

La función básica del MIDlet es establecer una conexión de red y leer líneas de un archivo de texto ubicado en un servidor Web. El archivo de texto debe, por tanto, poder abrirse en un navegador Web poniendo su dirección completa.

El archivo de texto ubicado en http://poldo.ugr.es se denomina frases.txt y su contenido es el siguiente:

Aprendemos de la historia que realmente no aprendemos de la historia.
Las leyes mezquinas producen grandes crímenes.
El derecho a estar solo es el comienzo de toda libertad.
Entre amigos, ¿qué es la Constitución?.
El mejor resultado de la educación es la tolerancia.
La tiranía siempre se organiza mejor que la libertad.

Cada frase del archivo debe aparecer en una línea aparte. Esto es necesario porque el MIDlet procesará las líneas una a una. Esto facilita el análisis del texto. Para conseguir la funcionalidad deseada dividiremos el código del MIDlet en los siguientes componentes:

1.4.1. La interfaz de usuario

Al ejecutar este MIDlet por primera vez se recupera el texto completo del archivo. Posteriormente se irán seleccionando las frases de forma aleatoria. La selección se hace al activar el comando Siguiente. Sólo se precisa un comando más, Salir, con el que finaliza la ejecución del MIDlet. Estos comandos se crean como datos miembros de la clase Frases, junto con los elementos de la interfaz de usuario del MIDlet, la cadena de caracteres que almacena la frase actualmente seleccionada, el vector de cadenas necesario para almacenar el contenido del archivo y una variable booleana para controlar si se trata de la primea vez que se llama al método startApp().

  // Comandos de gestion del MIDlet
  private Command comandoSalir, comandoSiguiente;

  // Display del dispositivo movil
  private Display display;

  // Formulario para posicionar los elementos de
  // la aplicacion
  private Form formulario;

  // Para almacenar la frase seleccionada
  private StringItem frase;

  // Vector para guardar todas las frases
  private Vector frases;

  // Variable booleana para controlar la ejecucion
  // de startApp la primera vez y en sucesivas
  // llamadas despues de cada pausa
  private boolean primeraVez;

Como se aprecia, en primer lugar se definen los comandos necesarios: comandoSalir y comandoSiguiente. El objeto display se usará para conseguir mostrar cosas en la pantalla del terminal móvil. El objeto formulario, de la clase Form, se precisa para que contenga la frase seleccionada en cada momento. En este contenedor se mostrará el contenido de la frase seleccionada, que estará almacenada en el objeto frase, de la clase StringItem. Finalmente, se declara el vector frases usado para contener todas las frases del archivo. Para poder usar objetos de la clase Vector es necesario importar la clase (se consigue mediante la sentencia import java.util.Vector;). A continuación se muestran las líneas a incluir en el constructor de la clase:

  // Constructor de la clase Frases. Inicializa los datos
  // miembros
  public Frases() {
     // Se obtiene una referencia al display
     display = Display.getDisplay(this);

     // Se crean los comandos
     comandoSalir=new Command("Salir", Command.EXIT, 2);
     comandoSiguiente = new Command("Siguiente", Command.OK, 2);

     // Se crea el formulario
     formulario = new Form("Frase del día");

     // Se crea el StringItem para contener la frase seleccionada
     frase = new StringItem("", "Leyendo frases...");

     // Se agrega el objeto al formulario
     formulario.append(frase);

     // Se establecen los comandos al formulario
     formulario.addCommand(comandoSalir);
     formulario.addCommand(comandoSiguiente); 

     // Se agrega un gestor de eventos para atender a los comandos
     formulario.setCommandListener(this);

     // Se crea el vector de frases
     frases = new Vector();

     // Se inicializa primeraVez a true
     primeraVez=true;
  }

El código del método startApp(). Siguiendo las indicaciones vistas previamente, se prepara el método para la posible ocurrencia de eventos de pausa. A tal efecto se incluyó el dato miembro primeraVez.

  // Se inicia la ejecucion del MIDlet y se muestra la primera de las frases
  public void startApp() throws MIDletStateChangeException {
     // Mostrar el formulario y leer las frases solo se hara la primera
     // vez
     if (primeraVez == true){
        // Se muestra el formulario por pantalla
        display.setCurrent(formulario);

        // Se leen las frases
        leerFrases();

        // Se hace que primeraVez sea false
        primeraVez=false;
     }

     // Sea o no la primera vez, se selecciona aleatoriamente
     // una frase y se muestra
     mostrarFrase();
  }

1.4.2. Gestión de comandos

La gestión de comandos se realiza en el método commandAction(), cuyo código se incluye a continuación:

  // Método de gestión de los comandos
  public void commandAction(Command c, Displayable s) {
     // Si se trata del comando salir se llama de destroyApp()
     if (c == comandoSalir) {
        // Se llama con argumento false para controlar la
        // posible solicitud de salida mientras se esta
        // leyendo el archivo
        destroyApp(false);

        // Se indica al dispositivo que se desea finalizar
        notifyDestroyed();
     }
     else if (c == comandoSiguiente) {
        // Mostrar de forma aleatoria la siguiente frase
        mostrarFrase();
     }
  }

1.4.3. Lectura del texto del archivo

La funcionalidad de red de este MIDlet se encuentra dentro del método leerFrases(). Recordad que los pasos básicos necesarios son:

Los puntos 2 y 3 se realizan mediante un bucle while que realiza la lectura hasta alcanzar el final del archivo. A continuación se incluye el código comentado del método leerFrases():

  // Método que lee las frases del archivo del servidor web
  private void leerFrases() {
     StreamConnection conexion = null;
     InputStream entrada = null;
     StringBuffer datos = new StringBuffer();

     // Se procede a realizar la conexion
     try {
        // Se abre la conexión HTTP
        conexion=(StreamConnection)Connector.open("http://poldo.ugr.es/frases.txt");

        // Se obtiene un flujo de entrada a partir de la conexión
        entrada = conexion.openInputStream();

        // Se leen lineas del flujo de entrada
        int ch;
        boolean hecho = false;
        while ((ch = entrada.read()) != -1) {
           if (ch != '\n') {
              // La linea se lee caracter a caracter
              datos.append((char)ch);
           }
           else {
              // Se agrega la frase al vector de frases
              frases.addElement(datos.toString());

              // Se limpia el StringBuffer 
              datos = new StringBuffer();
           }
        }
     }
   
     // Se recoge la excepcion, si se produjera
     catch (IOException e) {
        // En caso de producirse error, se muestra el mensaje por la pantalla
        System.err.println("No pudo establecerse la conexión.");
     }
  }  

Quedarí por programar el método que selecciona al azar una frase y la muestra por pantalla:

  // El metodo mostrarFrase selecciona frase al azar y la muestra por pantalla
  private void mostrarFrase() {

     // Se comprueba que el vector de frases no esté vacío
     if (!frases.isEmpty()) {
        // Se crea el generador de números aleatorios. Se inicializa a 
        // partir de la fecha y hora actual
        Random generador = new Random(Calendar.getInstance().getTime().getTime());

        // Se selecciona frase al azar. El número generado estará entre 0 y 
        // el tamaño del vector -1 (que es el índice de la última posición)
        int numeroFrase = Math.abs(generador.nextInt()) % frases.size();

        // Se muestra la frase seleccionada
        frase.setText((String)frases.elementAt(numeroFrase));
     }
     else
       frase.setText("No hay frases disponibles!");
  }

Ejercicio: completad el MIDlet anterior, montar el proyecto correspondiente y hacedlo funcionar.

Resumen

En esta parte se han introducido los conceptos básicos sobre conexión de redes. De ahora en adelante se considera la construcción de un MIDlet capaz de recuperar y mostrar las condiciones meteorológicas de un determinado lugar. No hay ninguna razón especial para elegir este problema y podría haberse trabajado con cualquier otra fuente de información soportada en la Web.

2. MIDlet para mostrar datos meteorológicos

2.1. Información meteorológica en la Web

Una de las aplicaciones más interesantes de J2ME consiste en recuperar datos de Internet y hacerlos disponibles a los usuarios. Una de estas aplicaciones consistiría en obtener información meteorológica mediante el teléfono móvil. Este será el objetivo de esta sección: construir un MIDlet que pueda realizar esta función. Las acciones básicas que el MIDlet debe realizar son:

En la red existen diversos sitios Web que ofrecen información meteorológica en tiempo real. En la mayoría de estos sitios se introduce el nombre de una ciudad o un código postal y se ofrece la información relativa a dicha zona geográfica.

Sin embargo, al pensar en acceder a esta información desde un dispositivo móvil surgen varios problemas. En primer lugar, ¿;cómo actuar sobre la página Web para solicitar información sobre una determinada ciudad? Y en segundo lugar, ¿cómo visualizar la información de la página sobre la pantalla del dispositivo móvil?

Nota:

Para visualizar información meteorológica en un MIDlet es preciso encontrar un origen de los datos (una página Web) con el formato adecuado para poder leer y analizar. Uno de estos sitios es, por ejemplo, http://iwin.nws.noaa.gov/. En este sitio la información se ofrece en un formato simple fácil de analizar y mostrar. Es decir, resulta relativamente sencillo leer la página con los datos solicitados y analizarla para extraer la información de interés. Como la pantalla de los dispositivos móviles es limitada hay que filtrar la información recibida de la página Web antes de mostrarla.

La página web con información meteorológica está bien organizada y está en un formato fácil de acceder. Hemos de pensar en la forma de obtener la información deseada. Jugando un poco con la página vemos que la información de Nueva York se encuentra en la página: http://iwin.nws.noaa.gov/iwin/ny/hourly.html. Esta información URL incluye la dirección base (http://iwin.nws.noaa.gov/) y un par de directorios adicionales que se refieren a la información en la que estamos interesados (iwin/ny/). Finalmente, sigue la página en sí que deseamos recuperar: hourly.html.

Es decir, la información sobre los diferentes estados se organiza en directorios diferentes, de forma que si queremos acceder a la información sobre un determinado estado sólo hemos de modificar las dos letras relativas al estado: en este caso ny. Por ejemplo, si se desea acceder a la información meteorológica sobre Arizona la dirección a usar será: http://iwin.nws.noaa.gov/iwin/az/hourly.html. En realidad, la cadena que indica la dirección a acceder podría descomponerse de la forma siguiente:

String direccion="http://iwin.nws.noaa.gov/iwin/"+estado+"/hourly.html";

La variable estado indicaría las dos letras que identifican a cada uno de los estados.

Conviene ahora prestar atención a la información mostrada en la página de un estado cualquiera. En verdad, aunque parece que su contenido es texto únicamente, se trata de información ubicada en una página web, por lo que está codificada mediante HTML. Por tanto, habrá que ignorar las etiquetas de HTML para acceder a los datos reales. La página de un estado cualquiera sería la siguiente:

New York - Hourly data

NOAA's NWS will be accepting comments on proposed IWIN replacement pages until April 30, 2006. Please learn more about the replacement and how to leave a comment here

      

 
ASUS41 KPHI 030810
RWRPHI

REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE MOUNT HOLLY NJ
400 AM EDT TUE OCT 03 2006

NOTE:  "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.

 * = STATION DOES NOT REPORT PRECIPITATION (E.G. RAIN, SNOW, ETC.) 
        OR FOG.

NJZ015>026-030900-
SOUTHERN NEW JERSEY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
POMONA         PTCLDY    54  49  83 CALM      30.22S                  
TRENTON        CLOUDY    51  48  89 CALM      30.20S                  

$$
NJZ001>014-030900-
NORTHERN NEW JERSEY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
SUSSEX         CLEAR     45  44  97 CALM      30.20F                  
ANDOVER          N/A     46  45  96 CALM      30.20S                  
NEWARK         PTCLDY    55  47  74 W6        30.19S                  
TETERBORO      PTCLDY    53  47  79 CALM      30.18F                  
CALDWELL       PTCLDY    48  47  96 CALM      30.20S                  
SOMERVILLE     PTCLDY    47  45  93 CALM      30.19S                  

$$
PAZ043-044-047-054-055-060>062-066>071-030900-
EASTERN PENNSYLVANIA
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PHILADELPHIA   NOT AVBL                                               
LANCASTER      CLOUDY    57  54  89 CALM      30.19F                  
ALLENTOWN      CLOUDY    52  48  86 CALM      30.19F                  
MOUNT POCONO   CLOUDY    49  45  86 VRB3      30.20F                  
WILKES BARRE   PTCLDY    50  47  89 SE5       30.18F                  

$$
DEZALL-MDZ008-012-015-019-020-030900-
DELAWARE AND EASTERN MARYLAND
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
WILMINGTON     CLOUDY    59  55  87 CALM      30.20S                  
PATUXENT       MOCLDY    62  56  80 SW3       30.21S                  
OCEAN CITY     PTCLDY    58  56  93 W3        30.22R                  
WALLOPS ISLAND PTCLDY    57  53  86 CALM      30.22S                  

$$
PAZ001-021-NYZ056-072-MDZ011-DCZ001-030900-
OTHER NEARBY LOCATIONS
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BINGHAMTON     CLEAR     53  47  79 S6        30.16F                  
NEW YORK CITY  PTCLDY    58  50  75 CALM      30.21F                  
BALTIMORE      NOT AVBL                                               
WASHINGTON DC  LGT RAIN  64  59  83 SE7       30.20F                  

$$


 
 
ASUS41 KOKX 030810
RWROKX

REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE UPTON NY
400 AM EDT TUE OCT 03 2006

NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.

NYZ071-072-076-NJZ005-030900-
NEW YORK CITY METRO AREA
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
CENTRAL PARK   PTCLDY    58  50  75 CALM      30.21F                  
LAGUARDIA APRT PTCLDY    60  49  66 CALM      30.18S                  
KENNEDY INTL   PTCLDY    53  50  89 CALM      30.19F                  
NEWARK/LIBERTY PTCLDY    55  47  74 W6        30.19S                  
WHITE PLAINS   NOT AVBL                                               
$$
 
NYZ077>081-030900-
LONG ISLAND NEW YORK
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
FARMINGDALE    CLEAR     52  48  86 CALM      30.19S                  
ISLIP          NOT AVBL                                               
SHIRLEY        NOT AVBL                                               
WESTHAMPTON    CLEAR     42  39  89 CALM      30.20S                  
MONTAUK POINT    N/A     52  48  86 CALM      30.20R                  
$$
 
NYZ052-065-067-030900-
HUDSON VALLEY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
NEWBURGH       NOT AVBL                                               
MONTGOMERY     NOT AVBL                                               
POUGHKEEPSIE   PTCLDY    45  45 100 CALM      30.17F                  
ALBANY         PTCLDY    50  47  89 S6        30.15F                  
$$
 
NJZ001-003-005-008-013-015-019-021-022-030900-
NEW JERSEY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
TETERBORO      PTCLDY    53  47  79 CALM      30.18F                  
CALDWELL       PTCLDY    48  47  96 CALM      30.20S                  
SOMERVILLE     PTCLDY    47  45  93 CALM      30.19S                  
ANDOVER          N/A     46  45  96 CALM      30.20S                  
TRENTON        CLOUDY    51  48  89 CALM      30.20S                  
MILLVILLE      NOT AVBL                                               
WRIGHTSTOWN    NOT AVBL                                               
BELMAR         NOT AVBL                                               
$$
 
PAZ047>061-062-071-030900-
EASTERN PENNSYLVANIA
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PHILADELPHIA   NOT AVBL                                               
ALLENTOWN      CLOUDY    52  48  86 CALM      30.19F                  
SCRANTON       NOT AVBL                                               
$$

CTZ002-004>006-009-010-012-RIZ004-006-007-MAZ004-011-015-030900-
SOUTHERN NEW ENGLAND
 IN CT
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BRADLEY INTL   CLEAR     47  45  93 CALM      30.17S                  
HARTFORD       CLEAR     49  47  93 CALM      30.18S                  
DANBURY        CLEAR     44  43  96 CALM      30.20F                  
WTRBRY/OXFORD  NOT AVBL                                               
BRIDGEPORT     CLEAR     49  45  86 CALM      30.18F                  
MERIDEN        CLEAR     45  43  93 CALM      30.19R                  
NEW HAVEN      CLEAR     47  45  93 CALM      30.18S                  
GROTON         NOT AVBL                                               
WILLIMANTIC    FOG       45  44  97 CALM      30.19R VSB 1/4          

 IN RI
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PROVIDENCE     PTCLDY    48  46  93 SW5       30.17S                  
BLOCK ISLAND   NOT AVBL                                               
WESTERLY       CLEAR     46  44  93 CALM      30.19R                  

 IN MA
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BOSTON         NOT AVBL                                               
WORCESTER      NOT AVBL                                               
WESTFIELD      MOCLDY    45  44  97 CALM      30.17S                  
PROVINCETOWN   NOT AVBL                                               
NANTUCKET      CLEAR     50  47  89 CALM      30.17R                  
$$

ANZ350-353-355-338-335-330-030900-
COASTAL MARINE OBSERVATIONS
  
STATION/POSITION TIME  SKY/WX   TEMP    WIND        PRES    VSBY  WAVE
                                AIR SEA DIR/SP/G                  HT/PER
                 (UTC)          (F)     (DEG/KT/KT) (MB)    (MI)  (FT/S)
AMBROSE LIGHT    0700            63 66  250/  3/  4 1022.9
BUOY 20S FIRE IS 0700            65 65  220/  4/  6 1022.2          3/13
BUOY 23SW MTP    0700            64 64  290/  8/  8 1022.0          3/12
CENTRAL LI SOUND 0700            63 67  300/ 10/ 14 1022.1
ROBBINS REEF     0700            58     270/  6/  7 1023.2
$$


>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEY <<<<<<<<<<<<<<<<<<<<<<<<<<<
>                                                          <
>     SKY/WX - SKY CONDITION/PRESENT WEATHER               <
>     TMP    - TEMPERATURE IN FAHRENHEIT                   <
>     DP     - DEWPOINT IN FAHRENHEIT                      <
>     RH     - RELATIVE HUMIDITY IN PERCENT                <
>     WIND   - DIRECTION AND SPEED IN MPH                  <
>     PRES   - MEAN SEA LEVEL PRESSURE IN INCHES OF HG     <
>     WCI    - WIND CHILL INDEX                            <
>     VSB    - VISIBILITY IN MILES                         <
>     HX     - HEAT INDEX                                  <
>     TC     - TEMPERATURE IN CELSIUS                      <
>     VRB    - VARIABLE WIND DIRECTION                     <
>                                                          <
>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEY <<<<<<<<<<<<<<<<<<<<<<<<<<<




 
 
ASUS41 KALY 030810
RWRALY

NEW YORK STATE HOURLY WEATHER ROUNDUP
NATIONAL WEATHER SERVICE ALBANY NY
400 AM EDT TUE OCT 03 2006

NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR NO OBSTRUCTIONS TO VISIBILITY.

NYZ032-033-038>043-046>054-057>066-NYZ062>081-030900-
EAST

  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
ALBANY         PTCLDY    50  47  89 S6        30.15F                  
GLENS FALLS    NOT AVBL                                               
POUGHKEEPSIE   PTCLDY    45  45 100 CALM      30.17F                  
NEW YORK CITY  PTCLDY    60  49  66 CALM      30.18S                  
CENTRAL PARK   PTCLDY    58  50  75 CALM      30.21F                  
$$

NYZ005>009-017-018-044>046-055-056-030900-
CENTRAL

  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
SYRACUSE       PTCLDY    47  45  93 E5        30.10F                  
UTICA          NOT AVBL                                               
ELMIRA         MOCLDY    43  43 100 CALM      30.14R FOG              
BINGHAMTON     CLEAR     53  47  79 S6        30.16F                  
$$

NYZ026>034-041>043-030900-
NORTH

  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
WATERTOWN      NOT AVBL                                               
FORT DRUM      NOT AVBL                                               
MASSENA        CLEAR     44  42  93 CALM      30.04F                  
SARANAC LAKE   PTCLDY    37  35  92 CALM      30.09F                  
PLATTSBURGH    CLOUDY    47  45  93 CALM      30.10S                  
$$

NYZ001>004-010>016-019>021-030900-
WEST

  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
NIAGARA FALLS  CLEAR     63  57  81 S12         N/A                   
BUFFALO        CLEAR     60  54  80 S7        30.04F                  
DUNKIRK        MOCLDY    65  55  70 S12       30.05F                  
ROCHESTER      PTCLDY    57  54  89 S5        30.07R                  
PENN YAN       CLEAR     55  51  86 SW7       30.10F                  
$$

             KEY
       WCI = WIND CHILL INDEX
       VSB = VISIBILITY
       HX  = HEAT INDEX
$$


 
 
ASUS41 KBOX 030810
RWRBOX

REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE TAUNTON MA
400 AM EDT TUE OCT 03 2006

NOTE:  "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO 
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.  THE FOLLOWING 
OBSERVATION LOCATIONS DO NOT REPORT PRESENT WEATHER...PROVINCETOWN...
SMITHFIELD...BLOCK ISLAND...KEENE...AND OXFORD.

MAZALL-030900-
EASTERN MASSACHUSETTS
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BOSTON         NOT AVBL                                               
BEVERLY        CLEAR     45  43  93 CALM      30.15F                  
LAWRENCE       NOT AVBL                                               
BEDFORD        NOT AVBL                                               
BLUE HILL        N/A     52  46  80 SW8       30.15S                  
NORWOOD        PTCLDY    38  38 100 CALM      30.16S FOG              
MARSHFIELD     NOT AVBL                                               
PLYMOUTH       NOT AVBL                                               
TAUNTON        CLEAR     41  40  96 CALM      30.15S FOG              
NEW BEDFORD    CLEAR     42  40  92 CALM      30.16S FOG              
$$

MAZALL-030900-
CAPE COD AND THE ISLANDS
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
FALMOUTH       NOT AVBL                                               
HYANNIS        NOT AVBL                                               
CHATHAM        CLEAR     51  48  89 CALM      30.17R                  
NANTUCKET      CLEAR     50  47  89 CALM      30.17R                  
MARTHAS VNYRD  CLEAR     40  37  89 CALM      30.17S                  
$$
 
MAZALL-030900-
CENTRAL AND WESTERN MASSACHUSETTS
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
WORCESTER      NOT AVBL                                               
FITCHBURG      MOCLDY    44  42  93 CALM      30.17S                  
ORANGE         FOG       44  44 100 CALM      30.17R VSB 1/4          
SPRINGFIELD    NOT AVBL                                               
WESTFIELD      MOCLDY    45  44  97 CALM      30.17S                  
NORTH ADAMS    PTCLDY    42  42 100 CALM      30.17F FOG              
$$
 
RIZALL-030900-
RHODE ISLAND
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PROVIDENCE     PTCLDY    48  46  93 SW5       30.17S                  
NEWPORT        CLEAR     47  45  93 CALM      30.18R FOG              
WESTERLY       CLEAR     46  44  93 CALM      30.19R                  
$$
 
CTZALL-030900-
CONNECTICUT
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BRADLEY INTL   CLEAR     47  45  93 CALM      30.17S                  
HARTFORD       CLEAR     49  47  93 CALM      30.18S                  
BRIDGEPORT     CLEAR     49  45  86 CALM      30.18F                  
DANBURY        CLEAR     44  43  96 CALM      30.20F                  
GROTON         NOT AVBL                                               
NEW HAVEN      CLEAR     47  45  93 CALM      30.18S                  
MERIDEN        CLEAR     45  43  93 CALM      30.19R                  
WILLIMANTIC    FOG       45  44  97 CALM      30.19R VSB 1/4          
$$

MEZ002-015-021-024-NHZ003-005-008-011-012-014-VTZ005-008-030900-
NORTHERN NEW ENGLAND
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PORTLAND ME    CLEAR     45  43  93 CALM      30.13S                  
BANGOR ME      CLEAR     45  41  86 W6        30.10R                  
CONCORD NH     CLOUDY    42  41  96 CALM      30.15F                  
MANCHESTER NH  CLOUDY    46  43  89 CALM      30.14R                  
NASHUA NH      MOCLDY    44  42  93 CALM      30.16S                  
PORTSMOUTH NH  NOT AVBL                                               
JAFFREY NH     FOG       41  40  96 CALM      30.16S VSB 1/4          
KEENE NH       NOT AVBL                                               
BURLINGTON VT  MOCLDY    45  42  89 CALM      30.11F                  
MT. WASHINGTON CLOUDY    36  18  48 NW55        N/A  WCI  19          
$$

NYZ052-076-030900-
EASTERN NEW YORK
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
ALBANY         PTCLDY    50  47  89 S6        30.15F                  
NEW YORK CITY  PTCLDY    60  49  66 CALM      30.18S                  
$$
 
ANZALL-030900-
MARINE OBSERVATIONS
  
STATION/POSITION TIME  TEMP    WIND        PRES    VSBY  WAVE
                       AIR SEA DIR/SP/G                  HT/PER
                 (UTC) (F)     (DEG/KT/KT) (MB)    (MI)  (FT/S)
BOSTON BUOY      0700   55 56  240/  4/  6 1021.1F         3/ 7
BUZZARDS BAY     0700   57 63   60/  2/  3 1021.5F
SE OF CAPE COD   0700   60 62  330/ 10/ 12 1020.7S         5/ 6
S OF MONTAUK PT  0700   64 64  290/  8/  8 1022.0S         3/12
MASS BAY-STELLWA 0700   55 58  260/  8/ 10 1020.5R  1 7/8  3/ 6
ISLE OF SHOALS   0700   53     260/  9/ 10 1020.6R
$$

......................KEY.........................
  SKY/WX - SKY CONDITION/PRESENT WEATHER
  TMP    - TEMPERATURE IN FAHRENHEIT
  DWPT   - DEWPOINT IN FAHRENHEIT
  RH     - RELATIVE HUMIDITY IN PERCENT
  WIND   - DIRECTION AND SPEED IN MPH
  PRES   - MEAN SEA LEVEL PRESSURE IN INCHES OF HG
  WCI    - WIND CHILL INDEX
  VSB    - VISIBILITY IN MILES
  HX     - HEAT INDEX
  TC     - TEMPERATURE IN CELSIUS
  VRB    - VARIABLE WIND DIRECTION
  N/A    - NOT AVAILABLE


 
 
ASUS41 KGYX 030808
RWRGYX
WEATHER ROUNDUP FOR MAINE AND NEW HAMPSHIRE
NATIONAL WEATHER SERVICE GRAY ME
400 AM EDT TUE OCT 03 2006

MEZ002-005-006-010-012-015-018-020-021-024-026-027-029-030900-
MAINE
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PORTLAND       CLEAR     45  43  93 CALM      30.13S                  
WISCASSET      NOT AVBL                                               
FRYEBURG       FOG       39  37  93 CALM      30.13R VSB 3/4          
AUGUSTA        NOT AVBL                                               
BANGOR         NOT AVBL                                               
GREENVILLE       N/A     45  42  89 CALM      30.05S                  
MILLINOCKET    NOT AVBL                                               
HOULTON        NOT AVBL                                               
PRESQUE ISLE   NOT AVBL                                               
FRENCHVILLE    NOT AVBL                                               
CARIBOU        CLOUDY    44  41  89 SW3       30.00R                  
$$

NHZ002-005-008-009-011-012-014-030900-
NEW HAMPSHIRE
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
ROCHESTER      PTCLDY    46  44  93 CALM      30.14S                  
MANCHESTER     NOT AVBL                                               
CONCORD        CLOUDY    42  41  96 CALM      30.15F                  
BERLIN         CLOUDY    41  40  96 CALM      30.14R                  
WHITEFIELD     FOG       41  41 100 CALM      30.15R VSB 1/4          
JAFFREY        NOT AVBL                                               
LEBANON        NOT AVBL                                               
MT WASHINGTON  CLOUDY    36  18  48 NW55        N/A                   
$$

VTZ005-007-008-030900-
VERMONT
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
ST JOHNSBURY     N/A     44  43  96 MISG      30.14R                  
MONTPELIER     FOG       41  39  93 CALM      30.16S VSB 1/2          
BURLINGTON     MOCLDY    45  42  89 CALM      30.11F                  
$$

MAZ007-012-024-CTZ003-RIZ002-NYZ038-NYZ072-030900-
SOUTHERN NEW ENGLAND AND NY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PROVIDENCE     PTCLDY    48  46  93 SW5       30.17S                  
HARTFORD       CLEAR     47  45  93 CALM      30.17S                  
ALBANY         PTCLDY    50  47  89 S6        30.15F                  
NEW YORK CITY  PTCLDY    60  49  66 CALM      30.18S                  
$$

ANZ081-ANZ082-ANZ150-NHZ014-MEZ023>029-030900-
COASTAL MARINE OBSERVATIONS
  
STATION/POSITION TIME  TEMP    WIND        PRES    WAVE
                       AIR SEA DIR/SP/G            HT/PER
                 (UTC) (F)     (DEG/KT/KT) (MB)    (FT/S)
MATINICUS ROCK   0700   54     270/ 12/ 14 1018.6F
PORTLAND WX BUOY 0700   54 56  260/ 10/ 12 1019.3S   3/13
ISLE OF SHOALS   0700   53     260/  9/ 10 1020.6R
CASHES LEDGE BUO 0700   56 56                N/A     3/11
GEORGES BANK BUO 0700   59 60  320/ 16/ 19 1017.4R   7/ 7
$$

.............KEY..............
   WCI - WIND CHILL
   TC  - TEMPERATURE IN CELSIUS
   VSB - VISIBILITY IN MILES
   HX  - HEAT INDEX
   FAIR- INDICATES FEW OR NO CLOUDS BELOW 12,000 FT, WITH NO 
         SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.




 
 
ASUS41 KBUF 030800
RWRBUF
 
BUFFALO  CLEAR  60/16  54  81  30.04F  S 7
      


 
 
ASUS41 KPHI 030710
RWRPHI

REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE MOUNT HOLLY NJ
300 AM EDT TUE OCT 03 2006

NOTE:  "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.

 * = STATION DOES NOT REPORT PRECIPITATION (E.G. RAIN, SNOW, ETC.) 
        OR FOG.

NJZ015>026-030800-
SOUTHERN NEW JERSEY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
POMONA         MOCLDY    52  48  86 CALM      30.22S                  

$$
NJZ001>014-030800-
NORTHERN NEW JERSEY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
ANDOVER          N/A     47  45  93 CALM      30.20S                  
NEWARK         NOT AVBL                                               

$$
PAZ043-044-047-054-055-060>062-066>071-030800-
EASTERN PENNSYLVANIA
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PHILADELPHIA   NOT AVBL                                               
ALLENTOWN      FAIR      50  47  89 NW5       30.20S                  
WILKES BARRE   CLOUDY    50  47  89 E3        30.19S                  

$$
DEZALL-MDZ008-012-015-019-020-030800-
DELAWARE AND EASTERN MARYLAND
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
WILMINGTON     NOT AVBL                                               
PATUXENT       FAIR      60  55  83 CALM      30.21R                  
OCEAN CITY     NOT AVBL                                               
WALLOPS ISLAND FAIR      58  53  84 CALM      30.22S                  

$$
PAZ001-021-NYZ056-072-MDZ011-DCZ001-030800-
OTHER NEARBY LOCATIONS
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BINGHAMTON     NOT AVBL                                               
NEW YORK CITY  FAIR      59  51  75 CALM      30.22R                  
BALTIMORE      NOT AVBL                                               
WASHINGTON DC  NOT AVBL                                               

$$


 
 
ASUS41 KALY 030710
RWRALY

NEW YORK STATE HOURLY WEATHER ROUNDUP
NATIONAL WEATHER SERVICE ALBANY NY
300 AM EDT TUE OCT 03 2006

NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR NO OBSTRUCTIONS TO VISIBILITY.

NYZ032-033-038>043-046>054-057>066-NYZ062>081-030800-
EAST

  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
ALBANY         FAIR      48  46  93 S3        30.17R                  
GLENS FALLS    NOT AVBL                                               
POUGHKEEPSIE   NOT AVBL                                               
NEW YORK CITY  NOT AVBL                                               
CENTRAL PARK   FAIR      59  51  75 CALM      30.22R                  
$$

NYZ005>009-017-018-044>046-055-056-030800-
CENTRAL

  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
SYRACUSE       FAIR      47  45  93 E6        30.11F                  
UTICA          NOT AVBL                                               
ELMIRA         NOT AVBL                                               
BINGHAMTON     NOT AVBL                                               
$$

NYZ026>034-041>043-030800-
NORTH

  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
WATERTOWN      NOT AVBL                                               
FORT DRUM      NOT AVBL                                               
MASSENA        NOT AVBL                                               
$$

NYZ001>004-010>016-019>021-030800-
WEST

  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BUFFALO        FAIR      60  53  77 SW7       30.06S                  
ROCHESTER      MOCLDY    57  53  86 SW6       30.06F                  
$$

             KEY
       WCI = WIND CHILL INDEX
       VSB = VISIBILITY
       HX  = HEAT INDEX
$$


 
 
ASUS41 KOKX 030710
RWROKX

REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE UPTON NY
300 AM EDT TUE OCT 03 2006

NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.

NYZ071-072-076-NJZ005-030800-
NEW YORK CITY METRO AREA
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
CENTRAL PARK   FAIR      59  51  75 CALM      30.22R                  
LAGUARDIA APRT NOT AVBL                                               
KENNEDY INTL   NOT AVBL                                               
NEWARK/LIBERTY NOT AVBL                                               
WHITE PLAINS   NOT AVBL                                               
$$
 
NYZ077>081-030800-
LONG ISLAND NEW YORK
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
FARMINGDALE    NOT AVBL                                               
ISLIP          NOT AVBL                                               
SHIRLEY        NOT AVBL                                               
WESTHAMPTON    NOT AVBL                                               
MONTAUK POINT    N/A     53  48  83 CALM      30.19S                  
$$
 
NYZ052-065-067-030800-
HUDSON VALLEY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
NEWBURGH       NOT AVBL                                               
MONTGOMERY     NOT AVBL                                               
POUGHKEEPSIE   NOT AVBL                                               
ALBANY         FAIR      48  46  93 S3        30.17R                  
$$
 
NJZ001-003-005-008-013-015-019-021-022-030800-
NEW JERSEY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
TETERBORO      NOT AVBL                                               
CALDWELL       NOT AVBL                                               
SOMERVILLE     NOT AVBL                                               
ANDOVER          N/A     47  45  93 CALM      30.20S                  
TRENTON        NOT AVBL                                               
MILLVILLE      NOT AVBL                                               
WRIGHTSTOWN    NOT AVBL                                               
BELMAR         NOT AVBL                                               
$$
 
PAZ047>061-062-071-030800-
EASTERN PENNSYLVANIA
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PHILADELPHIA   NOT AVBL                                               
ALLENTOWN      FAIR      50  47  89 NW5       30.20S                  
SCRANTON       NOT AVBL                                               
$$

CTZ002-004>006-009-010-012-RIZ004-006-007-MAZ004-011-015-030800-
SOUTHERN NEW ENGLAND
 IN CT
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BRADLEY INTL   FAIR      48  46  93 CALM      30.17S                  
HARTFORD       NOT AVBL                                               
DANBURY        NOT AVBL                                               
WTRBRY/OXFORD  NOT AVBL                                               
BRIDGEPORT     FAIR      52  46  80 CALM      30.19R                  
MERIDEN        NOT AVBL                                               
NEW HAVEN      NOT AVBL                                               
GROTON         NOT AVBL                                               
WILLIMANTIC    NOT AVBL                                               

 IN RI
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PROVIDENCE     FAIR      49  46  90 W5        30.17F                  
BLOCK ISLAND   NOT AVBL                                               
WESTERLY       NOT AVBL                                               

 IN MA
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BOSTON         NOT AVBL                                               
WORCESTER      NOT AVBL                                               
WESTFIELD      NOT AVBL                                               
PROVINCETOWN   NOT AVBL                                               
NANTUCKET      NOT AVBL                                               
$$

ANZ350-353-355-338-335-330-030800-
COASTAL MARINE OBSERVATIONS
  
STATION/POSITION TIME  SKY/WX   TEMP    WIND        PRES    VSBY  WAVE
                                AIR SEA DIR/SP/G                  HT/PER
                 (UTC)          (F)     (DEG/KT/KT) (MB)    (MI)  (FT/S)
AMBROSE LIGHT    0600            63 66  270/  2/  2 1022.9
BUOY 20S FIRE IS 0600            65 65  200/  2/  4 1022.5          2/13
BUOY 23SW MTP    0600            64 65  290/  6/  8 1022.0          3/12
CENTRAL LI SOUND 0600            64 67  300/  8/  8 1022.1
ROBBINS REEF     0500            62        CALM     1023.0
$$


>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEY <<<<<<<<<<<<<<<<<<<<<<<<<<<
>                                                          <
>     SKY/WX - SKY CONDITION/PRESENT WEATHER               <
>     TMP    - TEMPERATURE IN FAHRENHEIT                   <
>     DP     - DEWPOINT IN FAHRENHEIT                      <
>     RH     - RELATIVE HUMIDITY IN PERCENT                <
>     WIND   - DIRECTION AND SPEED IN MPH                  <
>     PRES   - MEAN SEA LEVEL PRESSURE IN INCHES OF HG     <
>     WCI    - WIND CHILL INDEX                            <
>     VSB    - VISIBILITY IN MILES                         <
>     HX     - HEAT INDEX                                  <
>     TC     - TEMPERATURE IN CELSIUS                      <
>     VRB    - VARIABLE WIND DIRECTION                     <
>                                                          <
>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEY <<<<<<<<<<<<<<<<<<<<<<<<<<<




 
 
ASUS41 KBOX 030710
RWRBOX

REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE TAUNTON MA
300 AM EDT TUE OCT 03 2006

NOTE:  "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO 
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.  THE FOLLOWING 
OBSERVATION LOCATIONS DO NOT REPORT PRESENT WEATHER...PROVINCETOWN...
SMITHFIELD...BLOCK ISLAND...KEENE...AND OXFORD.

MAZALL-030800-
EASTERN MASSACHUSETTS
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BOSTON         NOT AVBL                                               
BEVERLY        NOT AVBL                                               
LAWRENCE       NOT AVBL                                               
BEDFORD        NOT AVBL                                               
BLUE HILL        N/A     52  46  80 SW7       30.15S                  
NORWOOD        NOT AVBL                                               
MARSHFIELD     NOT AVBL                                               
PLYMOUTH       NOT AVBL                                               
TAUNTON        NOT AVBL                                               
NEW BEDFORD    NOT AVBL                                               
$$

MAZALL-030800-
CAPE COD AND THE ISLANDS
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
FALMOUTH       NOT AVBL                                               
HYANNIS        NOT AVBL                                               
CHATHAM        NOT AVBL                                               
NANTUCKET      NOT AVBL                                               
MARTHAS VNYRD  NOT AVBL                                               
$$
 
MAZALL-030800-
CENTRAL AND WESTERN MASSACHUSETTS
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
WORCESTER      NOT AVBL                                               
FITCHBURG      NOT AVBL                                               
ORANGE         NOT AVBL                                               
SPRINGFIELD    NOT AVBL                                               
WESTFIELD      NOT AVBL                                               
NORTH ADAMS    NOT AVBL                                               
$$
 
RIZALL-030800-
RHODE ISLAND
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PROVIDENCE     FAIR      49  46  90 W5        30.17F                  
NEWPORT        NOT AVBL                                               
WESTERLY       NOT AVBL                                               
$$
 
CTZALL-030800-
CONNECTICUT
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
BRADLEY INTL   FAIR      48  46  93 CALM      30.17S                  
HARTFORD       NOT AVBL                                               
BRIDGEPORT     FAIR      52  46  80 CALM      30.19R                  
GROTON         NOT AVBL                                               
NEW HAVEN      NOT AVBL                                               
MERIDEN        NOT AVBL                                               
WILLIMANTIC    NOT AVBL                                               
$$

MEZ002-015-021-024-NHZ003-005-008-011-012-014-VTZ005-008-030800-
NORTHERN NEW ENGLAND
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PORTLAND ME    NOT AVBL                                               
BANGOR ME      NOT AVBL                                               
CONCORD NH     FOG       39  39 100 CALM      30.15F VSB 3/4          
MANCHESTER NH  NOT AVBL                                               
NASHUA NH      NOT AVBL                                               
PORTSMOUTH NH  NOT AVBL                                               
JAFFREY NH     NOT AVBL                                               
KEENE NH       NOT AVBL                                               
BURLINGTON VT  FAIR      45  43  93 CALM      30.13R                  
MT. WASHINGTON CLOUDY    37  19  48 NW52        N/A  WCI  22          
$$

NYZ052-076-030800-
EASTERN NEW YORK
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
ALBANY         FAIR      48  46  93 S3        30.17R                  
NEW YORK CITY  NOT AVBL                                               
$$
 
ANZALL-030800-
MARINE OBSERVATIONS
  
STATION/POSITION TIME  TEMP    WIND        PRES    VSBY  WAVE
                       AIR SEA DIR/SP/G                  HT/PER
                 (UTC) (F)     (DEG/KT/KT) (MB)    (MI)  (FT/S)
BOSTON BUOY      0600   56 57  270/  6/  8 1021.2R         2/ 7
BUZZARDS BAY     0600   58 63   30/  4/  4 1021.8R
SE OF CAPE COD   0600   60 62  340/ 12/ 14 1020.7R         5/ 6
S OF MONTAUK PT  0600   64 65  290/  6/  8 1022.0R         3/12
MASS BAY-STELLWA NOT AVBL
ISLE OF SHOALS   0600   53     250/  8/  9 1020.2S
$$

......................KEY.........................
  SKY/WX - SKY CONDITION/PRESENT WEATHER
  TMP    - TEMPERATURE IN FAHRENHEIT
  DWPT   - DEWPOINT IN FAHRENHEIT
  RH     - RELATIVE HUMIDITY IN PERCENT
  WIND   - DIRECTION AND SPEED IN MPH
  PRES   - MEAN SEA LEVEL PRESSURE IN INCHES OF HG
  WCI    - WIND CHILL INDEX
  VSB    - VISIBILITY IN MILES
  HX     - HEAT INDEX
  TC     - TEMPERATURE IN CELSIUS
  VRB    - VARIABLE WIND DIRECTION
  N/A    - NOT AVAILABLE


 
 
ASUS41 KGYX 030708
RWRGYX
WEATHER ROUNDUP FOR MAINE AND NEW HAMPSHIRE
NATIONAL WEATHER SERVICE GRAY ME
300 AM EDT TUE OCT 03 2006

MEZ002-005-006-010-012-015-018-020-021-024-026-027-029-030800-
MAINE
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PORTLAND       NOT AVBL                                               
WISCASSET      NOT AVBL                                               
FRYEBURG       NOT AVBL                                               
AUGUSTA        NOT AVBL                                               
BANGOR         NOT AVBL                                               
GREENVILLE       N/A     44  42  93 VRB3      30.05S                  
MILLINOCKET    NOT AVBL                                               
HOULTON        NOT AVBL                                               
PRESQUE ISLE   NOT AVBL                                               
FRENCHVILLE    NOT AVBL                                               
CARIBOU        CLOUDY    43  40  89 W5        29.99S                  
$$

NHZ002-005-008-009-011-012-014-030800-
NEW HAMPSHIRE
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
ROCHESTER      NOT AVBL                                               
MANCHESTER     NOT AVBL                                               
CONCORD        FOG       39  39 100 CALM      30.15F VSB 3/4          
BERLIN         NOT AVBL                                               
WHITEFIELD     NOT AVBL                                               
JAFFREY        NOT AVBL                                               
LEBANON        NOT AVBL                                               
MT WASHINGTON  CLOUDY    37  19  48 NW52        N/A                   
$$

VTZ005-007-008-030800-
VERMONT
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
ST JOHNSBURY     N/A     44  43  96 MISG      30.13F                  
BURLINGTON     FAIR      45  43  93 CALM      30.13R                  
$$

MAZ007-012-024-CTZ003-RIZ002-NYZ038-NYZ072-030800-
SOUTHERN NEW ENGLAND AND NY
  
CITY           SKY/WX    TMP DP  RH WIND       PRES   REMARKS
PROVIDENCE     FAIR      49  46  90 W5        30.17F                  
HARTFORD       FAIR      48  46  93 CALM      30.17S                  
ALBANY         FAIR      48  46  93 S3        30.17R                  
$$

ANZ081-ANZ082-ANZ150-NHZ014-MEZ023>029-030800-
COASTAL MARINE OBSERVATIONS
  
STATION/POSITION TIME  TEMP    WIND        PRES    WAVE
                       AIR SEA DIR/SP/G            HT/PER
                 (UTC) (F)     (DEG/KT/KT) (MB)    (FT/S)
MOUNT DESERT ROC 0600   53     300/ 12/ 13 1018.9R
MATINICUS ROCK   0600   54     280/ 10/ 11 1018.7R
PORTLAND WX BUOY 0600   53 56  270/  8/ 10 1019.3S   2/14
ISLE OF SHOALS   0600   53     250/  8/  9 1020.2S
CASHES LEDGE BUO 0600   56 56                N/A     4/13
GEORGES BANK BUO 0600   59 60  320/ 16/ 17 1017.2R   8/ 8
$$

.............KEY..............
   WCI - WIND CHILL
   TC  - TEMPERATURE IN CELSIUS
   VSB - VISIBILITY IN MILES
   HX  - HEAT INDEX
   FAIR- INDICATES FEW OR NO CLOUDS BELOW 12,000 FT, WITH NO 
         SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.




 
 
ASUS41 KBUF 030700
RWRBUF
 
BUFFALO  MAINLY CLEAR  60/16  53  78  30.06S  SW 7
      


 
This data is from the IWIN (Interactive Weather Information Network)

El archivo con el código html de esta página puede descargarse en el siguiente enlace: hourly.html.

El comienzo de la página contiene información no relacionada con nuestro objetivo. Mirando la parte inferior se observa que cada línea de datos comienza con el nombre de la ciudad, seguido por un conjunto de datos meteorológicos, formateados en columnas. Por tanto, para buscar la información sobre una determinada ciudad basta con encontrar la línea en que se encuentra este nombre y extraer la información necesaria. Este es el enfoque que se seguirá en este ejemplo.

2.2. Construcción del MIDlet meteorológico

La función básica del MIDlet a construir es establecer una conexión de red y recuperar el contenido de una página Web, que se analizará para buscar la información deseada, que se mostrará en la pantalla del terminal.

Para tener más control en el desarrollo de la aplicación se divide el proceso de desarrollo en tres etapas:

La interfaz de usuario

El MIDlet está diseñado de forma que el usuario debe ser capaz de introducir la ciudad y el estado del que se busca la información meteorológica. Tras obtener la información se precisa alguna forma de presentación de los datos obtenidos. Por tanto sería conveniente disponer de dos pantallas diferentes: una para gestionar la introducción de ciudad y estado y otra diferente para mostrar la información recogida de la página Web. En definitiva. el usuario introduce la ciudad y el estado y, tras pulsar un botón, se realiza la conexión para obtener el contenido de la página. Tras su análisis los resultados se presentarán en la pantalla correspondiente. Los resultados se limitan a presentar la información sobre condiciones generales, temperatura, humedad relativa, velocidad del viento y dirección. La pantalla donde se mostrará esta información se denominará pantalla de salida.

Además, será preciso disponer de varios comandos para controlar el funcionamiento de la aplicación. La pantalla de localización, donde se introduce el estado y la ciudad, precisa de un comando Ir que inicia la recuperación de datos. Como esta pantalla será, de alguna forma, la pantalla principal de la aplicación, es conveniente disponer de un comando Salir que finaliza la aplicación. Además, la pantalla de salida precisa de una comando Atrás que permita volver a la pantalla inicial.

Para realizar las pantallas se utilizan varios componentes de la interfaz de usuario que se almacenan como datos miembros del MIDlet Tiempo. La declaración de datos miembros es la siguiente:

   // Definicion de los comandos
   private Command comandoSalir, comandoIr, comandoAtras;

   // Display del dispositivo movil
   private Display display;

   // Especificacion del formulario de localizacion y de los campos de texto
   // que se usaran en el
   private Form pantallaLocalizacion;
   private TextField campoCiudad, campoEstado;

   // Especificacion del formulario de condiciones y de los textos que se
   // mostraran en el
   private Form pantallaCondiciones;
   private StringItem localizacion, condiciones, temperatura, humedad, viento;

Por su parte, el constructor de la clase se muestra a continuación:

   // Constructor de la clase Tiempo
   public Tiempo() {
      // Obtiene una referencia al display
      display = Display.getDisplay(this);

      // Se crean los comandos necesarios
      comandoSalir = new Command("Salir", Command.EXIT, 2);
      comandoIr = new Command("Ir", Command.OK, 2);
      comandoAtras = new Command("Atras", Command.BACK, 2);

      // Se crea el formulario de localizacion
      pantallaLocalizacion = new Form("Introduzca localización");
      // Se crea el campo de texto para introducir la ciudad
      campoCiudad = new TextField("Ciudad", "", 25, TextField.ANY);

      // Se agrega a la pantalla de localizacion
      pantallaLocalizacion.append(campoCiudad);

      // Se crea el campo de texto para introducir el estado
      campoEstado = new TextField("Estado", "", 2, TextField.ANY);

      // Se agrega el campo a la pantalla de localización
      pantallaLocalizacion.append(campoEstado);

      // Asocia los comandos de salida y de proceder a la busqueda
      pantallaLocalizacion.addCommand(comandoSalir);
      pantallaLocalizacion.addCommand(comandoIr);

      // Se asocia a la pantalla el gestor de comandos
      pantallaLocalizacion.setCommandListener(this);

      // Se crea el formulario de la pantalla de condiciones
      pantallaCondiciones = new Form("Condiciones actuales");

      // Se crean los items de texto que apareceran en la pantalla. Se
      // comienza por el de localizacion
      localizacion = new StringItem("", "");
      pantallaCondiciones.append(localizacion);

      // Se crea el string para las condiciones
      condiciones = new StringItem("", "");
      pantallaCondiciones.append(condiciones);

      // Lo mismo para la temperatura
      temperatura = new StringItem("", "");
      pantallaCondiciones.append(temperatura);

      // Igual para la humedad
      humedad = new StringItem("", "");
      pantallaCondiciones.append(humedad);

      // Igual para el viento
      viento = new StringItem("", "");
      pantallaCondiciones.append(viento);

      // Se asocia el comando Atrás a la pantalla de condiciones
      pantallaCondiciones.addCommand(comandoAtras);
      pantallaCondiciones.setCommandListener(this);
   }

El MIDlet que estamos construyendo consta de tres comandos: Salir, Ir y Atrás. El comando de salida ya se usó en el MIDlet previo, pero el funcionamiento de los otros dos precisa quizás algunos comentarios adicionales. El comando Ir está asociado a la pantalla de localización y es responsable de iniciar la recogida y presentación de datos meteorológicos sobre la ciudad y estado que el usuario haya introducido. El comando Atrás está asociado a la pantalla de condiciones y tiene como misión provocar que aparezca de nuevo la pantalla de localización, de forma que el usuario del MIDlet pueda volver a introducir otra ciudad y estado (o bien que se salga de aplicación). El método responsable de gestionar los comandos e implementar su funcionalidad se presenta a continuación:

   // Método commandAction
   public void commandAction(Command comando, Displayable pantalla) {
      // Si se trata del comando salir, se sale de la aplicación. Se usa
      // false como argumento
      if (comando == comandoSalir) {
         destroyApp(false);
         notifyDestroyed();
      }
      // Si el comando es Ir, se procede a obtener la información
      else if (comando == comandoIr) {
         // Se obtiene la información para el estado y ciudad indicados
         obtenerCondiciones(campoCiudad.getString().toUpperCase(), campoEstado.getString().toLowerCase());
      }
      // Si el comando es Atras, se vuelve a la pantalla de localizacion
      else if (comando == comandoAtras) {
         // Se vacían los campos de ciudad y estado
         campoCiudad.setString("");
         campoEstado.setString("");

         // Se vuelve a la pantalla de localización
         display.setCurrent(pantallaLocalizacion);
      }
   }

Lectura de datos

El método obtenerCondiciones() lee la ciudad y el estado especificado y procede a leer los datos meteorológicos adecuados. La dirección URL de la página a consultar incluye las iniciales del estado en minúscula. Las iniciales de la ciudad, sin embargo, han de ir en mayúscula. De ahí la llamada a las funciones pertinentes para asegurarse que al producirse la conexión web la dirección URL esté convenientemente formada.

El corazón de la aplicación, por tanto, es el método encargado de obtener las condiciones meteorológicas deseadas. Este método debe realizar las siguientes tareas:

  1. Construir la dirección URL a acceder
  2. Abrir la conexión con dicha dirección
  3. Leer los datos de la conexión de red y buscar la información de interés
  4. Al encontrar la información deseada, extraer la información relevante
  5. Presentar la información en la pantalla de la aplicación

Estos pasos pueden apreciarse en el método, cuyo listado aparece a continuación:

   // Método para obtener las condiciones meteorológicas
   private void obtenerCondiciones(String ciudad, String estado) {
      StreamConnection conexion = null;
      InputStream entrada = null;
      StringBuffer datos = new StringBuffer();

      // Se intenta el establecimiento de la conexion. Esto debe hacerse
      // en un bloque try-catch
      try {
         // Se abre la conexion HTTP
         conexion = (StreamConnection)Connector.open("http://iwin.nws.noaa.gov/iwin/"+estado+"/hourly.html");
System.out.println("Conexion a : http://iwin.nws.noaa.gov/iwin/"+estado+"/hourly.html");

         // Se obtiene el flujo de entrada de la conexion
         entrada = conexion.openInputStream();

         // Se lee la entrada linea a linea
         int ch;
         boolean hecho = false;

         // Bucle de lectura. Si se alcanza el caracter -1 indica que no hay
         // mas datos
         while (((char)(ch = entrada.read()) != -1) && !hecho) {
            // Mientras no se lea el salto de linea
            if (ch != '\n') {
               // El caracter se agrega a los datos leidos
               datos.append((char)ch);
            }
            else {
               // Al ir leyendo vemos si aparece la ciudad buscada. Para que
               // pueda estar, la longitud de la cadena leida debe ser al menos
               // igual de larga que el nombre de la ciudad buscada
               if (datos.length() >= ciudad.length()) {
                  // Se mira si la ciudad buscada es la primera palabra de la
                  // linea leida
                  if ((ciudad.length() > 0) &&
                      (datos.toString().substring(0, ciudad.length()).compareTo(ciudad) == 0)) {
                      // Si se ha encontrado, se escriben los datos obtenidos
                      localizacion.setText(ciudad + ", " + estado.toUpperCase());

                      // Se muestran las condiciones 
                      condiciones.setText("Cond.: " +datos.toString().substring(15, 22));

                      // Se extrae la temperatura y se muestra
                      temperatura.setText("Temperatura: " +datos.toString().substring(25, 27) + '\260');

                      // Se extrae y muestra la humedad relativa
                      humedad.setText("Humedad Rel.: " +datos.toString().substring(33, 35) + "%");

                      // Se extrae y muestra la velocidad del viento
                      viento.setText("Viento: " +datos.toString().substring(36, 44) + " mph");

                      // Se muestra la pantalla de condiones
                      display.setCurrent(pantallaCondiciones);

                      // Se indica que se ha terminado, para no seguir leyendo
                      hecho = true;
               }
            }

            // Se libera el string para leer los datos de la siguiente linea
            datos = new StringBuffer();
         }
      }

      // Si al llegar aqui la variable booleana hecho vale false,
      // entonces se indica que hubo algun problema 
      if (!hecho)
         display.setCurrent(new Alert("Tiempo","Localización no válida.", null, AlertType.ERROR));
      }
      catch (IOException e) {
         System.err.println("Problema al establecer la conexión.");
      }
   }

Prueba del MIDlet

Tras compilar, preverificar y empaquetar el MIDlet, hay que probarlo en el emulador de Ktoolbar, por ejemplo. Para cubrir la funcionalidad siguiente se realizará el siguiente conjunto de acciones:

Ejercicio: completad el MIDlet anterior, montar el proyecto correspondiente y hacedlo funcionar.

Ejercicio: construid un MIDlet de consulta de distancias entre dos direcciones. Leed las notas siguientes para realizar este ejercicio:

3. Ejercicio: MIDlet con información de rutas

3.1. Dirección Web a usar

Existen algunas páginas Web que permiten introducir una dirección de partida y otra de llegada y obtener la forma de alcanzar la segunda desde la primera. La idea de este ejercicio es usar estas páginas para construir un MIDlet que haga esta tarea desde un dispositivo móvil. En concreto, la página a usar es la de Microsoft MapPoint. Si se abre dicha página se obtiene una pantalla como la siguiente:

Direcciones en la Web

3.2. Consideraciones

Conviene tener en cuentas las siguientes consideraciones:

Otra cosa a tener en cuenta es la posibilidad de que se produzca una redirección. Algunas veces, al teclear una dirección URL se produce un redireccionamiento directo a otra dirección distinta. Una posible forma de controlar esto sería como se indica en el siguiente fragmento de código:

   // Método para realizar la conexion controlando la redireccion
   private void conectar() {
      HttpConnection conexion = null;
      InputStream entrada = null;
      StringBuffer datos = new StringBuffer();
      String direccionURL="....la que sea....";
      int respuesta=-1;
      int ch;

      System.out.println("Intento de conexion con: "+direccionURL);
      // Se intenta el establecimiento de la conexion. Esto debe hacerse
      // en un bloque try-catch
      try {
         // Se abre la conexion HTTP. Se hace bucle para volver a intentarlo
         // en caso de ser necesario, de haber redireccion
         while (true){
            // Se intenta establecer la conexion
            conexion = (HttpConnection)Connector.open(direccionURL,Connector.READ_WRITE);

            // Se obtiene el codigo de respuesta a la peticion de conexion
            respuesta=conexion.getResponseCode();

            // Por si queremos ver la respuesta por pantalla
            System.out.println("Respuesta: "+respuesta);

            // Si hay redireccion, se controla
            if (respuesta == HttpConnection.HTTP_TEMP_REDIRECT ||
                respuesta == HttpConnection.HTTP_MOVED_TEMP ||
                respuesta == HttpConnection.HTTP_MOVED_PERM) {

                // Se obtiene la nueva direccion
                direccionURL = conexion.getHeaderField("location");
                direccionURL="http://maps.msn.com/"+direccionURL;

                // Se muestra por pantalla la nueva direccion
                System.out.println("Nueva direccion: "+direccionURL);
                conexion.close();
            } 
            else {
                // Si se pudo conectar, se rompe el bucle
                break;
            }
         }

         // Se controla, pese a todo, si hubo algun otro error
         if (respuesta != HttpConnection.HTTP_OK){
           conexion.close();
           System.out.println("Codigo error: "+respuesta);

           // En este caso se destruye el MIDlet
           destroyApp(true);
           notifyDestroyed();
         }
      }
      catch (IOException e) {
         System.err.println("Problema al establecer la conexión.");
         // En este caso se destruye el MIDlet
         destroyApp(true);
         notifyDestroyed();
      }

      // Si se llega aqui, la conexion esta realizada
      // a la lectura de la informacion
      ................................
   }

4. Conexión con servlets

Definición de servlet

En las aplicaciones Web es muy usual, como hemos visto, tener que rellenar datos en un formulario para solicitar información, registro, etc. Cuando el usuario de la página pulsa sobre el botón Enviar, el contenido de la página es procesado por un programa denominado CGI (Common Gateway interface). Los CGIs residen en el servidor y tienen como objetivo leer los datos introducidos por el usuario y componer una nueva página Web que se muestra en el navegador, conteniendo, normalmente, información para el usuario (subscripción correcta, falta de datos, página de registro, etc). Este mecanismo, sin embargo, presenta varios problemas:

Estas razones originan la aparición de la tecnología servlet. De esta forma, se hace que cada ejecución se haga en una hebra (y no en un proceso aparte) y que, al mismo tiempo, se pueda controlar los privilegios de seguridad del servlet.

Desde el punto de vista de programación del dispositivo móvil, lo que interesa saber es la forma de enviar datos a un servlet, de forma que este pueda realizar su trabajo. Esto es muy similar a los ejemplos vistos anteriormente. En realidad, en el ejemplo de las distancias entre direcciones, se estaba haciendo esto. La forma de especificar la dirección URL de un servlet es:

http://host/servlet?parámetros

Hay que tener en cuenta varias consideraciones a la hora de especificar los argumentos. En primer lugar, los argumentos se separan mediante el carácter &. Los espacios en blanco deben sustituirse por el carácter +. Los caracteres alfanuméricos deben cambiarse por % seguido del número hexadecimal que representa el código del carácter a representar. Por ejemplo, si se quiere enviar como argumento S. Antonio, entonces habrá que escribir S%2e+Antonio. Esto es así ya que el número hexadecimal 2e es el código ASCII del carácter ".".

Ejercicio

En la dirección http://sesamo.ugr.es:8080/calcAvanzada se ha instalado el servlet calculadora, cuya misión es realizar operaciones aritméticas que no pueden realizarse en el dispositivo móvil, como por ejemplo, senos y logaritmos. Los parámetros de este servlet son:

Tanto el establecimiento de la conexión como la lectura de datos se realiza de forma análoga a como se ha visto en el resto de ejemplo.