Mostrando entradas con la etiqueta Moviles. Mostrar todas las entradas
Mostrando entradas con la etiqueta Moviles. Mostrar todas las entradas

lunes, 17 de mayo de 2010

Login WAP

Les dejo un script para hacer un login para páginas WAP (para el celular).
El script lo adapté a mi página, de alguno que habré encontrado en Hotscripts.com y me fue muy útil.
Es bueno, ya que no necesitas ningun servidor espacial para WAP, sino uno que tenga PHP y MySQL (mas abundantes).

index.php

Código PHP:
<?php//reg wml+php+mysql script v 1,00 (c) GumSloneheader("Content-type: text/vnd.wap.wml");header("Cache-Control: no-store, no-cache, must-revalidate");
print
'<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card title="Mi Sitio Wap"><p>'
;
include(
"config.php");$name$_GET['name'];$pass$_GET['pass'];$action $_GET['action'];$namestrtolower($name);$result mysql_query("SELECT * FROM usuarios WHERE usr='$name' AND pwd='$pass'",$link);$otvet mysql_fetch_array($result);
$usr $otvet['usr'];
if (
$action == "panel"){
    if(
$otvet['usr'] != ""){
        echo 
'Hola '.$otvet['usr'].'!<br/>';
        echo 
'<a href="./link.php?name='.$name.'&amp;pass='.$pass.'&amp;action=panel">Link 1</a><br/>';
        echo 
'<a href="./link.php?name='.$name.'&amp;pass='.$pass.'&amp;action=panel">Link 2</a><br/>';
    }
} else if (
$action == "exit"){
    echo 
'<a href="index.php">Sesion cerrada correctamente!</a>';
}else{
        echo 
'Mi Sitio Wap - Login<br/>';
        echo 
'
        Nombre de usuario:
        <input type="text" name="name"/>
        <br/>
        Clave Movil:
        <input type="password" name="pass"/>
        <br/>
        <a href="index.php?name=$(name)&amp;pass=$(pass)&amp;action=panel">[Login]</a>
        <br/>'
;
}
print
"</p>
</card>
</wml>"
;?>
config.php


Código PHP:
<?php//reg wml+php+mysql script v 1,00 (c) GumSlone$db_host "localhost";  // DB Host$db_user "";  // DB User$db_pass "";  // DB Pass$db_name "";  // DB Name$link mysql_connect($db_host$db_user$db_pass);mysql_select_db($db_name$link);?>

J2ME, Java Wireless Message API (WMA)

Sin lugar a dudas, la mensajería instantánea a través de mensajes cortos (SMS) es una de las formas de comunicación más extendida y aceptadas por la sociedad.
En este tutorial voy a intentar hacer una introducción de las características más importantes que nos proporciona Java para el envío y recepción de SMS desde aplicaciones para móviles (MIDLets). Se presupone que el lector ya posee conocimientos básicos de programación (J2ME, MIDP, CLDC), compilación e instalación de MIDLets.

Introducción a WMA

WMA, son las siglas de Wireless Message API (curiosamente también lo son de uno de los formatos de audio de Windows, Windows Media Audio), una extensión de la especificaciones del CLDC y MIDP para el envio, la recepción y la gestión de SMS desde MIDLets.
A pesar de ser una extensión opcional, la gran mayoría de los terminales la llevan instalada y lista para ser usuada desde nuestras aplicaciones J2ME.
WMA es una especificación no una implementación. Su implementación dependerá del terminal y del protocolo de comunicación que use (GSM, CDMA, etc). Por supuesto, nosotros como desarrolladores podemos abstraernos de esto último.
Versiones de la especificación WMA:
Versión 1.0: Especificación inicial. Describe las funcionales básicas para el envío y la recepción de SMS. (JSR 120)
Versión 1.1: Una ampliación de la especificación 1.0, para soportar el nuevo modelo de seguridad del MIDP 2.0.
Versión 2.0: Una ampliación a las anteriores para la gestión de mensajes multimedia (MMS). (JSR 205)

Introducción al API WMA

El API está compuesto exclusivamente de interfaces ubicadas bajo el páquete javax.wireless.messaging. Estas interfaces son:
javax.wireless.messaging.Message: Define la funcionalidad genérica de todos los tipos de mensajes. Permite:
  1. Especificar el destinatario del mensaje. public void setAddress(String addr)
  2. Obtener el emisor del mensaje. public String getAddress()
  3. Obtener la fecha de envio del mensaje. java.util.Date getTimestamp()
javax.wireless.messaging.TextMessage: Representa a un mensaje de texto.
Hereda la funcionalidad de javax.wireless.messaging.Message añadiendo los métodos public void setPayloadText(String data) y public String getPayloadText() para especificar u obtener los datos del mensaje.
javax.wireless.messaging.BinaryMessage: Representa a un mensaje binario.
Hereda la funcionalidad de javax.wireless.messaging.Message añadiendo los métodos public void setPayloadData(byte[] data) y public byte[] getPayloadData() para especificar u obtener los datos del mensaje.
javax.wireless.messaging.MessageListener: Oyente de mensajes entrantes.
Esta interfaz es útil en javax.wireless.messaging.MessageConnection que funcionan en modo servidor. (Será explicada más adelante.)
javax.wireless.messaging.MessageConnection: Interfaz a través de la cual se realiza el envío y la recepción de mensajes. (Será explicada más adelante.)

¿Qué pasos tengo que realizar para enviar un mensaje (SMS)?

  1. Obtener un MessageConnection en modo cliente (Se verá más adelante).
  2. Crear el mensaje a través de la interfaz MessageConnection.
  3. Especificar el contenido y el destinatario del mensaje.
  4. Usar el método send de la interfaz MessageConnection para enviar el mensaje.

¿Qué pasos tengo que realizar para recibir un mensaje (SMS) de forma asíncrona?

  1. Obtener un MessageConnection en modo servidor (Se verá más adelante).
  2. Implementar la interfaz MessageListener en una de nuestras clases.
  3. Asociar la clase anterior al MessageConnection.
  4. Cuando el método notifyIncomingMessage() de la interfaz MessageListener sea invocado, significa que hemos recibido un mensaje.
  5. Deberemos invocar el método receive() de la interfaz MessageConnection en un hilo independiente.
  6. Realizar el tratamiento del mensaje.

¿Qué pasos tengo que realizar para recibir un mensaje (SMS) de forma síncrona?

  1. Obtener un MessageConnection en modo servidor (Se verá más adelante).
  2. Invocar el método receive() de la interfaz MessageConnection en un hilo independiente (Es un método bloqueante).
  3. Realizar el tratamiento del mensaje.

En J2ME, todas las comunicaciones que requieren los MIDLets con el exterior (Bluetooth, Socket, Http, etc.) se obtienen a través la clase javax.microedition.io.Connector que forma parte del CLDC. Esta clase devuelve una instancia de una clase que implementa la interfaz javax.microedition.io.Connection para el modo de comunicación deseada. Pues bien, la interface javax.wireless.messaging.MessageConnection no es más que un javax.microedition.io.Connection para comunicación via SMS.
Básicamente a través de está inteface podemos crear, enviar y recibir SMS tanto de forma síncrona como asíncrona.

¿Cómo obtengo javax.wireless.messaging.MessageConnection?

Los javax.wireless.messaging.MessageConection pueden funcionar de dos modos:
  1. En modo cliente: Sólo sirve para enviar SMS a un destinatario.
  2. En modo servidor: Sirve para recibir y tratar los SMS que son dirigidos hacia el. En esté modo también se pueden enviar SMS.
La forma de especificar el modo de funcionamiento deseado se realiza a través de la cadena de conexión que se le pasa a la clase javax.microedition.io.Connector.
Ejemplos de como especificar el modo cliente:
MessageConnection conn = (MessageConnection) javax.microedition.io.Connector.open("sms://+34666666666");
MessageConnection conn = (MessageConnection) javax.microedition.io.Connector.open("sms://+34666666666:5555"); En ambos casos el SMS sería enviado al teléfono 666666666 de España (por el prefijo +34), pero con una importante diferencia. En el primer caso, el SMS sería tratado por la aplicación que por defecto tiene instalada el teléfono, mientras que, en el segundo caso, el SMS sería tratado por la aplicación que esté escuchando en ese puerto.
Ejemplo de como especificar el modo servidor:
MessageConnection conn = (MessageConnection) javax.microedition.io.Connector.open("sms://:5555");
Los SMS que llegen al puerto 5555 serán atendidos por el MIDLet. En realidad, "5555" NO es un puerto sino un IDENTIFICADOR que le indica a la plataforma java que desea tratar los SMS que llegen al terminal con ese identificador.

Métodos de la clase:

public javax.wireless.messaging.Message newMessage(java.lang.String type, java.lang.String address)
Crea un nuevo mensaje para ser enviado.
En el argumento type especificamos el tipo de mensaje que deseamos enviar:
   MessageConnection.TEXT_MESSAGE para mensajes de texto
   MessageConnection.BINARY_MESSAGE para mensajes binarios.
En el argumento address debemos especificar la dirección del destinatario del mensaje. Normalmente, su número de teléfono.
public int numberOfSegments(javax.wireless.messaging.Message msg)
Devuelve el número de segmentos que son necesarios para enviar la información a través de la red.
Por ejemplo, si queremos enviar el Quijote via SMS pues seguro que son necesarios más de un segmento (un segmento es igual a un SMS como lo conocen los usuarios) y este método nos devolvería o bien un número grande o bien el valor 0 indicando que no se puede enviar la información deseada.
public javax.wireless.messaging.Message receive() throws IOException, InterruptedIOException
Devuelve un mensaje enviado a nuestra aplicación. Hay que tener varias cosas importantes en mente:
  1. Es un método bloqueante, por lo que generalmente deberá ser invocado en un hilo distinto al hilo principal donde está ejecutandose el Midlet.
  2. Nuestra aplicación es responsable de guardar la información recibida a memoria no volátil en caso de ser necesario.
public void send(javax.wireless.messaging.Message msg) throws IOException, InterruptedIOException
Envia el mensaje al destinatario.
Este método debe ser invocado en un hilo distinto al hilo principal donde está ejecutandose el Midlet.
Para especificar el destinatario del mensaje se debe usar el método setAddress(java.lang.String addr) definido en la interfaz javax.wireless.messaging.Message de la que heradan javax.wireless.messaging.TextMessage y javax.wireless.messaging.BinaryMessage.
public void setMessageListener(javax.wireless.messaging.MessageListener l) throws IOException
Registrar una clase que implemante la interfaz javax.wireless.messaging.MessageListener, el plataforma J2ME invocará el método notifyIncomingMessage() cuando reciba un mensaje.
Este método sólo tiene sentido para javax.wireless.messaging.MessageConnection que funcionen en modo servidor

Ejemplo 1. Envío de un SMS en modo texto.

En este ejemplo, vamos a hacer una aplicación que envie el texto que introduzca el usuario en un área de texto a un destinatario fijo.
Para el desarrollo de aplicaciones para móviles, yo personalmente utilizo el IDE NetBeans con la extensión Mobility

  1. package autentia.tutoriales.wma;  
  2. import javax.microedition.lcdui.*;  
  3. improt javax.microedition.midlet.*;  
  4.   
  5. /** 
  6.  * MIDLet de Ejemplo del uso del API WMA (Wireless Messagin API)  
  7.  * @author Carlos García. Autentia. 
  8.  */   
  9. public class WMAMidlet extends javax.microedition.midlet.MIDlet {  
  10.     private boolean started;  
  11.       
  12.     /** 
  13.      * Constructor 
  14.      */  
  15.     public WMAMidlet(){  
  16.         this.started = false;  
  17.     }  
  18.   
  19.     /*  
  20.      * @see javax.microedition.midlet.MIDlet#startApp() 
  21.      */  
  22.     protected void startApp() throws MIDletStateChangeException {  
  23.            
  24.         // Este método puede ser incovado varias veces mientras la aplicación se esté ejecutando.   
  25.         // Por ejemplo, si se está ejecutando la aplicación y nos llega una llamada   
  26.         // entrante, la aplicación generalmente es pausada y esté método será   
  27.         // invocado cuando la llamada finalize.  
  28.           
  29.         if (! this.started){      
  30.             this.started = true;  
  31.             Display.getDisplay(this).setCurrent(new WMAMainForm(this));  
  32.         }  
  33.     }  
  34.       
  35.     /*  
  36.      * @see javax.microedition.midlet.MIDlet#destroyApp(boolean) 
  37.      */  
  38.     protected void destroyApp(boolean arg0) throws MIDletStateChangeException {  
  39.         this.destroyApp(true);  
  40.     }  
  41.   
  42.     /*  
  43.      * @see javax.microedition.midlet.MIDlet#pauseApp() 
  44.      */  
  45.     protected void pauseApp() {  
  46.         // En este ejemplo no se requiere ninguna tarea cuando el MIDLet es pausado.  
  47.     }     
  48.   
  49. }  

  1. package autentia.tutoriales.wma;  
  2.   
  3. import java.io.*;  
  4. import javax.microedition.io.*;  
  5. import javax.microedition.lcdui.*;  
  6. import javax.wireless.messaging.*;  
  7.   
  8.   
  9.   
  10. /** 
  11.  * Ventana principal de la aplicación 
  12.  * @author Carlos García. Autentia 
  13.  */   
  14. public class WMAMainForm extends javax.microedition.lcdui.TextBox   
  15.             implements javax.microedition.lcdui.CommandListener {  
  16.       
  17.     /** 
  18.      * Referencia al MIDLet 
  19.      */  
  20.     private javax.microedition.midlet.MIDlet midlet;  
  21.       
  22.     /** 
  23.      * Envia el SMS 
  24.      */  
  25.     private javax.microedition.lcdui.Command cmdSend;  
  26.       
  27.     /** 
  28.      * Finaliza la aplicación 
  29.      */  
  30.     private javax.microedition.lcdui.Command cmdExit;  
  31.       
  32.     /** 
  33.      * Constructor 
  34.      * Ventana principal de la aplicación 
  35.      */  
  36.     public WMAMainForm(javax.microedition.midlet.MIDlet midlet) {  
  37.         super("Mensaje a enviar"""166, TextField.ANY);  
  38.         this.midlet = midlet;  
  39.           
  40.         this.createUI();  
  41.     }  
  42.   
  43.     /** 
  44.      * Crea y configura el interfaz gráfico de la ventana. 
  45.      */  
  46.     private void createUI(){  
  47.         this.setTicker(new Ticker("Autentia Real Business Solutions"));  
  48.         this.cmdSend = new Command("Enviar", Command.OK,   1);  
  49.         this.cmdExit   = new Command("Salir",  Command.STOP, 1);  
  50.           
  51.         this.addCommand(cmdSend);         
  52.         this.addCommand(cmdExit);  
  53.         this.setCommandListener(this);        
  54.     }  
  55.       
  56.       
  57.     /**  
  58.       * El usuario desea enviar el SMS  
  59.      */   
  60.     private void sendSMSClick() throws java.io.IOException {   
  61.         MessageConnection conn = null;   
  62.         TextMessage msg = null;   
  63.         try {   
  64.             // Paso 1: Obtenemos una implementación del Connection que se encargará de enviar el SMS   
  65.             conn = (MessageConnection) Connector.open("sms://+34699221570");   
  66.               
  67.             // Paso 2: Creamos el SMS   
  68.             msg = (TextMessage) conn.newMessage(MessageConnection.TEXT_MESSAGE);  
  69.   
  70.             // Paso 3: Establecemos el contenido del SMS   
  71.             msg.setPayloadText(this.getString());   
  72.               
  73.             // Paso 4: Enviamos el SMS   
  74.             conn.send(msg);   
  75.         } finally {   
  76.             // Paso 5: IMPORTANTE Cerramos la conexión   
  77.             this.closeQuietly(conn);   
  78.             conn = null;   
  79.         }   
  80.     }  
  81.   
  82.       /** 
  83.        * Cierra un Connection ignorando todas las posibles excepciones 
  84.        */  
  85.         private void closeQuietly(javax.microedition.io.Connection conn){  
  86.             try {  
  87.                 conn.close();  
  88.             } catch (Exception ex){  
  89.                 // Nada  
  90.             }  
  91.         }    
  92.           
  93.     /*  
  94.      * Receptor de eventos del UI (User Interface) 
  95.      * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable) 
  96.      */  
  97.     public void commandAction(Command arg0, Displayable arg1) {  
  98.         try {  
  99.             if (arg0 == cmdSend){  
  100.                 this.sendSMSClick();  
  101.             } else if (arg0 == cmdExit){  
  102.                 this.midlet.notifyDestroyed();  
  103.             }  
  104.         } catch (Exception ex){  
  105.             // En caso de error modificamos el texto de la ventana con el mensaje  
  106.             this.setString(ex.toString());  
  107.         }  
  108.     }  
  109. }  

Ejemplo 2. Envío de un SMS en modo binario.

Los pasos para enviar información en modo binario son los mismos que para el envio de SMS en modo texto.
Los mensajes binarios son representados bajo la clase javax.wireless.messaging.BinaryMessage. La principal diferencia entre esta clase y javax.wireless.messaging.TextMessage es el método para especificar el contenido del mensaje a enviar. En este último caso, el contenido es un array de bytes y es especificado a través del método setPayloadData.
  1. /** 
  2. * El usuario desea enviar el SMS en modo binario 
  3. */  
  4.   
  5. private void sendBinarySMSClick() throws java.io.IOException {  
  6.     MessageConnection conn = null;  
  7.     BinaryMessage msg = null;  
  8.     ByteArrayOutputStream bout = null;  
  9.       
  10.     try {  
  11.         // Paso 1: Obtenemos una implementación del Connection que se encargará de enviar el SMS   
  12.         conn = (javax.wireless.messaging.MessageConnection) Connector.open("sms://+34699221570");   
  13.           
  14.         // Paso 2: Creamos el SMS   
  15.         msg = (BinaryMessage) conn.newMessage(MessageConnection.BINARY_MESSAGE);  
  16.           
  17.         // Paso 3: Establecemos el contenido del SMS con algunos datos de prueba. Por ejemplo, datos de una persona.   
  18.         bout = new ByteArrayOutputStream();   
  19.         dout = new DataOutputStream(bout);   
  20.         dout.writeBoolean(true);  // ¿Soltero?   
  21.         dout.writeByte(55); // Edad   
  22.         dout.writeUTF("Madrid"); // Provincia de nacimiento   
  23.         dout.writeUTF("España"); // País.   
  24.         dout.writeLong(888883311L); // DNI   
  25.         msg.setPayloadData(bout.toByteArray());   
  26.           
  27.         // Paso 4: Enviamos el SMS   
  28.         conn.send(msg);   
  29.     } finally {   
  30.         // Paso 5: IMPORTANTE. Cerramos las objetos, liberando recursos   
  31.         this.closeQuietly(bout);   
  32.         this.closeQuietly(dout);   
  33.         this.closeQuietly(conn);   
  34.         dout = null;   
  35.         dout = null;   
  36.         conn = null;   
  37.     }   
  38. }  
  39.   
  40.    /** 
  41.     * Cierra un OutputStream ignorando todas las posibles excepciones 
  42.     */          
  43. private void closeQuietly(java.io.OutputStream out){  
  44.        try {  
  45.            out.close();  
  46.        } catch (Exception ex){  
  47.            // Nada  
  48.        }  
  49. }  
  50.          
  51.    /** 
  52.     * Cierra un Connection ignorando todas las posibles excepciones 
  53.     */  
  54. private void closeQuietly(javax.microedition.io.Connection conn){  
  55.        try {  
  56.            conn.close();  
  57.        } catch (Exception ex){  
  58.            // Nada  
  59.        }  
  60. }     

Introducción a Push Registry.

A partir de la especificación MIDP 2.0, se añadió una potente característica a la plataforma J2ME que consiste en que nuestras aplicaciones puedan ser iniciadas por eventos externos o temporizadores.
Por ejemplo, nuestra aplicación puede ser iniciada cuando reciba un SMS en un determinado puerto (identificador).

Información interesante

A continuación os presento una tabla con información relacionada con el juego número de SMS necesarios para enviar información.

Referencia:  http://java.sun.com/products/wma/index.jsp Por lo general los mensajes de texto se envian con el juego de caracteres del GSM-7 bit, y sólo cuando el mensaje tiene caracteres que no pueden ser codificados con ese juego de caracteres se usará el UCS-2.

Conclusiones y reflexiones

En comparación con otros, este API es bastante simple y fácil de utilizar.
Sabiendo utilizar esta y otras tecnologías como las que os presentamos en Autentia a través de nuestros tutoriales, se pueden hacer sistemas interesantes y útiles.
No olvideis que esto es sólo una introducción, asi que si necesitais más información debeis dirigiros a las páginas oficiales de la especificación.
Espero que os haya parecido interesante este tutorial.

Ejemplo de conexión de JavaME con periférico por puerto serial/USB

Todos los equipos Nextel con Java ME tienen la capacidad de establecer una conexión de datos por el puerto serial o mini USB desde una aplicación Java.
En la terminal receptora, es simplemente necesario poder detectar al equipo conectado como si fuese un modem.
Es muy sencillo. El código adjunto ofrece un ejemplo.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.Connector;
import javax.microedition.io.CommConnection;
import java.io.IOException;
import java.io.DataOutputStream; public class SocketTest extends MIDlet implements CommandListener {
    private boolean midletPaused = false;
    private Command exitCommand;
    private Command okCommand;
    private Form form;
    private StringItem stringItem;
    /**
     * The SocketTest constructor.
     */

    public SocketTest() {
    }
    /**
     * Initilizes the application.
     * It is called only once when the MIDlet is started. The method is called before the startMIDlet method.
     */

    private void initialize() {
    }
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Started point.
     */

    public void startMIDlet() {
        switchDisplayable(null, getForm());
    }
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Resumed point.
     */

    public void resumeMIDlet() {
    }
    /**
     * Switches a current displayable in a display. The display  instance is taken from  getDisplay method. This method is used by all actions in the design for switching displayable.
     * @param alert the Alert which is temporarily set to the display; if null, then nextDisplayable is set immediately
     * @param nextDisplayable the Displayable to be set
     */

    public void switchDisplayable(Alert alert, Displayable nextDisplayable) {
        Display display = getDisplay();
        if (alert == null) {
            display.setCurrent(nextDisplayable);
        } else {
            display.setCurrent(alert, nextDisplayable);
        }
    }
    /**
     * Called by a system to indicated that a command has been invoked on a particular displayable.
     * @param command the Command that was invoked
     * @param displayable the Displayable where the command was invoked
     */

    public void commandAction(Command command, Displayable displayable) {
        if (displayable == form) {
            if (command == exitCommand) {
                exitMIDlet();
            } else if (command == okCommand) {
                openSocketConnection();
            }
        }
    }
    /**
     * Returns an initiliazed instance of exitCommand component.
     * @return the initialized component instance
     */

    public Command getExitCommand() {
        if (exitCommand == null) {
            exitCommand = new Command("Exit", Command.EXIT, 0);
        }
        return exitCommand;
    }
    /**
     * Returns an initiliazed instance of form component.
     * @return the initialized component instance
     */

    public Form getForm() {
        if (form == null) {
            form = new Form("Prueba", new Item[] { getStringItem() });
            form.addCommand(getExitCommand());
            form.addCommand(getOkCommand());
            form.setCommandListener(this);
        }
        return form;
    }
    /**
     * Returns an initiliazed instance of stringItem component.
     * @return the initialized component instance
     */

    public StringItem getStringItem() {
        if (stringItem == null) {
            stringItem = new StringItem("Prueba", "Prueba conexion serial");
        }
        return stringItem;
    }
    /**
     * Returns an initiliazed instance of okCommand component.
     * @return the initialized component instance
     */

    public Command getOkCommand() {
        if (okCommand == null) {
            okCommand = new Command("Ok", Command.OK, 0);
        }
        return okCommand;
    }
    /**
     * Returns a display instance.
     * @return the display instance.
     */

    public Display getDisplay () {
        return Display.getDisplay(this);
    }
    /**
     * Exits MIDlet.
     */

    public void exitMIDlet() {
        switchDisplayable (null, null);
        destroyApp(true);
        notifyDestroyed();
    }
    /**
     * Called when MIDlet is started.
     * Checks whether the MIDlet have been already started and initialize/starts or resumes the MIDlet.
     */

    public void startApp() {
        if (midletPaused) {
            resumeMIDlet ();
        } else {
            initialize ();
            startMIDlet ();
        }
        midletPaused = false;
    }
    /**
     * Called when MIDlet is paused.
     */

    public void pauseApp() {
        midletPaused = true;
    }
    /**
     * Called to signal the MIDlet to terminate.
     * @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.
     */

    public void destroyApp(boolean unconditional) {
    }
    public void openSocketConnection() {
        try {
        CommConnection cc = (CommConnection)Connector.open("comm:com0;baudrate=19200");
        DataOutputStream dos = cc.openDataOutputStream();
        dos.writeChars("Sample output");
        dos.flush();
        cc.close();
        }
        catch (IOException ex){
            Alert alert = new Alert("Exception: ", ex.getMessage() ,null,AlertType.ERROR);
            switchDisplayable(alert,getDisplay().getCurrent());
        }
    }
}

Usabilidad para PDA Parte III Final

3 - Consistencia y Usabilidad

Aunque como objetivo general el término consistencia hace referencia a secuencia de acciones, términos, unidades, colores o tipografía comunes dentro de un mismo programa de aplicación o un mismo escenario, la consistencia no tiene significado en sí misma, es inherentemente un concepto relacional.
Del mismo modo que la consistencia se presenta como uno de los factores más críticos, su no ausencia o los errores derivados de su mala administración se convierten en uno de los grandes problemas a resolver en los desarrollos de soluciones.
Por medio de la aparición de esta tipología de problemas, los usuarios quedarán desorientados o serán incapaces de navegar con fluidez por las distintas fases de los procesos planteados en las herramientas que se apliquen.
La única manera de afrontar este tipo de situaciones es desde una estrategia global que planifique dicha consistencia desde antes de iniciar el desarrollo y que sea capaz de articular acciones que permitan solventar aquellos errores propios del desarrollo. Y en el campo de la Experiencia del Usuario, este es el campo de la Arquitectura de la Información. Desde la AI será posible desde prototipar todos los elementos que estarán presentes en la aplicación a desarrollar y ver la interacción de todos ellos con el propósito de las tareas planteadas.
Wendy Kellogg sugiere dos vertientes distintas sobre la consistencia, que son perfectamente aplicables al mundo PDA:
    • Consistencia descriptiva – son las propiedades para las que la interfaz de la aplicación
    es elaborada las que determinan su consistencia o no.
    • Consistencia evaluativo – es el uso que se le va a dar al desarrollo el que acabará
    aportando las bases para determinar la consistencia de la interfaz.
En el caso del diseño de aplicaciones para PDA, podría determinarse que la consistencia descriptiva queda escalonada en dos niveles. El primero de ellos trataría cuestiones sobre apariencia estética o comportamientos, y el segundo sobre efectividad de uso.
Recomendaciones 
    • Es crítico tener en cuenta que en un entorno PDA, nunca hay que forzar al usuario a que suponga o adivine que palabras, situaciones o acciones distintas significan una misma cosa. Es imprescindible, seguir recomendaciones estipuladas y extendidas ampliamente para plataformas móviles.
    • Es muy recomendable utilizar experiencias que sitúen al usuario dentro de su entorno cotidiano. Ello implica el conservar la consistencia de los modelos mentales utilizados, colores, iconos, etc.
    • Desde el punto de vista de la usabilidad, la aplicación desarrollada, debería tener apariencia similar y comportarse de manera similar a otros productos o aplicaciones que el usuario utilice habitualmente. De este modo, su tránsito al terminal móvil será menos traumático. En este caso, es recomendable utilizar la mayoría de los estándares que entornos como Symbian o Windows tienen en sus aplicaciones. En ocasiones,   reinventar la rueda tiene más pegas que beneficios.
    • Durante las distintas fases de la aplicación, es crítico mantener referencias claras en el ‘look & feel’. Ello tiene una relevancia crítica especialmente en cuestiones de navegación. En este sentido, tanto la ubicación como la manera de accionarse los mecanismos de navegación han de permanecer consistentes en todas las fases disponibles.
    • Aplique la consistencia igualmente tanto al lenguaje o a la ubicación de los botones de navegación (‘Guardar’, ‘Siguiente’, ‘Salir’, …). En este caso, no existe problema alguno en repetir tanto ubicaciones como terminología, ya que ello, proporciona consistencia a la aplicación y refuerza la sensación de ‘ubicación’ capacitando al usuario la creación de rutas o pautas de actuación memorizadas. En estos entornos más que en cualquier otro, cobra especial relevancia la máxima ‘reconocer y recordar antes que identificar’.
    • Es muy recomendable proporcionar la documentación referente a los estándares sobre UI utilizados, poniendo especial énfasis al desarrollo que se ha respetado en la disposición de elementos en pantalla, tipografía, etiquetado, colores, tamaño de las fuentes, etc. Es imprescindible que dichos desarrollos sean realizados acorde a estándares internacionales.

Usabilidad para PDA Parte II

2 - Conociendo a los usuarios de aplicaciones móviles

El usuario: es la pieza fundamental por la que hay que comenzar todo diseño de aplicaciones. En el caso que nos ocupa, el usuario de aplicaciones móviles posee y demanda una serie de características particulares, pues el uso de este tipo de terminales le dotan de unas determinadas idiosincrasias muy particulares y no presentes en ningún otro entorno telemático.
Del mismo modo, este tipo de terminales poseen un tipo de limitaciones que no van a ser solventadas a corto plazo. De modo que es imprescindible tener en cuenta estos dos entornos a la hora de establecer recomendaciones de usabilidad.

A la hora de plantear las recomendaciones de usabilidad hacia PDAs, se puede hacer desde tres puntos distintos:

   • Teniendo en cuenta al usuario.
   • Teniendo en cuenta la interacción usuario - máquina.
   • Teniendo en cuenta aquellos aspectos específicos de la máquina

Estas vienen marcadas de la siguiente manera:

Sobre los usuarios

• Los usuarios de aplicaciones móviles se desenvuelven en entornos donde van a estar expuestos a multitud de estímulos simultáneos fuera de la aplicación. La gran diferencia con respecto a entornos telemáticos tradicionales es que la atención del usuario va a estar influida en gran medida por el entorno. Tradicionalmente, esta interacción se había dado en entornos más o menos silenciosos, en los que el usuario se disponía a llevar a cabo esa interacción cómodamente sentado y pudiendo destinar grandes cantidades de atención a las tareas a acometer. No obstante, la propia idiosincrasia de los dispositivos móviles hace que la mayor parte de las acciones que se lleven a cabo con ellos se llevarán a cabo en todos aquellos momentos en los que el usuario NO esté en presencia de dicho entornos de reposo. Dichos momentos, van a estar marcados en general por multitareas, como por ejemplo, consultar el correo electrónico mientras existe un desplazamiento de un lugar a otro, a puntar una cita en el calendario en mitad de una conversación.
Por consiguiente, los productos destinados a dispositivos móviles han de tener en cuenta estas circunstancias y crear aplicaciones que sean sencillas, de navegación extremadamente simple y cuyos objetivos sean fácilmente alcanzables con la mínima carga cognitiva.

• Debido a que la mayoría de las ocasiones en las que se utiliza el dispositivo móvil van a implicar entornos cambiantes o, al menos, abiertos, un factor a tener muy en cuenta es la luminancia que sufrirá la interfaz inicial. Esta sufrirá variaciones drásticas incluso en escasos periodos de tiempo imposibilitando la fijación de la atención en tareas largas o que requieran una atención excesiva. Como el entorno es algo incontrolable dentro del mundo móvil, la única manera de atacar dicho problema es mejorando al máximo las capacidades del terminal que va a contener nuestro producto. En ese sentido, los dispositivos de la serie HP Rx, o modelos similares al Acer n50 proporcionan unas excelentes prestaciones que disminuyen este factor en gran medida.
Ejemplo de reflejos en la pantalla debido a los problemas de luminancia
Imagen 1: Ejemplo de reflejos en la pantalla
debido a los problemas de luminancia.

• En el caso de que sea necesario, aplique técnicas de internacionalización y localización a fin de acomodar los entornos que cree a las distintas culturas que puedan actuar potencialmente con el desarrollo que usted está llevando a cabo.

• Es crítico saber el tipo de población a la que el programa va ir destinado. Diversos usuario sutilizando un mismo entorno, pueden provocar grandes inconvenientes, en tanto en cuanto su manera de interactuar varía. Por ese motivo, es recomendable hacer los desarrollos de software lo más estándares posible, sin particularizar hacia poblaciones específicas. De este modo, aquellos que deseen un excesivo detalle y personalización en sus entornos, si están estandarizados encontrarán estos sencillos de uso y aquellos usuarios que no tengan (o no quieran tener) ningún tipo de pericia en el uso de este tipo de entornos, encontrarán agradable el realizar las tareas requeridas.

Sobre la interacción Usuario - Máquina

• Debido a que la movilidad es el aspecto que va a imperar en el desarrollo, existe un factor determinante para el terminal: su reducido tamaño. Desde el punto de vista de la Usabilidad ello va a generar consecuencias críticas a tener en cuenta, como puede ser el reducido tamaño de la pantalla, por ejemplo. Por ese motivo, la simplificación de la terminología, la asignación de extrema relevancia a la información icónica o la elección de iconos auto-explicativos son pilares fundamentales sobre los que planificar el diseño y estructura de la interfaz.

• Adicionalmente al punto anterior, la interactividad que el usuario va a tener con el terminal va a ser reducida, ya que, en la mayoría de los casos, lo va a sostener con una mano y con la otra va a sostener un puntero por medio del cual interactuará con la interfaz. Por ese modo, la versatilidad de movimientos va quedar reducida en gran medida.

Reducida capacidad de movimientos debido a el uso de una sola mano
Imagen 2: Reducida capacidad de movimientos debido al uso de una sola mano.

• Otro aspecto a tener en cuenta y que también se encuentra ligado a este punto es que debido a que estamos hablando de terminales que se utilizan con una sola mano y que, generalmente, quedan alineados visualmente hacia el lado de la mano que está sosteniendo dicho terminal, la percepción de los elementos de la interfaz será distinta si es observada por un usuario diestro o por un usuario zurdo. Especialmente, esto es crítico en usuarios zurdos, pues estos, asimilando la manera de coger el bastón como suelen hacerlo con los bolígrafos cuando escriben, en muchos casos adoptarán una posición de pinza, la cual, al interactuar con la interfaz y realizar desplazamientos, puede provocar frecuentes bloqueos visuales de elementos de la interfaz. La mano de este modo, taparía parte de la pantalla, dificultando el uso y la efectividad de las acciones realizadas.

• Mientras que seleccionar opciones de la pantalla con el puntero del ratón de un ordenador de sobremesa viene a ser algo sencillo y fácilmente adquirible como destreza, emular las mismas actuaciones en el mundo de las PDAs es algo mucho más complicado. La destreza de los usuarios a la hora de lograr un impacto con un bastón de PDA en un determinado punto de la pantalla es ostensiblemente inferior a la que logran ejecutando la misma tarea con un puntero de ratón en un ordenador de sobremesa. Ello, queda agravado por el hecho de que muchos usuarios tienden a utilizar sustitutos del bastón si este se ha extraviado. De modo que reemplazan dicho elemento de navegación por bolígrafos, palillos, lapiceros, etc…

Sobre la máquina

• Si bien los ordenadores personales se han convertido en herramientas cotidianas del entrono profesional y doméstico, las PDAs aún no han alcanzado ese estatus. Por ese motivo no se les ‘perdonan’ ciertos fallos que si bien están presentes en los terminales de sobremesa, pueden provocar el desuso o el abandono de la PDA. Por ello, es imprescindible desarrollar las aplicaciones y los terminales para que presenten los mínimos inconvenientes posibles.

• Minimice todo lo que pueda las interacciones que deba hacer el usuario con el terminal. Ello, se ha de hacer partiendo de la base que la pantalla es de reducidas dimensiones, que solo podrá interactuar con una mano, sosteniendo un bastón (el cual no les es familiar y, a veces, ni siquiera cómo), que lo hará en movimiento y que el entorno presentará gran cantidad de estímulos distractores. En consecuencia, las acciones, o navegaciones deben disponer de un ratio máximo de ‘clicks’ de tres o cuatro.

• Aquellas tareas no necesariamente relacionadas con la interfaz o con el producto de software en sí, han de ser igualmente minimizadas. De este modo, se ha de buscar una simplicidad casi infantil en tareas tales como establecer conexiones WIFI, sincronizar los datos e informaciones de los ordenadores de sobremesa con la información contenida en la PDA o las actualizaciones de software requeridas por parte de los paquetes de software contenidos en las PDAs.
Fácil acceso a las tareas de la PDA por medio de menús sencillo
Imagen 3: Acceso fácil a las tareas de la PDA
por medio de menús sencillos.

 

Usabilidad para PDA Parte I

1 - Principios generales de Usabilidad

La actualidad impone un ritmo vertiginoso. La actividad normal a la que las personas se ven sometidas les implica un desplazamiento constante y una mayor conectividad, independientemente del entrono en el que se encuentre. De este modo, el concepto de aplicaciones estáticas diseñadas para entornos estáticos se ha convertido a todas luces en un lastre ineficaz que, poco a poco está siendo superado.  
Por este motivo, el usuario se ha dotado de un conjunto de dispositivos que le han facultado para continuar con su actividad en cualquier momento, en cualquier sitio y sin sufrir mermas operativas por ello.

Dentro del mundo de los dispositivos móviles, la extensa gama existente nos hace diferenciar entornos muy variados. No es equiparable un producto desarrollado para un teléfono móvil que para un Pocket PC (en adelante PDA, -del inglés Personal Digital Assistant-). Sin embargo, es tal la vertiginosa carrera que están emprendiendo los fabricantes de dispositivos que sus productos están cubriendo en escaso tiempo la mayor parte de las necesidades que al usuario se le pueden plantear en su uso normal del dispositivo. De este modo, la aparición de teléfonos móviles híbridos cuenta ya con una presencia extendida dentro del mundo empresarial, aportando versatilidad y aglutinando multifunciones en un solo dispositivo. Ello ha provocado que incuso dentro del campo de desarrollo de aplicaciones para teléfonos móviles, los desarrolladores comiencen a verse condicionados por el tipo de terminal para el que va destinado el desarrollo. Por consiguiente, desarrollar aplicaciones, productos o juegos para un terminal
Nokia 6630, por ejemplo, no tiene gran relación con desarrollar para un Sony-Ericsson 750i. Del mismo modo, desarrollar aplicaciones para un Nokia 9300 no puede ser equiparado con desarrollar para una LOOX 700.
Xda II