scieee AI-readable full text Open interactive document viewer

Diseño e implementación de una aplicación domótica en Android reconfigurable a partir de un XML

Cano Calabuig, Raúl

Full text

UNIVERSIDAD POLITÉCNICA DE VALENCIA ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA Proyecto Fin de Carrera Diseño e implementación de una aplicación domótica en Android reconfigurable a partir de un XML Autor: Raúl Cano Calabuig Director: Ismael Torres Diciembre 2010 2 A mis Padres, amigos y Maribel 3 Agradecimientos Quiero mostrar mi agradecimiento a todas las personas que han hecho posible este proyecto. En primer lugar al personal del el Grupo de sistemas pervasivos del centro de investigación en métodos de producción de software (ProS) de la UPV, cuya colaboración ha resultado facilitadora en la elaboración de este trabajo. En segundo lugar agradecer su colaboración y disposición a mi director de proyecto Ismael Torres y Nacho Mansanet por todo el apoyo en la realización de este proyecto de final de carrera. Finalmente agradecer a todas las personas que han estado ahí durante todo el tiempo dedicado a este proyecto, especialmente a mi familia y a mis amigos, que me han apoyado en todo momento. 4 5 Índice de Contenido 1. INTRODUCCIÓN .................................................................................................................... 9 1.1. MOTIVACIÓN .......................................................................................................................... 9 1.2. OBJETIVOS DEL PROYECTO ........................................................................................................ 10 1.3. ESTRUCTURA DE LA MEMORIA ................................................................................................... 11 2. PROPUESTA DE APLICACIÓN ............................................................................................... 13 2.1. OBJETIVO DE LA APLICACIÓN ..................................................................................................... 13 2.2. LÍNEAS DE INVESTIGACIÓN ........................................................................................................ 14 2.2.1. Desarrollo de aplicaciones en Android ....................................................................... 14 2.2.2. Procesado de un documento XML ............................................................................. 15 2.3. CONTEXTO TECNOLÓGICO ........................................................................................................ 16 2.3.1. Android ...................................................................................................................... 16 2.3.2. XML (Extensible Markup Language) .......................................................................... 21 3. DESCRIPCIÓN DEL ESCENARIO Y ENTRADA DE DATOS ........................................................ 22 3.1. ESTRUCTURA DEL ESCENARIO UTILIZADO ..................................................................................... 22 3.2. GESTIÓN Y PROCESADO DEL ESCENARIO ...................................................................................... 23 3.2.1. Presentación del escenario ........................................................................................ 23 3.2.2. Estructura e implementación de las clases necesarias .............................................. 25 3.2.3. Procesado del escenario ............................................................................................ 27 4. ARQUITECTURA DE LA APLICACIÓN .................................................................................... 33 4.1. ARQUITECTURA POR CAPAS ...................................................................................................... 33 4.1.1. Capa interfaz ............................................................................................................. 33 4.1.2. Capa de modelo de negocio ...................................................................................... 34 4.1.3. Capa de datos ............................................................................................................ 34 4.2. ESTRUCTURA DE LA APLICACIÓN ................................................................................................ 34 4.2.1. Directorio “src” .......................................................................................................... 34 4.2.2. Directorio “res” .......................................................................................................... 38 4.3. IMPLEMENTACIÓN DE ACTIVIDADES ............................................................................................ 38 4.3.1. Main Activity .............................................................................................................. 39 4.3.2. Change URL Activity ................................................................................................... 43 4.3.3. Actividades de los diferentes dispositivos .................................................................. 43 4.4. IMPLEMENTACIÓN DE INTERFAZ DE USUARIO ................................................................................ 43 4.4.1. Implementación de interfaz de ubicaciones .............................................................. 44 4.4.2. Implementación de interfaz de dispositivos ............................................................... 45 4.4.3. Implementación de interfaz de cambio de ruta ......................................................... 46 4.5. COMUNICACIÓN CON LA PLATAFORMA DOMÓTICA ........................................................................ 47 4.6. MANIFIESTO DE LA APLICACIÓN ................................................................................................. 48 4.7. OTRAS CARACTERÍSTICAS IMPLEMENTADAS .................................................................................. 49 4.7.1. Captura de excepciones ............................................................................................. 49 4.7.2. Inclusión de iconos dinámicos en la interfaz de ubicaciones ..................................... 50 4.7.3. Camino navegacional................................................................................................. 51 4.8. MEJORAS APLICABLES.............................................................................................................. 52 4.8.1. Lista de URL conocida ................................................................................................ 52 4.8.2. Mejora en el tratado de excepciones de la entrada de datos .................................... 52 4.8.3. Autentificación ........................................................................................................... 52 4.8.4. Interfaz visual............................................................................................................. 53 5. PROTOTIPO DE APLICACIÓN ............................................................................................... 54 5.1. INTERFAZ DE DISPOSITIVOS ....................................................................................................... 54 5.2. DEMOSTRACIÓN DEL PROTOTIPO ............................................................................................... 58 5.2.1. Navegación por ubicaciones y dispositivos ................................................................ 59 5.2.2. Interacción con dispositivos ....................................................................................... 60 6 5.2.3. Cambio de URL de entrada ........................................................................................ 61 6. CONCLUSIONES Y TRABAJOS FUTUROS............................................................................... 63 6.1. VALORACIÓN PERSONAL .......................................................................................................... 63 6.2. TRABAJOS FUTUROS ................................................................................................................ 63 7. REFERENCIAS ...................................................................................................................... 65 ANEXO A: MUTESERVLET ........................................................................................................ 66 ANEXO B: MYLISTADAPTER, CONSTRUCCIÓN DE UNA LISTA PERSONALIZADA ....................... 69 ANEXO C: GUÍA DE PUESTA EN MARCHA DE LA APLICACIÓN .................................................. 73 7 Índice de Ilustraciones Ilustración 2.1. Posición en el mercado de los SO móviles. .......................................................... 16 Ilustración 2.2. Árbol de Interfaz .................................................................................................. 19 Ilustración 2.3. Ejemplo Layout .................................................................................................... 20 Ilustración 3.1 Ejemplo de la sección Location del documento de entrada ................................. 24 Ilustración 3.2 Ejemplo de la sección Device del documento de entrada .................................... 25 Ilustración 3.3 Método startDocument del Handler en SAX ........................................................ 30 Ilustración 3.4 Método endDocument del Handler en SAX ......................................................... 30 Ilustración 3.5 Configuración e inicialización del Parser SAX ....................................................... 31 Ilustración 3.6 Invocando al Parser .............................................................................................. 32 Ilustración 4.1 Fragmento del layout switch_device.xml ............................................................. 33 Ilustración 4.2 Directorio "src" de la aplicación ........................................................................... 35 Ilustración 4.3 Paquete pfc.Housed.Activity ................................................................................ 35 Ilustración 4.4 Paquete pfc.Housed.Adapter ............................................................................... 36 Ilustración 4.5 Paquete pfc.Housed.Devices ................................................................................ 36 Ilustración 4.6 Paquete pfc.Housed.Devices.Activity ................................................................... 37 Ilustración 4.7 Paquete pfc.Housed.Framework .......................................................................... 37 Ilustración 4.8 Paquete pfc.Housed.Handler ................................................................................ 38 Ilustración 4.9 Directorio "res" de la aplicación ........................................................................... 38 Ilustración 4.10 Fragmento de AndroidManifest.xml que hace referencia a MainActivity ......... 39 Ilustración 4.11 Clase Housed ...................................................................................................... 40 Ilustración 4.12 Manejador de click en la lista de localizaciones ................................................. 40 Ilustración 4.13 Declaración de botón back ................................................................................. 40 Ilustración 4.14 Capturar referencia del botón ............................................................................ 40 Ilustración 4.15 Instalación del manejador que utilizará ............................................................. 41 Ilustración 4.16 Método que gestiona los eventos producidos ................................................... 41 Ilustración 4.17 Interfaz de ubicaciones ....................................................................................... 44 Ilustración 4.18 Elementos dinámicos y estáticos de la interfaz de ubicaciones ......................... 45 Ilustración 4.19 Interfaz de dispositivo Switch ............................................................................. 46 Ilustración 4.20 Interfaz de cambio de ruta ................................................................................. 47 Ilustración 4.21 Método switchOn de la clase Switch .................................................................. 48 Ilustración 4.22 Fragmento de AndroidManifest.xml .................................................................. 49 Ilustración 4.23 Fragmento de permisos del AndroidManifest.xml ............................................. 49 Ilustración 4.24 Iconos dinámicos de la interfaz de ubicaciones ................................................. 51 Ilustración 5.1. Interfaz del dispositivo Switch ............................................................................. 54 Ilustración 5.2 Interfaz del dispositivo PercentualDimmer .......................................................... 55 Ilustración 5.3 Interfaz del Dispositvo Pulse................................................................................. 56 Ilustración 5.4 Interfaz del dispositivo Sensor .............................................................................. 57 8 Ilustración 5.5 Interfaz del dispositivo VerticalMovement .......................................................... 58 Ilustración 5.6 Estructura domótica ejemplo ............................................................................... 59 Ilustración 5.7 Ejemplo navegación entre localizaciones y dispositivos....................................... 60 Ilustración 5.8 Ejemplo interacción con un dispositivo Switch .................................................... 61 Ilustración 5.9 Ejemplo de cambio de dirección del documento de entrada ............................... 62 Ilustración 0.1. Fragmento de código de la clase Switch, método getDeviceState ...................... 68 Ilustración 0.1. Código fila.xml ..................................................................................................... 69 Ilustración 0.2. Código fila_icono.xml .......................................................................................... 70 Ilustración 0.3. Código del método getView la clase MyListAdapter ........................................... 71 9 1. Introducción El proyecto “Diseño e implementación de una aplicación domótica en Android reconfigurable a partir de un XML” surge con la intención de crear una aplicación para la mencionada plataforma móvil que sea capaz de procesar y mostrar mediante interfaces sencillas, ciertos escenarios domotizados y debidamente descritos en un documento XML que obtiene la aplicación a través de la red de manera dinámica. 1.1. Motivación Tecnologías móviles En poco tiempo, los terminales móviles se han convertido en un elemento indispensable en nuestra vida cotidiana, siendo esta una de las razones por las cuales se ha producido una evolución del sector tan acelerada. La incorporación a los móviles de nuevas tecnologías, que nos permiten por ejemplo el acceso a internet, reproductor multimedia, fotografía digital, etc., dan al usuario muchas posibilidades de uso de su terminal. Con las tendencias actuales de un mercado que, cada vez más, se decanta por los Smartphone, encontramos tecnologías en estos mismos terminales, que hace poco tiempo eran novedosas en el sector de la informática. El hardware implantado en los mismos, es mucho más avanzado en algunos casos, que el instalado en una ordenador de hace pocos años. El tamaño ocupado los chips y componentes se ha reducido considerablemente, gracias a la evolución de las tecnologías de fabricación. Paralelamente a la evolución hardware que han sufrido los terminales móviles, nos encontramos con un software cada vez más avanzado, que nos permite aprovechar al máximo las características de estos nuevos terminales. Como bien venimos viendo a través de los años, hay gran variedad de terminales móviles y con ellos gran variedad de sistemas, como es el caso de iOS, 16 2.3. Contexto tecnológico 2.3.1. Android En este punto haremos un pequeño análisis de Android, mencionamos un poco su historia, su situación de mercado y la estructura básica sus aplicaciones, desde el punto de vista del desarrollador y del usuario de la plataforma. 2.3.1.1. Introducción Desde su lanzamiento en octubre del 2008 y considerado un sistema joven, Android se ha convertido en una gran plataforma en el mercado. Tal como se observa en la tabla de la Ilustración 2.1, se sitúa en dos años con una cuota de mercado de 14.7% a la altura de otros importantes sistemas operativos, según un informe de la IDC. Posee varias características que son claves para este éxito, entre ellas encontramos la versatilidad del sistema, adaptándose rápidamente a los cambios de hardware y avances tecnológicos actuales. Destacamos además la política de admisión de aplicaciones de Android Market, con esto han conseguido que muchos Ilustración 2.1. Posición en el mercado de los SO móviles. 17 desarrolladores creen aplicaciones para este sistema operativo, que aunque relativamente nuevo, es muy accesible. El desarrollo de aplicaciones en Android se realiza principalmente en el lenguaje de programación orientada a objetos Java en un entorno parecido a Java SE 5, sin embargo, la implementación no es oficial de SUN por lo que tiene ciertos matices al estar basado realmente en el proyecto Harmony de la fundación Apache, adaptado por Google para emplearlo en Android. El entorno de desarrollo para aplicaciones Android más difundido es Eclipse junto al plugin ADT (Android developement tools) mantenido por los creadores de la plataforma por lo que será el escogido para la realización del proyecto. Estas características junto a muchas otras hacen de Android un sistema operativo que cumple los requisitos mínimos para el desarrollo de nuestra aplicación, aplicando así los conocimientos adquiridos de los lenguajes de programación utilizados por ese SO durante los cursos anteriores como son Java y XML. 2.3.1.2. Arquitectura Con el objetivo de comprender mejor Android, echaremos un pequeño vistazo a su arquitectura y las características de la misma, en este apartado conoceremos de qué se compone el sistema operativo con mayor detalle, describiendo cada una de las partes. El sistema operativo Android se compone de las siguientes partes: Aplicaciones: Todas las aplicaciones escritas en el lenguaje de programación Java, este es el objetivo principal del proyecto. Entre otras, el propio sistema contiene algunas aplicaciones básicas, como pueden ser, cliente de email, programa de SMS, calendario, contactos, etc. Framework de aplicaciones: Los desarrolladores tienen acceso completo a los mismos APIs del framework usados por las aplicaciones base. La arquitectura está 18 diseñada para simplificar el reúso de componentes. Éste mismo mecanismo permite que los componentes sean reemplazados por el usuario. Librerías: Android incluye un set de librerías C/C++ utilizadas por varios componentes del sistema Android. Estas capacidades se exponen a los desarrolladores a través del framework de aplicaciones de Android. Algunas son: System C library (implementación librería C Standard), librerías de medios, librerías de gráficos, 3d, SQLite, entre otras. Runtime de Android: Cada aplicación Android corre su propio proceso, con su propia instancia de la máquina virtual Dalvik. Núcleo - Linux: Android depende de un Linux versión 2.6 para los servicios base del sistema como seguridad, gestión de memoria, gestión de procesos, etc. El núcleo también actúa como una capa de abstracción entre el hardware y el software. 2.3.1.3. Jerarquía Visual La principal clase de Android es Activity, un objeto de la clase android.app.Activity. Una actividad hace multitud de cosas, pero por ella misma no se presenta nada por pantalla. Para conseguirlo es necesario diseñar el UI, con View y Viewgroup, que son las clases que se utilizan para crear la interfaz entre el usuario y la plataforma Android. View: Una View es un objeto cuya clase es android.View.View. Es una estructura de datos cuyas propiedades contienen los datos de la capa y la información específica del área rectangular de la pantalla. La clase View es útil como clase base para los Widgets, que son unas subclases ya implementadas que dibujan los elementos en la pantalla. Los Widgets contienen sus propias medidas. La lista de Widgets es amplia e incluyen entre otros: Text, EditText, InputMethod, MovementMethod, Button, etc. 19 Viewgroups: Un Viewgroup es un objeto de la clase android.View.Viewgroup, como su propio nombre indica, un Viewgroup es un objeto especial de View cuya función es contener y controlar la lista de Views y de otros Viewgroups. Los Viewgroups te permiten añadir estructuras a la interfaz y acumular complejos elementos en la pantalla que son diseccionados por una sola entidad. La clase Viewgroup es útil como base de la clase Layouts, que son subclases implementadas que proveen los tipos más comunes de los Layouts de pantalla. Los Layouts proporcionan una manera de construir una estructura para una lista de View. Árbol estructurado de la interfaz UI: En la plataforma Android tú defines una Activity del UI usando un árbol de nodos View y Viewgroups, tal como se muestra en la Ilustración 2.2. El árbol puede ser tan simple o complejo como necesites hacerlo, y se puede desarrollar usando los Widgets y Layouts que Android proporciona o creando tus propias Views. Para añadir el árbol a la pantalla, la Activity llama al método “setContentView” y pasa una referencia al objeto nodo principal. Una vez que el sistema Android ha referenciado el objeto nodo principal ya puede trabajar directamente con el nodo para anular, medir y dibujar el árbol. Ilustración 2.2. Árbol de Interfaz 20 Como se ha dicho anteriormente, cada Viewgroup es el responsable de tomar medidas sobre el espacio que tienen, preparando a sus hijos y llamando a “Draw” por cada hijo que se muestra a sí mismo. El hijo hace una petición sobre el tamaño y la localización del padre, pero el objeto padre toma la última decisión sobre el tamaño que cada hijo puede tener. LayoutParams: Cómo un hijo especifica su posición y su tamaño. Todos los Viewgroup utilizan como clase anidada una extensión de ViewGroup.LayoutParams. Esta subclase contiene los tipos de propiedades que definen la posición y el tamaño de un hijo, en propiedades apropiadas para la clase de grupo de clases. Hay que destacar que cada subclase LayoutParams tiene su propia sintaxis para cambiar los valores. Cada elemento hijo debe definir unos LayoutParams que sean apropiados para su padre, aunque se podrían definir diferentes LayoutParams para sus hijos. Ilustración 2.3. Ejemplo Layout 21 Todos los Viewgroup incluyen anchura y altura, muchos también incluyen márgenes y bordes. Se puede indicar que el View tenga las dimensiones del tamaño de su contenedor, o que llegue a ser tan grande como el contenedor le permita. 2.3.2. XML (Extensible Markup Language) Este metalenguaje extensible está muy presente en el trascurso de nuestro proyecto, como ya sabemos, puede tener muchas funciones. En nuestro caso lo encontramos como intermediario para la comunicación de datos, tal y como venimos señalando durante el trascurso de este documento. Además Android hace un uso extensivo del estándar XML para la definición de las interfaces gráficas y del manifiesto que cada una de las aplicaciones Android posee. Existen varias formas de procesar documentos XML en Java, necesitaremos conocerlas e implantar la más satisfactoria al proyecto, con la finalidad de aplicarla en el documento de entrada de datos de la aplicación. En el próximo capítulo veremos las diferentes opciones de las que disponemos en este aspecto y cual escogeremos finalmente para implantarla. 22 3. Descripción del escenario y entrada de datos 3.1. Estructura del escenario utilizado En este punto, enumeraremos los diferentes dispositivos que ofrece a fecha de hoy el escenario y que dispositivos de este escenario soporta la aplicación. Podemos encontrar más detalladamente explicados en el proyecto de final de carrera “Implementación de aspectos de eficiencia energética en el Hogar Digital: un caso práctico” desarrollado por Miriam Gil Pascual y dirigido por el profesor Joan Fons i Cors. La aplicación desarrollada deberá comunicarse con los dispositivos que a continuación se enumeran a través de un Servlet y que se encuentran en el laboratorio del ProS: - AngularDimmer - HexDimmer - PercentualDimmer - Pulse - Sensor - Switch - VerticalMovement Cada unos de estos dispositivos, tendrá una ubicación asociada a él, y esta misma ubicación puede contener más de un dispositivo, por lo tanto se convierten en otro punto importante de la estructura. En resumen en la estructura podemos encontrar ubicaciones (Location) y dispositivos (Device), como ya hemos visto existen distintos tipos de dispositivos según sea su función final, por tanto, deberemos distinguir en todas las posibilidades existentes. 23 3.2. Gestión y Procesado del escenario Una de las características principales de la aplicación desarrollada es la entrada de datos, como se menciona anteriormente, debe tratar y analizar el documento recibido mediante la URL proporcionada por el usuario. Con tal de cumplir estas características se deben contemplar varios puntos. En primer lugar, y como explicamos en el sub-apartado Presentación del escenario, debemos conocer y comprender el documento de entrada, estudiando el formato de los datos y las partes que utilizará la aplicación. Una vez estudiado el documento de entrada, debemos realizar la estructura que albergará los datos que serán leídos del mismo documento, este punto implica conocer la jerarquía de los datos y conocer sus atributos y características, para poder modelar una estructura correcta. Para terminar con la obtención de datos de la entrada, estudiamos cada uno de los procesadores de documentos XML ofrecidos por Java y compatibles con Android, comparamos las posibilidades que nos ofrecen e implantamos el elegido en la aplicación, adaptando sus funciones a nuestras necesidades. En el sub-apartado Procesado del escenario encontramos las diferentes tecnologías ofrecidas por el lenguaje, así como los problemas surgidos para implantarlas. 3.2.1. Presentación del escenario El escenario que recibirá nuestra aplicación se encuentra expresado en XML, que posee una estructura determinada. En el caso de nuestra aplicación, solo debemos prestar atención a los sectores que nos interesan, ya que este mismo documento, contiene información que es redundante para nosotros y en cambio es importante para otro tipo de proyectos de la plataforma. 24 Dicho esto, vamos a exponer las partes del documento que son primordiales para nosotros, de las cuales obtendremos información y analizaremos con el sistema de tratado de documentos XML que hemos elegido. Siguiendo un orden secuencial del documento, el primer objeto que nos encontramos son las diferentes ubicaciones, que presentan diferentes características. Como vemos en la Ilustración 3.1 dentro del tag Location encontramos los atributos de la misma, podemos distinguir varios campos, los más importantes para nosotros son: el campo bajo la etiqueta ID que será el identificador de la localización, Name que contiene el nombre completo de la misma, SuperLocationIDRef donde encontramos la ID de la localización que estará por encima de la actual, es decir la localización padre o SuperLocation, la etiqueta Sublocations hace referencia a las localizaciones que existen dentro de la misma, por último LocationDevice contiene los dispositivos que están ligados a esta localización. Prosiguiendo con la lectura del documento, la siguiente parte relevante, la encontramos en los dispositivos (“Device”), en cuyo apartado encontramos diferentes características y descripción del mismo, así como que posición y en que ubicación se encuentran. Ilustración 3.1 Ejemplo de la sección Location del documento de entrada 25 Tal como se observa en la Ilustración 3.2, al igual que en Location, dentro del tag Device, se encuentran diferentes etiquetas como son: ID que contiene el identificador del dispositivo, Type y DataType que nos indican el tipo del dispositivo, la etiqueta Properties puede contener información sobre el nombre completo del elemento y otras características de menor utilidad. Ahora conocemos la distribución de la información que nos es necesaria para el desarrollo correcto de la aplicación, el siguiente paso es crear una serie de clases que contendrán dicha información que seguidamente extraeremos. 3.2.2. Estructura e implementación de las clases necesarias En este apartado, describiremos las clases que componen la estructura creada para albergar la información recibida de la lectura y procesado del documento de entrada. Dicha estructura se compone de tres clases importantes y diferenciadas: Installation, Location y Device. A continuación describiremos las relaciones entre estas clases y la composición de las mismas con la ayuda de un diagrama de clases. Ilustración 3.2 Ejemplo de la sección Device del documento de entrada 32 Una vez tenemos la dirección del documento a analizar, introducimos el manejador y ordenamos al intérprete que obtenga el documento y lo analice. Al finalizar el análisis, podremos proceder a obtener los datos ya estructurados y correctos. En caso de ocurrir una excepción en la llamada, se capturará y se mostrará al usuario por interfaz gráfica la naturaleza de dicha excepción. Ilustración 3.6 Invocando al Parser 33 4. Arquitectura de la aplicación El siguiente apartado tiene como objetivo servir de la base para presentar la arquitectura propuesta para el prototipo de la aplicación móvil con el objetivo de crear una aplicación más sostenible. Conseguimos esto con el empleo de buenas prácticas de programación, separando los interfaces y la implementación. 4.1. Arquitectura por capas La arquitectura con la que se desarrolla la aplicación móvil en Android es multicapa, dedicando así a cada una de las capas una funcionalidad concreta y bien definida. 4.1.1. Capa interfaz La capa de interfaz o de presentación de la aplicación está compuesta por las vistas definidas en ficheros XML. Tiene un papel muy importante en la aplicación, ya que se trata de la presentación de la aplicación al usuario. En la Ilustración 4.1 podemos ver un fragmento de los ficheros XML que implementan una de las vistas. Ilustración 4.1 Fragmento del layout switch_device.xml 34 4.1.2. Capa de modelo de negocio Esta capa es la encargada de manejar los datos enviados por anterior, es decir, en función de los eventos recibidos por la capa de presentación deberá tomar decisiones de modificar el modelo y mostrar los resultados. Aquí se implementa toda la lógica de negocio. En la aplicación, esta capa se implementa en Java. 4.1.3. Capa de datos Es la encargada de acceder a los datos según reciba las solicitudes de la capa anterior. Se obtendrán los datos del documento de entrada, mediante el tratado y extracción de datos del mismo. 4.2. Estructura de la aplicación El objetivo del siguiente apartado es presentar la estructura interna de la aplicación realizada, en base a los conocimientos adquiridos sobre la tecnología utilizada y acorde a lo presentado en anteriores apartados. 4.2.1. Directorio “src” Dentro de este directorio encontramos los paquetes Java que contiene la aplicación, a continuación, explicaremos con detalle el contenido de cada uno de ellos, esto ayudará a encontrar fácilmente el código encargado de cada funcionalidad. 35 La funcionalidad distribuida en paquetes quedaría de esta forma: pfc.Housed.Activity En este paquete podemos encontrar la actividad principal de la aplicación, llamada “Housed”, será la encargada de inicializar los componentes de la misma y cargar la interfaz textual principal. Junto a esta actividad, encontramos otra, llamada “ChangeUrlActivity”, que nos permitirá mediante la carga de una interfaz diseñada para ello, cambiar la Url del archivo de entrada. pfc.Housed.Adapter Situado en este paquete encontramos el adaptador que nos permite rellenar el listado tratando uno a uno cada objeto a introducir en el. Esta clase hereda del adaptador por defecto llamado “BaseAdapter” y tiene como tareas, cargar las View de cada uno de los objetos que componen la fila, así como determinar que objetos pueden ser pulsados. Ilustración 4.2 Directorio "src" de la aplicación Ilustración 4.3 Paquete pfc.Housed.Activity 36 pfc.Housed.Device Este paquete contiene la implementación de los posibles dispositivos de los que dispondrá nuestra aplicación, dentro de las mismas clases encontramos métodos que permiten la comunicación con los dispositivos mediante llamadas HTTP por método GET al servidor que los maneja, dando la opción de obtener los diferentes estados que puede tener cada uno de los dispositivos. Todas las clases contendías en este paquete heredan de la clase “Device” contenida en el paquete pfc.Housed.Framework. pfc.Housed.Devices.Activity En este paquete se encontrarán las Activity encargadas del control del estado de los dispositivos, así como de la carga de las interfaces de cada uno de los tipos. Cada una de estas Activity representará un dispositivo de un tipo y en función de las acciones realizadas por el usuario utilizará los métodos de los objetos determinados. Ilustración 4.4 Paquete pfc.Housed.Adapter Ilustración 4.5 Paquete pfc.Housed.Devices 37 pfc.Housed.Framework Encontramos dentro de este paquete, la implementación de la estructura que soporta la obtención de datos. pfc.Housed.Handler Por último, este paquete contiene el Handler o manejador de eventos del intérprete que utilizaremos para la entrada de datos de la aplicación. Esta clase hereda del manejador por defecto llamado “DefaultHandler” y reescribiendo sus métodos. Ilustración 4.6 Paquete pfc.Housed.Devices.Activity Ilustración 4.7 Paquete pfc.Housed.Framework 38 4.2.2. Directorio “res” En este directorio almacenaremos todo tipo de recursos externos que utilizará la aplicación para su funcionamiento. Los más importantes que encontramos son las imágenes, almacenadas en el directorio “drawable” y los ficheros xml que contienen la definición de las vistas en “layout”. 4.3. Implementación de actividades Android basa sus aplicaciones en el uso de las Activity, relacionadas con una interfaz de usuario, son las encargadas de gestionar los eventos que sobre ella se produzcan. En este apartado, veremos las actividades que componen nuestra aplicación y que funciones tiene cada cual de ellas. Ilustración 4.8 Paquete pfc.Housed.Handler Ilustración 4.9 Directorio "res" de la aplicación 39 Cada una de las actividades creadas para la aplicación debe de ser especificada en el Manifiesto de actividades, donde podremos ver, las actividades que componen la aplicación, así como, las características y opciones de las mismas. Como explicaremos a continuación, la aplicación se compone de una actividad principal, la cual será la encargada de crear sub-actividades y proporcionarles la información necesaria para su correcto funcionamiento, así como recibir información de las mismas cuando sea necesario. 4.3.1. Main Activity La actividad principal de nuestra aplicación se sitúa en el paquete Java llamado pfc.Housed.Activity y la hemos llamado “Housed.java”. Como actividad propia de la aplicación debe estar registrada en el Manifiesto de actividades (“AndroidManifest.xml”), en este registro, debe constar que dicha actividad es la actividad principal y tendrá como categoría “Launcher”, esto nos permitirá iniciar la aplicación con esta actividad. En el punto anterior, se mencionó que cada actividad se relaciona con una interfaz de usuario, en este caso, nuestra actividad principal será la encargada de gestionar los eventos e introducir la información en nuestra interfaz de ubicaciones. Esta interfaz es de tipo lista de objetos, por tanto, esta característica implica que Housed herede de ListActivity y no de Activity. Ilustración 4.10 Fragmento de AndroidManifest.xml que hace referencia a MainActivity 40 Otra de las funciones principales de esta actividad es gestionar los eventos que sobre la interfaz gráfica asociada se produzcan, para este fin, se crean métodos dentro de la clase, que permiten el manejo de los diferentes eventos que se pueden producir, como por ejemplo, clic en uno de los botones de la interfaz o en un objeto de la lista. Con tal de gestionar este tipo de eventos hemos de asignar al elemento de la interfaz un manejador de eventos, que será el método que se inicie al producirse el evento. Primero declararemos el tipo de Widget que queremos manejar. Seguidamente a esto, vamos a referenciar el recurso desde la actividad y posteriormente asignaremos el manejador que vamos a utilizar. Ilustración 4.14 Capturar referencia del botón Ilustración 4.13 Declaración de botón back Ilustración 4.12 Manejador de click en la lista de localizaciones Ilustración 4.11 Clase Housed 41 Por último declaramos el método que gestionará los eventos y dentro del mismo declaramos el método del evento que vamos a gestionar e implementaremos las acciones del mismo. MainActivity es también la encargada de cargar los datos de entrada y mostrarlos, para ello se declara un método “Load”, en el cual se inicializara y llamará a nuestro manejador, tal y como se explica en el punto anterior. Otra de las funciones de este método, es la declaración de la variable que recibirá dichos datos, así como, el manejo de las diferentes excepciones que puedan ocurrir en el proceso de obtención de datos de entrada. Como se expuso en el punto anterior, la actividad principal tiene otra función principal, debe enviar y recibir datos de sus sub-actividades. Para la obtención de datos de las sub-actividades, especialmente de la actividad ChangeURLActivity, se debe manejar este evento, existe un método “onActivityResult” que nos permite la realización de esta tarea de manera sencilla. En el podemos extraer desde el Bundle los datos que la sub-actividad nos envía. Lógicamente, antes de finalizar el método si la URL proporcionada por el cliente cambió se debe llamar al método “Load”, que se encargará de extraer los datos de la entrada y mostrarlos correctamente como hemos explicado anteriormente. Ilustración 4.16 Método que gestiona los eventos producidos Ilustración 4.15 Instalación del manejador que utilizará 48 La última parte para conseguir la comunicación con la plataforma domótica, es la utilización de los métodos creados. Al iniciar una actividad correspondiente a un dispositivo, mediante la selección del mismo en la interfaz de ubicaciones, esta actividad localiza el dispositivo que corresponde a los datos que recibe de la MainActivity, una vez localizado, se procede a consultar los datos y el estado del mismo. Los datos, se pueden encontrar localmente, ya que son proporcionados por la entrada de la aplicación, en cambio, para el estado del mismo se llamarán a los métodos creados para este fin y mencionados anteriormente. Como vimos en el punto anterior la interfaz de dispositivos ofrece también la posibilidad, mediante varios mecanismos de cambiar el estado del mismo, según sea su clase. Los eventos producidos en estos mecanismos se manejan, dando la funcionalidad correspondiente con el uso de los métodos de consulta de estado y modificación. 4.6. Manifiesto de la aplicación Este archivo es de importancia dentro de la aplicación, ya que en él se declararán tanto los componentes de Android utilizados como los recursos del sistema que la aplicación necesita. Ilustración 4.21 Método switchOn de la clase Switch 49 En nuestro caso, el manifiesto contendrá la declaración de las actividades de las que se compone la aplicación, indicando el modo y las características de la ejecución de cada una de ellas. Además, en la parte final se definen los permisos de los que dispone la aplicación, en este caso, el único permiso necesario para la correcta ejecución de la aplicación es la conexión a internet. 4.7. Otras características implementadas 4.7.1. Captura de excepciones Es necesario capturar y distinguir entre las diferentes excepciones que se pueden producir en la vida de la aplicación, para ello, en la Main Activity o Housed.java, se ha implementado la captura de las diferentes excepciones. Brevemente enumeraremos las excepciones que tratan la aplicación y el resultado de las mismas en la interfaz. Encontramos, excepciones recibidas de la entrada de datos, bien producidas por una estructuración errónea del documento de entrada, o por una dirección URL Ilustración 4.23 Fragmento de permisos del AndroidManifest.xml Ilustración 4.22 Fragmento de AndroidManifest.xml 50 errónea. El primer caso se capturara como una IOException y se mostrara por pantalla un mensaje informativo del tipo de excepción producida. En el caso de las excepciones producidas por una dirección de URL errónea introducida por el usuario, se capturarán como FileNotFoundException e igual que en la anterior, se muestra la naturaleza de la misma. 4.7.2. Inclusión de iconos dinámicos en la interfaz de ubicaciones A lo largo de la memoria, se ha mencionado la inclusión de iconos en la lista de ubicaciones y dispositivos que harían más intuitiva la interfaz. Con esta pequeña variedad de iconos permiten al usuario distinguir rápidamente los elementos. Una vez introducidos en el proyecto, en la sección de /res/drawable ya se pueden referenciar desde cualquier lugar. En nuestro caso, la clase responsable de dibujar el icono correcto en cada uno de los elementos será, el adaptador de la lista de elementos (MyListAdapter.java). Cuando se recibe el elemento, se consulta el tipo del mismo y se dibuja el icono asociado en la fila correspondiente. 51 4.7.3. Camino navegacional Con la finalidad de que el usuario de la aplicación pueda navegar como el desee entre las localizaciones y dispositivos que presenta la estructura domótica hemos implementado un camino navegacional en la actividad principal, que tiene como objetivo seguir los pasos del usuario, para en cualquier momento poder volver sobre ellos. Para ello, se crea un ArrayList donde según el botón de navegación pulsado se añadirán o eliminarán elementos de la lista. Lógicamente, estos elementos hacen referencia al dispositivo o localización pulsada. Otra de las características que conseguimos con esta implementación, es poder mostrar al usuario distintas posibilidades según sea su situación en la estructura, de este modo, si el usuario se encuentra en el ParentLocation el botón Back se convierte en un botón de salida de aplicación y se muestra el botón de cambio de URL, que no se muestra en el resto de la estructura. Ilustración 4.24 Iconos dinámicos de la interfaz de ubicaciones 52 4.8. Mejoras aplicables 4.8.1. Lista de URL conocida Actualmente, la aplicación solo recuerda la última URL introducida por el usuario en la sección ChangeURL, para mejorar este aspecto, una de las opciones propuestas por el autor es la inclusión de un historial local de URL visitadas, que sea recordado siempre. El se puede presentar como una lista de elementos para que el usuario pueda navegar por ellos y seleccionarlos. Con esta mejora tendríamos una aplicación más sencilla y usable. 4.8.2. Mejora en el tratado de excepciones de la entrada de datos Gracias a la sencilla captura de excepciones implementada, podemos distinguir entre los errores que se producen en la entrada de datos. Con tal de dar mayor información al usuario, se puede mejorar este aspecto concretando más la naturaleza del error e informando al usuario donde se ha producido y que puede hacer para solucionarlo. 4.8.3. Autentificación Uno de los aspectos más comunes de las aplicaciones es la autentificación, en este caso, tal y como se presenta la aplicación, no dispone de esta funcionalidad. La inclusión de esta funcionalidad proporcionaría ciertas ventajas para el usuario, ya que esto unido a la lista de URL conocidas, proporciona al usuario una aplicación más sencilla, segura y personalizada. Los problemas que nos plantea esta funcionalidad, se refieren al cuando y como se debe implementar. En cuanto al cuando realizar la autentificación, la opción más común y cómoda es introducirla al inicio de la aplicación. Para la implementación, 53 pensamos en el formulario de autentificación, se puede hacer mediante un formulario que salte al inicio de la misma y donde el usuario debe rellenar los diferentes campos. En cambio, para que la aplicación verifique los datos necesitamos que sean persistentes, una de las opciones que Android nos brinda es la introducción de una pequeña base de datos. Hay que tener en cuenta, que la implementación de esta mejora, haría más complicada y pesada la aplicación. 4.8.4. Interfaz visual Para el usuario final es más atractiva una interfaz visual que una textual. Actualmente la aplicación dispone de una interfaz textual, por tanto, una de las mejoras que se podrían realizar es la inclusión de navegación por planos o imágenes, de forma que el usuario seleccionando partes de estas navegue por la estructura. Para llevar a cabo esta mejora, debemos tener en cuenta los campos que referencian a las imágenes en el documento de entrada de la aplicación, crear nuevos layout donde aplicaremos las características necesarias a cada una de las imágenes mostradas. Por último, se podría dar al usuario la opción de cambiar de interfaz textal a visual en cualquier momento de la navegación por la estructura de la aplicación. 54 5. Prototipo de aplicación Una vez creado el prototipo de aplicación, en este capítulo presentaremos el resultado de la aplicación, veremos cada una de las interfaces de dispositivos y se realizan diferentes pruebas sobre ella con un cierto caso práctico. 5.1. Interfaz de dispositivos Anteriormente, en el punto Implementación de interfaz de dispositivos se expone la necesidad de incluir una interfaz personalizada para cada uno de los dispositivos soportados por la aplicación. Ahora, veremos una serie de capturas que ilustrarán el resultado de estas interfaces de las que dispone el prototipo de aplicación. Para empezar, en la Ilustración 5.1 podemos ver la interfaz del dispositivo Switch en los dos posibles estados del dispositivo. Estos estados se representan gracias al ToggleButton que declaramos en el layout que reside /res/layout/swtich_device.xml. Ilustración 5.1. Interfaz del dispositivo Switch 55 En cuanto a los dispositivos Dimmer, disponen de una interfaz muy similar, su única diferencia es la configuración del SeekBar que muestra el progreso y el formato en el que se muestra este. En caso del dispositivo PercentualDimmer, el progreso es de 0-100 y se representa en tanto por cien, AngularDimmer abarca de 0-360 y se representa en grados, por ultimo HexDimmer tiene un rango de 0-255. Seguimos con el dispositivo llamado Pulse, cuya interfaz está dotada de un Button con el texto “Press” el cual activa el dispositivo al pulsarlo, enviando una señal como se ha explicado a lo largo del documento. Ilustración 5.2 Interfaz del dispositivo PercentualDimmer 56 La interfaz del dispositivo Sensor dispone de un TextView que muestra textualmente el estado actual del sensor, además de esto, se añade un botón cuya función es actualizar el estado del dispositivo y reflejarlo en el TextView. Ilustración 5.3 Interfaz del Dispositvo Pulse 57 Por último, nos centramos en la interfaz del dispositivo VerticalMovement, distinguimos tres botones con funcionalidades distintas. Las acciones son Up, Stop, Down, cada cual interactúa con el controlador tal y como expresa el nombre del Button. Ilustración 5.4 Interfaz del dispositivo Sensor 64 aplicación, se podrían desarrollar algunas de las mejoras expuestas en el punto Mejoras aplicables, como pueden ser: - Lista de URL conocida. - Mejora en el tratado de excepciones de la entrada de datos. - Autentificación. - Interfaz visual. Estos aspectos harían que la aplicación sea más madura, segura e intuitiva para el usuario. Como mejora adicional se contempla el hecho de actualizar la aplicación a las últimas versiones de la plataforma, ya que su evolución es constante y rápida, revisando el perfecto funcionamiento de todos los aspectos de la aplicación y manteniendo su total compatibilidad. 65 7. Referencias Las siguientes fuentes de información fueron empleadas durante la realización del proyecto. [1] DiMarzio, J.F. “Android A Programmer’s Guide”. McGrawHill. United States of America, 2008. [2] Rogers, Rick. “Android Application Development”. O’Reilly Series. United States of America, 2009. [3] Rogers, Reto. “Professional Android Application Development”. Wrox. Canadá, 2009. [4] Gil Pascual, Miriam. “Implementación de aspectos de eficiencia energética en el hogar digital: un caso práctico”. Valencia, 2008. [5] http://developer.android.com [6] http://source.android.com/ [7] http://www.android-spa.com/ 66 Anexo A: MuteServlet Para la correcta comunicación entre la aplicación y los dispositivos se hace uso de MuteServlet. MuteServlet es un Servlet que atiende peticiones de interacción con los dispositivos del tunnel de calimero. Esta implementado como un bundle OSGi que se instalará y ejecutará en la misma configuración de ejecución que el resto de dispositivos del túnel. Se utilizará de la siguiente manera. En primer lugar crearemos un petición http (http request) a la dirección donde oye el Servlet pasándole como parámetros el ID y tipo del dispositivo, así como la acción a tomar sobre el dispositivo y el nuevo valor en caso que sea necesario. A continuación se exponen los tipos de parámetros que admite el Servlet DeviceID El ID del dispositivo contra el que queremos interactuar. DeviceType El tipo del dispositivo. Puede ser uno de los siguientes: o es.upv.pros.tunnel.interfaces.IActuatorSwitch o es.upv.pros.tunnel.interfaces.IActuatorPulse o es.upv.pros.tunnel.interfaces.IActuatorVerticalMovement o es.upv.pros.tunnel.interfaces.IActuatorPercentualDimmer o es.upv.pros.tunnel.interfaces.IActuatorAngularDimmer o es.upv.pros.tunnel.interfaces.IActuatorHexDimmer o es.upv.pros.tunnel.interfaces.ISensor Action La operación a ejecutar. En función del tipo de dispositivo contra el que se actué, tendremos distintos tipos de acción: o es.upv.pros.tunnel.interfaces.IActuatorSwitch  switchOn  switchOff o es.upv.pros.tunnel.interfaces.IActuatorPulse  pulse o es.upv.pros.tunnel.interfaces.IActuatorVerticalMovement 67  moveUp  moveDown  stop o es.upv.pros.tunnel.interfaces.IActuatorPercentualDimmer  setPercentualValue  on  off o es.upv.pros.tunnel.interfaces.IActuatorAngularDimmer  setAngularValue o es.upv.pros.tunnel.interfaces.IActuatorHexDimmer  setHexValue o es.upv.pros.tunnel.interfaces.ISensor  getState Value En los dispositivos de tipo dimmer, existen operaciones que requieren un valor. Este deberá ser de tipo entero : o es.upv.pros.tunnel.interfaces.IActuatorPercentualDimmer  de 0 a 100 o es.upv.pros.tunnel.interfaces.IActuatorAngularDimmer  de 0 a 360 o es.upv.pros.tunnel.interfaces.IActuatorHexDimmer  de 0 a 255 También cabe notar que el Servlet responderá con el valor actual del dispositivo con el estado tras la operación. La respuesta será del tipo “state=VALOR_ACTUAL” Una vez sabemos cómo se utiliza, veremos la implementación de las peticiones y la opción de los datos de las respuestas del mismo. En cada uno de los dispositivos soportados por la aplicación, en la clase que hace referencia a ellos, se implementan métodos que enviarán peticiones al MuteServelt. Para ello estos métodos construyen la URL de petición de esta manera: 68 Como vemos en la imagen la URL está formada por las variables que obtenemos de la estructura de datos y que el MuteServlet necesita como es por ejemplo DeviceID. El método que arriba exponemos esta creado para solicitar el estado del dispositivo, por ello en la acción a realizar se introduce la opción getState. Este es el aspecto que tendría la URL una vez construida. http://pervasive.dsic.upv.es:8080/muteServlet/?DeviceID=L1&DeviceType= es.upv.pros.tunnel.interfaces.IActuatorSwitch&Action=getState Una vez construida la URL, llamamos a la misma, según nos indica la documentación del mute Servlet y obtenemos mediante la variable state la información que nos devuelve. Ahora solo queda procesar esa información y mostrar en la interfaz el resultado de esta llamada. Ilustración 0.1. Fragmento de código de la clase Switch, método getDeviceState 69 Anexo B: MyListAdapter, Construcción de una lista personalizada A lo largo de la memoria, se describe la importancia de esta clase en la construcción de la lista de ubicaciones que cargará la actividad principal y que muestra las ubicaciones y los dispositivos del escenario. En este anexo, veremos a nivel de código, como construimos dicha lista personalizada. La clase MyListAdapter es una extensión de la clase BaseAdapter, en la cual vamos a extender los métodos de esta y adaptarla para lograr la funcionalidad deseada. Esta clase nos proporciona cada una de las filas de la lista. Para ello dispone de unos métodos, el más importante para nuestra función es el llamado getView. Android llamará al método getView de nuestro adaptador para obtener la vista de cada una de las filas. En este caso, tendremos dos tipos de filas: fila con contenido e icono y otra con solo contenido. Previamente, se han creado dos layout que representan debidamente las filas, llamadas fila.xml y fila_icono.xml cuyo código podemos ver a continuación. Ilustración 0.1. Código fila.xml 70 En el código de fila.xml observamos el tipo TextView donde definimos su estilo y forma. De este modo la fila que solo contenga contenido se mostrará de este modo. En cambio, en fila_icono.xml encontramos la definición de un LinearLayout de orientación horizontal y dentro del mismo se introducen tanto un ImageView donde mostraremos el icono correspondiente al dispositivo o localización y el TextView que contendrá el contenido. Ilustración 0.2. Código fila_icono.xml 71 En primer lugar debemos comprobar qué clase de contenido estamos recuperando, para ello, en la sentencia condicional de la línea 69 se diferencia entre ellos, como vemos si se trata de un contenido estático, como pueden ser errores o cabeceras, se carga en el View el layout de la fila que solo contiene contenido (fila.xml) y se rellena el TextView como observamos en la línea 113. Además se comprueba si no Ilustración 0.3. Código del método getView la clase MyListAdapter 72 se trata de una cabecera, en ese caso se personaliza el tamaño y por último se retorna el View que espera la MainActivity. Por otro lado, en caso de tratarse de una fila con contenido de dispositivos o localizaciones, comprobamos mediante condicionales de que tipo se trata, como vemos, tenemos a nuestra disposición dos variables que contienen todos los objetos que se pueden recuperar. Finalmente, si el objeto recuperado es un tipo de dispositivo, se comprueba de que tipo es este, como podemos ver en las líneas de la 94 a 107. Con este método sobrescrito, conseguimos personalizar cada uno de los elementos que aparecen en la ListView, ajustando sus características al tipo de objeto que se trata. El resultado se puede observar en la Ilustración 4.24. 73 Anexo C: Guía de Puesta en marcha de la aplicación En este anexo veremos una breve guía de los componentes y pasos que se precisan para la puesta en marcha de la aplicación realizada. Entorno Eclipse Nos centramos inicialmente en la instalación del entorno de desarrollo utilizado y la incorporación al mismo de los plugins de Android necesarios. El primer paso es descargar el entorno de desarrollo Eclipse, que podemos encontrar en su página oficial (www.eclipse.org/downloads) en el apartado de descargas, en nuestro caso, hemos utilizado Eclipse IDE for Java EE Developers. Una vez descargado y descomprimido en nuestro sistema, iniciamos la herramienta. Instalación SDK Para la instalación del SDK de Android, acudimos a la página para desarrolladores de Android (http://developer.android.com/sdk/index.html), en ella podemos obtener el SDK para los diferentes sistemas operativos que soporta. Mediante el SDK-Manager podemos seleccionar los paquetes que deseamos instalar, en nuestro caso, seleccionaremos la versión 1.6 de Android. Además crearemos desde el mismo las Android Virtual Device (AVD). Plugin ADT Iniciamos Eclipse y seleccionamos la opción Help > Install New Software. En la ventana que ahora aparece Available Software, hacer clic al boton Add… Aparece la ventana Add Site, en el cuadro Name puede poner por ejemplo “Android plugin“, en el cuadro Locatión ponga la siguiente URL: https://dl-ssl.google.com/android/eclipse/. Una vez instalado el plugin, pasamos a configurarlo, nos dirigimos al menú Windows > preferences y dentro del mismo encontraremos la sección Android, donde referenciamos el directorio donde el SDK ha sido instalado en nuestro sistema.