Ir a contenido principal

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

La primera vez que se registra en developerWorks, se crea un perfil para usted. Información sobre su perfil (nombre, país/región y compañia) estará disponible al público y acompañará cualquiera de sus publicaciones. Puede actualizar su cuenta IBM en cualquier momento.

Toda la información enviada es segura.

  • Cerrar [x]

La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

Toda la información enviada es segura.

  • Cerrar [x]

Desarrollo de interfaces dinámicas de usuario con Android y XML

Recolección de datos mediante el motor de formularios de Android

Después de que terminara su carrera basquetbolista colegial sin un contrato multianual para jugar para los Lakers de Los Ángeles, Frank Ableson cambió su enfoque hacia el diseño de software informático. Disfruta solucionando problemas complejos, particularmente en las áreas de comunicaciones e interfaces de hardware. Cuando no está trabajando, está pasando el tiempo con su esposa Nikki y sus hijos. Es posible contactar a Frank escribiendo a frank@cfgsolutions.com.

Resumen:  Un número de sitios web atienden a organizaciones no lucrativas que proporcionan formularios de fácil configuración y que son utilizados para realizar sondeos y recolectar datos. Este tutorial introduce una arquitectura simple para diseñar aplicaciones similares para interfaces dinámicas de usuarios de Android que permiten a quienes no son programadores recolectar datos de usuarios de dispositivos móviles. Con este tutorial podrá crear un ejemplo de un motor de formularios, tanto con un servidor como con un dispositivo móvil.

Fecha:  25-02-2013
Nivel:  Intermediaria PDF:  A4 and Letter (1227 KB | 43 páginas)Get Adobe® Reader®

Actividad:  5145 vistas

El proyecto y el modelo de datos

Ahora estamos listos para empezar el proyecto de Android en Eclipse, crear el modelo de datos y la clase que le permitirá almacenar y gestionar los metadatos para la aplicación Forms Engine.

Creación del proyecto

La creación de una aplicación de Android comienza en un lugar conocido: Abra Eclipse y seleccione File > New como se muestra en la Figura 3.


Figura 3. Creación de una nueva aplicación de Android
Screen capture of creating a new Android application

Este paso inicia el asistente para nuevos proyectos de Eclipse. Seleccione Android Project (el entorno de Java especializado para Android). Asegúrese de darle al proyecto un identificador válido (yo utilicé XMLGUI). Para que la solución coincida con la solución que se describe en este tutorial, debajo de Properties, especifique XML GUI como nombre de la aplicación y com.msi.ibm como nombre del paquete. Seleccione la casilla de verificación Create Activity y especifique XmlGui para el nombre de la actividad como se muestra en la Figura 4.


Figura 4. Configuración de un nuevo proyecto
Screen capture of setting up a new project

Una vez que haya creado el proyecto, este debe verse similar a la imagen que se muestra en la Figura 5. (Vea una versión solo textual de la Figura 5).


Figura 5. Proyecto de Android finalizado directamente desde el asistente para nuevos proyectos
Android project directly upon completion of the new project wizard

Ahora que hemos creado el proyecto, es una buena práctica comprobar que la aplicación funciona en forma segura y limpia en el emulador Android. Observe que a veces las la aplicación no se desarrolla hasta que edite y guarde el archivo de origen de Java. Esto ocasiona que las herramientas de Android SDK generen automáticamente los archivos en la carpeta gen. Esto causa que Android SDK generen automáticamente los archivos en la carpeta gen. Puede probar la aplicación si no hay entradas en la pestaña Problems o en el entorno de Eclipse.

Para probar la aplicación, cree una Configuración de ejecución como se muestra en la Figura 6. En la lista Android Application, seleccione XmlGui. Compruebe que los siguientes valores estén presentes: XmlGui en el campo Name, XMLGUI en el campo Project y com.msi.ibm.XmlGui en el campo Launch. Haga clic en Run.


Figura 6. Ejecución de la configuración de ejecución
Run Configuration setup

Ahora que el proyecto está creado, configurado y se inicia correctamente en el emulador de Android, es tiempo de crear la herramienta de recolección de datos impulsada por XML para Android.


El modelo de datos

Los elementos constitutivos de esta aplicación requieren que presente elementos de entrada para un usuario, recolecte los datos, los valide y a continuación los envíe a una ubicación específica en el servidor. Cabe señalar que esta aplicación está configurada solo para nuevos registros. No existen disposiciones para buscar un registro existente para editarlo o eliminarlo.

Para guiar la aplicación lo suficiente sobre cómo presentar los formularios de entrada de datos, se requiere un conjunto de información (conocido comúnmente como metadatos). Los metadatos son los datos sobre los datos. En términos generales, esta aplicación debe entender los siguientes elementos de datos:

  • Nombre de formulario— Nombre del formulario en lectura humana directa
  • Identificador de formulario— Identificador único para esta recolección de metadatos
  • URL de envío— El lugar al que se deben enviar los datos recolectados
  • Uno o más campos— Estos pueden ser de texto, numéricos o se pueden seleccionar de una lista de campos

Virtualmente, todos los tipos de preguntas conducen a unos de estos tres tipos de elementos de interfaz de usuario. Por ejemplo, puede implementar una casilla de verificación como un campo de elección por Sí o por No. Puede implementar una selección múltiple como campos de selección múltiple Naturalmente, es posible extender el código que se muestra en este tutorial según lo desee.

Para su aplicación, el escenario de uso es el siguiente: Se encuentra en un evento en el que se puede inscribir para una o más actividades. Puede completar una hoja de papel o puede esperar hasta que llegue a su casa y confíe en que recordará inscribirse en el sitio web de la organización para participar. En este caso, asumirá que el usuario completará un formulario simple en el momento desde su teléfono al utilizar una aplicación dinámica en un dispositivo Android, en la que proporcionará el nombre, apellido, sexo y edad del participante.

El Listado 1 muestra los contenidos de xmlgui1.xml, que representa el formulario de registro para un evento de club de Robotics.


Listado 1. xmlgui1.xml

<?xml version="1.0" encoding="utf-8"?>
<xmlgui>
<form id="1" name="Robotics Club Registration" 
   submitTo="http://serverurl/xmlgui1-post.php" >
<field name="fname" label="First Name" type="text" required="Y" options=""/>
<field name="lname" label="Last Name" type="text" required="Y" options=""/>
<field name="gender" label="Gender" type="choice" required="Y" options="Male|Female"/>
<field name="age" label="Age on 15 Oct. 2010" type="numeric" required="N" options=""/>
</form>
</xmlgui>

Observe los siguientes aspectos sobre este documento XML:

  • El XML es muy simple de analizar gracias a su uso extensivo de atributos de elementos. Este abordaje es utilizado ya que permite que la extracción de datos sea fácil que la extracción de elementos secundarios y etiquetas múltiples. El uso de atributos de esta manera también mantiene el tamaño de descarga reducido y contribuye a mantener el tiempo de análisis bajo.
  • El atributo submitTo le indica a la aplicación el lugar al que debe enviar los datos una vez que hayan sido recolectados.
  • Cada elemento field proporciona atributos para el nombre del campo y para la etiqueta. Mientras estos valores estén relacionados, conserve el valor de cada atributo name como único en relación con los demás valores de name para que la aplicación receptora pueda analizarlos y procesarlos correctamente. También debe suministrar un valor label informativo para el usuario como una indicación sobre qué clase de datos debe ir en ese campo en particular.
  • Puede aumentar el alcance de este abordaje para incluir los valores predeterminados de campo, una expresión regex para validación o un enlace para obtener más información sobre un campo determinado.
  • El campo options se utiliza como una lista delimitada para el campo choice.

Ahora que poseemos una familiaridad básica con el modelo de datos, observemos el código responsable para convertir estos datos XML en una aplicación útil.


Representación de datos

El análisis de datos es un ejercicio algo mecánico que se muestra más adelante en este tutorial. Antes de examinar el proceso de análisis, la aplicación necesita lugar para almacenar y gestionar los metadatos en la memoria. Para este fin, existen dos clases de Java a su alcance, una para el formulario y otra para representar el campo del formulario. Comience observando XmlGuiForm.java en el Listado 2.


Listado 2. XmlGuiForm.java

package com.msi.ibm;
import java.util.Vector;
import java.util.ListIterator;
import java.net.URLEncoder;

public class XmlGuiForm {

   private String formNumber;
   private String formName;
   private String submitTo;
   public Vector<XmlGuiFormField> fields;


   public XmlGuiForm()
   {
      this.fields = new Vector<XmlGuiFormField>();
      formNumber = "";
      formName = "";
      submitTo = "loopback"; // do nothing but display the results
   }
   // getters & setters
   public String getFormNumber() {
      return formNumber;
   }

   public void setFormNumber(String formNumber) {
      this.formNumber = formNumber;
   }


   public String getFormName() {
      return formName;
   }
   public void setFormName(String formName) {
      this.formName = formName;
   }

   public String getSubmitTo() {
      return submitTo;
   }

   public void setSubmitTo(String submitTo) {
      this.submitTo = submitTo;
   }

   public Vector<XmlGuiFormField> getFields() {
      return fields;
   }

   public void setFields(Vector<XmlGuiFormField> fields) {
      this.fields = fields;
   }

   public String toString()
   {
      StringBuilder sb = new StringBuilder();
      sb.append("XmlGuiForm:\n");
      sb.append("Form Number: " + this.formNumber + "\n");
      sb.append("Form Name: " + this.formName + "\n");
      sb.append("Submit To: " + this.submitTo + "\n");
      if (this.fields == null) return sb.toString();
      ListIterator<XmlGuiFormField> li = this.fields.listIterator();
      while (li.hasNext()) {
         sb.append(li.next().toString());
      }
   
      return sb.toString();
   }

   public String getFormattedResults()
   {
      StringBuilder sb = new StringBuilder();
      sb.append("Results:\n");
      if (this.fields == null) return sb.toString();
      ListIterator<XmlGuiFormField> li = this.fields.listIterator();
      while (li.hasNext()) {
         sb.append(li.next().getFormattedResult() + "\n");
      }

      return sb.toString();
   }

   public String getFormEncodedData()
   {
      try {
      int i = 0;
      StringBuilder sb = new StringBuilder();
      sb.append("Results:\n");
      if (this.fields == null) return sb.toString();
      ListIterator<XmlGuiFormField> li = this.fields.listIterator();
      while (li.hasNext()) {
         if (i != 0) sb.append("&");
         XmlGuiFormField thisField = li.next();
         sb.append(thisField.name + "=");
         String encstring = new String();
         URLEncoder.encode((String) thisField.getData(),encstring);
         sb.append(encstring);
      }

      return sb.toString();
      }
      catch (Exception e) {
         return "ErrorEncoding";
      }
   }
}

Aquí hay unos elementos importantes que observar sobre la clase XmlGuiForm.

  1. Hay cuatro variables de miembro:
    • formNumber: Este es el único identificador para el mecanismo de distribución del formulario del lado del servidor.
    • formName: Este atributo se convierte en el título del formulario, el cual provee el contexto y la confirmación para el usuario.
    • submitTo: Esta es la URL para la aplicación para enviar los datos que se introdujeron (después de haberlos validado). Este valor también puede ser un valor de retorno. En el caso de un bucle de retorno, los datos se muestran al usuario en lugar de ser enviados al servidor. Esto es de gran utilidad para fines de prueba.
    • fields: Este es una clase de vector en plantilla para mantener los datos del campo del formulario. El Listado 3 muestra los detalles para XmlGuiFormField.java.
  2. Una serie de getters y setters para cada una de estas variables.
  3. Los métodos toString() y getFormattedResults() son los responsables de generar resúmenes para lectura humana directa de la clase XmlGuiForm.
  4. El método getFormEncodedData() es utilizado al preparar los datos para enviarlos a la URL indicada en el atributo submitTo.
  5. En lugar de utilizar clases java.lang.String estrictamente concatenadas, el código emplea un StringBuilder como un medio de memoria más eficiente para construir las cadenas de datos deseadas.
  6. La clase URLEncoder es aprovechada para preparar los datos para enviarlos al servidor. Esto hace que los datos se vean como se crearon realmente mediante un formulario HTML tradicional.
  7. Algunas expansiones potenciales de esta aplicación incluyen:
    • Almacenamiento local o en caché de los metadatos para hacer que las tareas repetitivas se ejecuten más rápido.
    • Almacenamiento local para registrar los datos durante un período de tiempo antes de enviarlos.
    • Registro— de fecha y hora por GPS en cada registro con datos de ubicación.

Ahora observemos la construcción de la clase XmlGuiFormField en el Listado 3.


Listado 3. XmlGuiFormField.java

package com.msi.ibm;
// class to handle each individual form
public class XmlGuiFormField {
   String name;
   String label;
   String type;
   boolean required;
   String options;
   Object obj;   // holds the ui implementation
                   // or the EditText for example


   // getters & setters
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getLabel() {
      return label;
   }
   public void setLabel(String label) {
      this.label = label;
   }
   public String getType() {
      return type;
   }
   public void setType(String type) {
      this.type = type;
   }
   public boolean isRequired() {
      return required;
   }
   public void setRequired(boolean required) {
      this.required = required;
   }
   public String getOptions() {
      return options;
   }
   public void setOptions(String options) {
      this.options = options;
   }

   public String toString()
   {
      StringBuilder sb = new StringBuilder();
      sb.append("Field Name: " + this.name + "\n");
      sb.append("Field Label: " + this.label + "\n");
      sb.append("Field Type: " + this.type + "\n");
      sb.append("Required? : " + this.required + "\n");
      sb.append("Options : " + this.options + "\n");
      sb.append("Value : " + (String) this.getData() + "\n");

      return sb.toString();
   }
   public String getFormattedResult()
   {
      return this.name + "= [" + (String) this.getData() + "]";

   }

   public Object getData()
   {
      if (type.equals("text") || type.equals("numeric"))
      {
         if (obj != null) {
            XmlGuiEditBox b = (XmlGuiEditBox) obj;
            return b.getValue();
         }
      }
      if (type.equals("choice")) {
         if (obj != null) {
            XmlGuiPickOne po = (XmlGuiPickOne) obj;
            return po.getValue();
         }
      }

      // You could add logic for other UI elements here
      return null;
   }

}

Observe con mayor detenimiento la clase XmlGuiFormField.

  • Hay seis miembros de nivel de clase:
    1. name contiene el nombre del campo— este es el nombre del campo del valor de los datos, análogo al nombre del campo de un formulario en HTML o el nombre de columna de base de datos.
    2. label contiene una descripción del campo o el valor que se muestra al usuario.
    3. type indica el tipo de campo de la interfaz de usuario que se desea construir.
      • text significa que este campo se implementa con un campo EditText para entradas alfanuméricas. Este es el valor más común.
      • numeric también es un valor EditText, pero solo está limitado a un valor de entrada numérica.
      • choice hace que el campo sea una lista desplegable.
    4. required es un valor booleano que marca el campo como requerido o no. Si el campo se requiere pero no se completa, se muestra un mensaje de error al usuario cuando este intenta enviar el formulario.
    5. options es un valor de cadena utilizado para transmitir la lista de selecciones disponibles para un campo de elección. Este campo está disponible para otros campos para ser utilizado quizás como una expresión regex para validación o puede ser sustituido para especificar un valor predeterminado.
    6. obj representa el widget de la interfaz de usuario. Por ejemplo, esta variable contiene un EditText para un campo numérico o de texto. Para un campo de elección, el miembro obj contiene un widget spinner. Este abordaje se explica con mayor detalle más adelante en este tutorial.
  • Como se preveía, estas variables tienen un número de getters y setters.
  • Los métodos toString() y getFormattedResult() aprovechan el método getData() que se explica a continuación.
  • En la clase XmlGuiFormField, es necesario gestionar más de un tipo de datos por lo que el código necesita ser explícito sobre cómo almacenar y acceder a los datos. El método getData() examina el tipo de cambio y realiza una conversión de tipo en el campo obj para interactuar correctamente con el objeto almacenado. Si desea agregar nuevos tipos de campos a esta a infraestructura, puede expandir el método getData() para que este sea compatible con el nuevo tipo de campo (vea el comentario cerca del final del Listado 3.

Ahora posee un método para almacenar y gestionar los metadatos. Es tiempo de ver a la aplicación en acción y después comenzar a atar las piezas entre sí.

4 de 12 | Anterior | Siguiente

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Desarrollo móvil, Industries
ArticleID=859240
TutorialTitle=Desarrollo de interfaces dinámicas de usuario con Android y XML
publish-date=02252013
author1-email=frank@cfgsolutions.com
author1-email-cc=