scieee AI-readable full text Open interactive document viewer

Desarrollo de la aplicación móvil Android para la plataforma de monitorización y seguridad de redes redBorder

Miguel Meana, Ángel María de

Abstract

Los dispositivos móviles son parte del día a día de cualquier persona. Durante los últimos años, muchas empresas han ampliado su estrategia a estos dispositivos, ya que al llevarlos consigo durante la mayor parte del tiempo, las personas tienden a hacer un uso constante de ellos. RedBorder® es un servicio de monitorización y gestión de eventos orientado a seguridad, y como otras empresas, ha incluido en su estrategia la necesidad de desarrollar una aplicación móvil para agregar más valor al producto. De esta idea nace redBorder Mobile, una aplicación móvil para Android® integrada con su plataforma, para la visualización de datos y notificación en tiempo real de cualquier anomalía en el sistema monitorizado por redBorder®.

Full text

Proyecto Fin de Carrera Ingeniería de Telecomunicación Formato de Publicación de la Escuela Técnica Superior de Ingeniería Autor: F. Javier Payán Somet Tutor: Juan José Murillo Fuentes Dep. Teoría de la Señal y Comunicaciones Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2013 Proyecto Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Desarrollo de la aplicación móvil Android para la plataforma de monitorización y seguridad de redes redBorder Autor: Ángel María de Miguel Meana Tutor: Pablo Nebrera Herrera Dep. Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2015 Proyecto Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Desarrollo de la aplicación móvil Android para la plataforma de monitorización y seguridad de redes redBorder Autor: Ángel María de Miguel Meana Tutor: Pablo Nebrera Herrera Profesor Titular Dep. Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2015 Proyecto Fin de Grado: Desarrollo de la aplicación móvil Android para la plataforma de monitorización y seguridad de redes redBorder Autor: Ángel María de Miguel Meana Tutor: Pablo Nebrera Herrera El tribunal nombrado para juzgar el trabajo arriba indicado, compuesto por los siguientes profesores: Presidente: Vocal/es: Secretario: acuerdan otorgarle la calificación de: El Secretario del Tribunal Fecha: Agradecimientos Re dBorder Mobile ha sido mi primer acercamiento al mundo laboral. No puedo estar más feliz tras esta experiencia, que me ha ayudado a aprender, me ha propuesto nuevos retos, y me ha hecho conocer personas con las que he entablado una gran amistad. Primero agradecer a mi familia el apoyo que me han dado siempre, ayudándome cuando las cosas no han salido como esperaba y celebrando los pasos que he ido dando en estos años. Gracias a mis padres por su educación, dedicación y cariño, me habéis enseñado que con esfuerzo y ganas todo se consigue. Gracias por escucharme y aconsejarme siempre, sois mi ejemplo a seguir en esta vida. También quiero mencionar a mi Tío Eloy, que ha sido como un segundo padre para mí, demonstrándome que es mejor pararte un momento a pensar las cosas y que es muy importante disfrutar. Ya sé que 18 años no se tienen otra vez, pero no te preocupes, tomé tu consejo y los he disfrutado al máximo. Gracias Cristina, por estar siempre a mi lado y apoyarme en cualquiera de mis alocadas ideas. Es muy importante para mi el sentir ese apoyo y poder compartir contigo cualquier cosa que se me pase por la cabeza. Gracias a mis amigos de Jerez, que aunque estemos en la distancia, seguimos encontrándonos y charlamos como si aún cada fin de semana echaramos las horas en la escalerita. También a mis compañeros de facultad, Antonio, Andrés, Carlos, Pedro, Merce, Pablo... con los que durante estos años he compartido experiencias, frustaciones y éxitos. La carrera es difícil pero con amigos cerca todo se lleva mucho mejor. Gracias a los maestros, sin ellos no sería posible que a día de hoy pueda convertir mis ideas en algo tangible. En especial a Pablo, mi tutor y amigo, que confió en mi para desarrollar este proyecto. Por último, quiero agradecer al equipo de redBorder su trato. Entrar en un equipo de trabajo siendo tan joven y ser escuchado es algo muy importante. Gracias a Jose Antonio, Clara y Carlos por enseñarme a comprender mejor Ruby entre charlas y tonterías. Me alegro enormemente de formar a día de hoy parte de esta familia. Ángel María de Miguel Meana Sevilla, 2015 I Resumen Los dispositivos móviles son parte del día a día de cualquier persona. Durante los últimos años, muchas empresas han ampliado su estrategia a estos dispositivos, ya que al llevarlos consigo durante la mayor parte del tiempo, las personas tienden a hacer un uso constante de ellos. RedBorder ® es un servicio de monitorización y gestión de eventos orientado a seguridad, y como otras empresas, ha incluido en su estrategia la necesidad de desarrollar una aplicación móvil para agregar más valor al producto. De esta idea nace redBorder Mobile, una aplicación móvil para Android ® integrada con su plataforma, para la visualización de datos y notificación en tiempo real de cualquier anomalía en el sistema monitorizado por redBorder®. III 1 Introducción Re dborder es un sistema de gestión de seguridad de código abierto basado en tecnologías de Big Data, desarrollado por ENEO Tecnología. Este proyecto se divide en dos versiones: una versión ``Community'' de código libre; y una versión ``Enterprise'' orientada a empresas. RedBorder cuenta con un gestor web que permite tanto la visualización de datos como la gestión de la infraestructura. Este gestor es muy completo, ofreciendo mucha variedad opciones a la hora de representar los datos, lo que engloba una gran cantidad de casos de uso. No obstante, en dispositivos móviles el ofrecer demasiadas opciones puede tener un efecto negativo, ya que el espacio disponible es menor y por lo tanto es más complicado navegar. 1.1 Motivación y objetivos Definición 1.1.1 (Proactividad) La proactividad es la capacidad de prevenir errores mediante detección temprana de anomalías, evitando que lleguen a convertirse en fallos. Según Fault, Configuration, Accounting, Performance and Security (FCAPS) 1 , en la gestión de fallos es imprescindible abarcar cualquier problema desde dos enfoques: • Proactividad: según la Definición 1.1.1, la alerta temprana de problemas de seguridad como tráfico anómalo desde un equipo o alta intensidad de tráfico hacía un servidor, es importante a la hora de lidiar con ataques malintencionados a nuestra red. • Reactividad: una vez se ha detectado un problema, las alarmas saltan y cada minuto es crucial para mitigar un ataque. Por ello es necesaria una rápida notificación a los encargados de la gestión de la red. La falta de visibilidad y la lentitud a la hora de responder ante un problema puede acarrear problemas económicos y de imagen de la propia empresa. Las pérdidas ecónomicas pueden ser directas, debido a un robo de cuentas bancarias o indirectas, debido a la pérdida de confianza de los usuarios. Es en este escenario cuando entra en juego la idea de `2/"Q`/2` JQ#BH2 . En la actualidad no hay persona que no salga de su casa con un dispositivo móvil inteligente en el bolsillo. Aprovechando esta ventaja, se presenta la posibilidad de desarrollar una aplicación móvil que permita al usuario tener un cierto control sobre los sistemas de gestión de redBorder. RedBorder Mobile se enfoca desde el punto de vista de la visualización de datos y la explotación de las notificaciones en tiempo real. Entre los miembros del equipo de redBorder y el autor del proyecto diseñamos una interfaz adaptada a pantallas móviles y tabletas en la cual representar los datos más relevantes. Como se explicará más adelante, para que el usuario se familiarize con la aplicación móvil rápidamente, la estructura de las vistas es similar a la del gestor web. El motivo de ignorar la configuración es debido a la complejidad de redBorder, la cual dificultaría su manejo a través de una interfaz móvil. Introducir gran cantidad de datos en una interfaz tan pequeña puede favorecer a que el usuario cometa fallos causando la inestabilidad del sistema. De este modo, planteamos un claro objetivo: ofrecer a un usuario de redBorder la posibilidad de tener en su mano la información relevante de su infraestructura en los casos en los que este no disponga de un ordenador, y ser notificado en el momento en el que ocurra una irregularidad en su red. 1FCAPS es un modelo de gestión de redes de telecomunicaciones desarrollado por la ISO 1 2Capítulo 1. Introducción 1.2 Plataforma móvil Dentro del marco de plataformas móviles encontramos una gran variedad con una clara dominancia de los sistemas operativos Android ® eiOS ® . La primera intención del equipo es el desarrollo de una aplicación multiplataforma utilizando el método de la encapsulación de aplicaciones web como aplicaciones móviles nativas. Durante dos semanas, trabajamos en el desarrollo hasta que encontramos un problema de rendimiento. La aplicación debe de soportar un gran procesamiento de datos, por ejemplo, estimamos que para mostrar una gráfica deberíamos de aplicar escalas y procesamientos de fecha a más de 200 eventos por petición. Dada la velocidad de los procesadores de javascript, se hacía inviable desarrollar una aplicación ágil y rápida. En este punto, tomamos la decisión de desarrollar una aplicación nativa. Barajamos la plataforma que escogeríamos para el desarrollo y tras una reunión, se pivotó la idea hacía el desarrollo de la aplicación para la plataforma de Android ® . La principal causa de esta decisión fuero los comentarios de los clientes actuales de redBorder, entre los cuales, había una clara dominancia del sistema operativo Android®. 1.3 Metodología de trabajo La integración de una aplicación móvil con una plataforma requiere del trabajo en equipo de los desarrolladores de ambas partes. Para poder realizar esta tarea de manera sincronizada, se acordó la manera de interconectar la aplicación móvil con el gestor web para poder acceder de manera rápida y eficiente a los datos. Los detalles se especifican en el tercer capítulo de este documento. Para trabajar en equipo, se han realizado reuniones presenciales cada 15 días, para acordar nuevas vías de mejora y hablar sobre el estado del proyecto. También se ha utilizado la herramienta de comunicación vía voz sobre IP, aFvT2. 2 RedBorder Re dBorder es una aplicación compleja que engloba muchos conceptos. Es importante dedicar un poco de tiempo a definir algunos de estos, ya que serán necesarios posteriormente. El gestor web está dividido en diversos módulos que se adaptan a las necesidades de cada cliente. Estas necesidades pueden ir desde la monitorización interna de una red empresarial para la prevención de problemas de seguridad; hasta la gestión de una red WiFi de un centro comercial. Ambos ejemplos definen dos casos de usos bastante diferentes que son cubiertos gracias a las distintas partes de las que está compuesta la aplicación. En la Figura 2.1 se muestra una captura de pantalla de un supuesto escenario de gestión de puntos de acceso WiFi en la ETSI. Figura 2.1 Ejemplo de la aplicación para la gestión de puntos de acceso WiFi. Actualmente, los módulos que incluye RedBorder son: •redBorder IPS: sistema IDS/IPS para detección y actuación frente a problemas de seguridad. • redBorder Flow: colector de tráfico de red, correlando la información recibida con la proporcionada por los enrutadores WiFi (como posicionamiento). De esta manera obtenemos una visión tanto a nivel de red de datos como espacial. • redBorder Monitor: monitor de recursos de las máquinas conectadas. Ofrece información de capa física como la carga de CPU o la velocidad de los ventiladores; y de la capa de red, como los paquetes recibidos y enviados. 2.1 Eventos Definición 2.1.1 (Evento) conjunto de información asociada a un suceso real que se almacena y mantiene una estructura establecida. Se puede realizar una analogía con la programación orientada a objetos, siendo la estructura la clase y el evento un objeto instanciado. 3 4Capítulo 2. RedBorder Los eventos son la base de RedBorder, ya que representan la información recolectada, procesada y almacenada. Cada tipo de evento está organizado en columnas, ofreciendo cada una de ellas información adicional sobre el suceso. Por ejemplo, podemos definir que cada evento de tráfico de red contendrá información sobre la dirección IP origen y la dirección IP destino, quedando así definida la estructura. Las direcciones son las columnas de este tipo de eventos, mientras que el conjunto de dirección origen igual a 192.168.1.1 y destino 192.168.1.2 sería un evento de tráfico. 2.1.1 Druid Definición 2.1.2 (Granularidad) en almacenamiento de datos, se define como una unidad de detalle de los datos. Partiendo de datos que pueden ser agrupados, la granularidad especifica el nivel de agrupación de estos datos. A mayor granularidad, mayor agrupación y menor detalle. Cuanto más baja es la granularidad, menor es la agrupación y mayor el detalle. Los eventos son almacenados en una base de datos de tipo On-Line Analytical Processing (OLAP), llamada Druid ® . No es objetivo de este trabajo el describir este tipo de base de datos, no obstante, es interesante explicar las bases de Druid®para comprender algunas ideas. La gran ventaja de este tipo de bases de datos, es que además de almacenar eventos, realizan cálculos sobre ellos creando resúmenes más rápidos de consultar. En Druid ® el término de granularidad está relacionado con el tiempo. La granularidad mínima es el mínimo tiempo de separación entre eventos, los que define el detalle máximo que podemos obtener. Es decir, a menor granularidad, mayor coste computacional y mayor necesidad de almacenamiento. En redBorder la granularidad mínima de los eventos es de un minuto, por lo que por su definición, podremos obtener como máximo el minuto en el que ocurrió un evento, pero no el segundo. Esta granularidad cubre la gran mayoría de los casos de uso y a su vez es suficientemente rápida para que las peticiones de datos no tarden excesivamente. De esta manera, cuando solicitamos datos, especificamos el intervalo de tiempo en el que queremos obtener los eventos, así como la granularidad. 2.2 Gestor web El gestor web es la herramiento principal para la consulta de datos y gestión de la infrastructura de redBorder. Este incluye numerosas vistas de configuración, aunque en este caso nos centraremos las dos vistas utilizadas en la aplicación móvil. 2.2.1 Vista de RAW Definición 2.2.1 (RAW) formato de ficheros que representa información tal y como es recibida. Muy utilizado en el lenguaje fotográfico para referirse a imágenes sin compresión alguna. Definición 2.2.2 (Vista RAW) vista en la cual se muestran los eventos tal y como se reciben, ordenados por el tiempo de llegada e incluyendo los datos asociados. Una manera de visualizar los eventos almacenados en el sistema es tal y como llegan a este, sin nungún tipo de filtro visual ni agrupación. Partiendo de la Definición 2.2.2, este tipo de vista nos permite visualizar en tiempo real todo lo que esta sucediendo en nuestro sistema. En el momento en el que agrupamos los elementos por columnas o ejercemos una ordenación o filtro, perdemos la visión global de lo que ocurre en nuestro sistema. Por ello, es especialmente útil para conocer la evolución actual de nuestro sistema, permitiendo ver los eventos que estamos recibiendo. En la figura Figura 2.2 tenemos un ejemplo de la vista RAW en el gestor web. 2.2.2 Vista de Tops Definición 2.2.3 (Top) valor que está por encima de otros basándose en una determinada referencia. Definición 2.2.4 (Vista Tops) vista en la que se agrupan los eventos por columnas, ordenándolos descendentemente en función del número de eventos o tráfico generado. 2.2 Gestor web 5 Figura 2.2 Vista de RAW del módulo Flow en el gestor web. Otra forma de visualizar los datos consiste en priorizar aquellos que han destacado en un periodo de tiempo. Esto nos ofrece la posibilidad de comprobar rápidamente los eventos más destacados en nuestro sistema en función de la columna que deseemos. En la figura Figura 2.3 tenemos un ejemplo de la vista RAW en el gestor web. Figura 2.3 Vista de Tops respecto a la columna de dirección IP origen del módulo Flow en el gestor web. 3 Integración con el gestor de redBorder La recepción de los datos en el dispositivo móvil debe de ser rápida y unificada. Para la definición de la interfaz de programación de la aplicación (más conocida en inglés por las siglas API), decidimos escoger una interfaz del tipo Representational State Transfer (REST). 3.1 REST Definición 3.1.1 (Recurso) estructura de datos interrelacionados entre si que representan un ente relevante de información para un usuario de la aplicación. Definición 3.1.2 (REST) define un conjunto de principios de arquitectura de información para diseñar servicios en línea basados en los recursos que ofrece dicho sistema y en los estados de estos. Para ello se basa en los distintos métodos definidos en el protocolo Hypertext Transfer Protocol (HTTP) (GET, POST, PUT, PATCH, DELETE) asignándolos las acciones de obtener, crear, actualizar y borrar los recursos. Los recursos son expuestos mediante una URL y ofreciendo su respuesta en formato XML o JSON. La simpleza y la orientación a los propios recursos contenidos en el servidor, han sido las razones por las que se ha elegido esta guía para el desarrollo de la interfaz de acceso. Conviene destacar que gran parte de la potencia de REST se pierde en este proyecto, ya que solo se aprovecha la obtención de datos (peticiones de tipo GET) puesto que no es el objetivo de la aplicación móvil cambiar el estado en los recursos almacenados en el servidor. Se detallará más adelante algunas peticiones concretas que necesitan ser de tipo POST. Existen otras alternativas como el lenguaje de descripción de servicios web (más conocido por su acrónimo en inglés, WSDL). Este tipo de soluciones se basan en el protocolo SOAP, definido por la organización W3C, actualmente en desuso debido a su complejidad. 3.2 Acceso a los recursos Se define la interfaz de acceso a la aplicación a través de la dirección base ?iiTUbV,ffI/B`2++BƟM /2H ;2biQ`=fTBfIp2`bBƟM miBHBx/=f. Un ejemplo de dirección base válida es: http://gestor.empresa.com/api/v1/ Como se especifica en REST, las rutas web deben de hacer referencia a los recursos y a las posibles acciones estos. Dentro de redBorder encontramos actualmente tres tipos de recursos: IPS, Flow y Monitor. Estos pueden devolverse de varias maneras en función del tipo de petición que se realice. 3.2.1 Identificación de usuarios en las peticiones Definición 3.2.1 (Identificador) cadena alfanumérica aleatoria. 7 8Capítulo 3. Integración con el gestor de redBorder Para acceder a cualquier información en el gestor web es necesario iniciar sesión con el nombre de un usuario y su contraseña. En el caso de la aplicación móvil, para evitar la petición de la contraseña del usuario cada vez que se accede a un servidor se ha optado por una autenticación mediante un identificador. La primera vez que un usuario inicia sesión en un servidor desde la aplicación móvil, se solicitan sus credenciales. Después de validar dichas credenciales y en caso de ser correctas, se retorna en la respuesta el identificador del usuario. Para agregar una mayor seguridad al acceso a la API de redBorder, desde el gestor es posible volver a generar un nuevo identificador cuando sea necesario. Esta acción invalida cualquier petición posterior que contenga el identificador antiguo, por lo que el usuario deberá de volver a introducir las credenciales de acceso en la aplicación móvil. Este parámetro se enviará con el identificador mi?niQF2M en la URL de la petición, quedando el formato de todas las peticiones como se indica en la Tabla 3.1. Tabla 3.1 Formato general de las peticiones. URL ?auth_token=<identificador> Tipo de llamada GET, POST, PUT, PATCH, DELETE Parámetros Identificador cadena de identificación del usuario Al estar este parámetro presente en todas las peticiones a excepción de la de inicio de sesión, se obviará su presencia en el formato de las peticiones que se exponen a continuación. Inicio de sesión Este petición identifica al usuario dentro del gestor de redBorder. Si la autenticación es correcta, el usuario obtendrá su identificador. El formato de esta petición es el definido en la Tabla 3.2 Tabla 3.2 Formato de la petición de inicio de sesión. URL users/login?user[username]=<nombre usuario>&user[password]=<contraseña>&user[gcm_id]=<identificador de notificaciones> Tipo de llamada POST Parámetros Nombre de usuario Cadena de texto con el nombre de usuario o el email Contraseña Cadena de texto con la contraseña del usuario Identificador de notificaciones Identificador del dispositivo para el envío de notificaciones. Se explica su implementación en la Subsección 5.4.7 3.2.2 Vista RAW Definición 3.2.2 (Vista) interfaz asociada a una pantalla de la aplicación, por ejemplo, un formulario para iniciar sesión o una lista de elementos. Cada vista está compuesta de multiples elementos gráficos. En este tipo de visualización la organización de los eventos se realiza en función del tiempo de llegada de estos. En la aplicación móvil, el usuario puede seleccionar la granularidad con la que se mostrarán los eventos en función del detalle que este necesite. Eventos en formato de lista Las peticiones de eventos para la vista de lista de RAW siguen el formato expuesto en la Tabla 3.3.Eneste caso, los módulos de los que podemos obtener los datos son Flow e IPS. El segundo parámetro es la ;`MmH`B// . Esta se envía codificada, atribuyendo a cada granularidad de tiempo un símbolo comprensible por el gestor. Véase Tabla 3.4 El tercer y cuarto parámetro, Q77b2i y 2M/niBK2 , se utilizan para paginar. Para evitar una gran cantidad de datos en una sola petición, se ha limitado el número de elementos devueltos. Cuando el usuario llega al final de la lista, aparece un icono que indica que se están cargando más resultados mientras la aplicación espera la respuesta del servidor. Para ello el servidor segmenta el tiempo en función de la granularidad y retorna los eventos en grupos de veinticinco elementos. 3.2 Acceso a los recursos 9 Tabla 3.3 Formato de peticiones de eventos en lista de tipo RAW. URL modules/<modulo>/?granularity=<granularidad>&offset=<desfase>&end_ti- me=<tiempo> Tipo de llamada GET Parámetros Modulo Nombre del módulo del que se desea obtener la información Granularidad Cadena de texto con la granularidad Desfase Numero de elementos ya recibidos Tiempo Tipo entero largo que representa el tiempo. El formato es UNIXTIME Tabla 3.4 Correspondencia de granularidades y símbolos del gestor. Granularidad Símbolo 1 minuto minute 5 minutos pt5m 15 minutos fifteen_minute 30 minutos thirty_minute 1 hora hour 8 horas pt8h 1 día pt24h 1 semana pt168h 1 mes pt720h En cada respuesta, el servidor indica el instante de tiempo y cuantos elementos ha devuelto. Estos valores son los que han de enviarse en la siguiente petición como Q77b2i y 2M/niBK2 , para que el servidor tenga constancia del evento en el que se quedó. Eventos como serie temporal Estas peticiones son utilizadas para representar los datos de manera gráfica. En este caso, el servidor solo devuelve el número de eventos o tráfico generado. Al no retornar ninguna columna, la petición es considerablemente más rápida. Las peticiones de este tipo tienen el formato definido en la Tabla 3.5. Tabla 3.5 Formato de peticiones de serie temporal para RAW. URL modules/<modulo>/raw_serie?granularity=<granularidad>&start_ti- me=<tiempo inicial>&end_time=<tiempo final> Tipo de llamada GET Parámetros Modulo Nombre del módulo del que se desea obtener la información Granularidad Cadena de texto con la granularidad Tiempo inicial y final Tipos de entero largo que representan el intervalo de tiempo en el que se debe de calcular la serie temporal. El formato de ambos es UNIXTIME Detalles de un evento Para obtener los detalles de un evento concreto, debemos de identificarlo en el servidor. Es necesario incluir en esta petición los distintos valores de las columnas del evento. Incluyendo múltiples valores y el tiempo en el que ha ocurrido dicho evento, podemos delimitarlo y obtener todos sus detalles. El formato de este tipo de peticiones es el definido en la Tabla 3.6. 3.2.3 Vista Tops En este caso, las peticiones deben de especificar la columna y el intervalo de tiempo. En el gestor, el usuario puede modificar la granularidad, como ocurría en las peticiones de tipo RAW. No obstante, para aliviar la 16 Capítulo 4. Interfaz Figura 4.4 Vista de una gráfica con el móvil en posicion horizontal. 4.4.1 Iniciar sesión en un gestor nuevo Esta sección permite la autenticación de un usuario en un nuevo gestor. Para ello, la vista dispone de un formulario que permite validar la identidad del usuario con el fin de acceder a los recursos en los que tiene permisos. La identidad del usuario debe ser única, por lo que los campos del formulario deben de ser suficientes para poder identificarlo unívocamente. En primera instancia, la vista se diseñó con dos campos, como podemos ver en Figura 4.5. Los campos fueron: •Dirección del gestor: dirección IP o URL del gestor redBorder a la que se quiere conectar. • Identificador de usuario: cadena aleatoria generada en el gestor que identifica de manera unívoca a un usuario. Figura 4.5 Esquemático de la primera versión de la vista de inicio de sesión. 4.5 Vistas de RAW 17 Con estos campos un usuario quedaba totalmente identificado, pero el identificador es excesivamente largo para ser copiado a mano y muy difícil de recordar. No obstante, este identificador es necesario ya que todas las peticiones al gestor lo deben de incluir. Es por ello que, como se ha comentado en el capítulo anterior, se optó por la autenticación por usuario y contraseña. Una vez que la autenticación es correcta, el gestor devuelve el identificador asociado a dicho usuario y se almacena en el dispositivo mediante el gestor de cuentas de Android ® . El prototipo final de esta vista, así como su implementación es el mostrado en la Figura 4.6. Figura 4.6 Prototipo junto con la implementación final del formulario de inicio de sesión. Siguiendo la línea de otras aplicaciones, de cara a ayudar a los usuarios a manejar la aplicación se han planteado los títulos de los elementos del formulario como preguntas. Este formulario al tener pocos elementos es un buen escenario para utilizar preguntas como títulos, ya que en otros más extensos esta técnica puede fatigar al usuario. 4.4.2 Inicio de sesión con gestores almacenados Esta vista mantiene la misma estética que el formulario de inicio de sesión, situando el logo en la parte superior y la información a continuación. Tenemos una lista con las credenciales de los gestores a los que se ha accedido previamente y en la zona inferior un botón para agregar nuevos gestores. La información ofrecida sobre los gestores es la dirección de estos y el nombre de usuario con el que se accede. Se permite almacenar varios usuarios para un mismo gestor. Una vez implementado el esquema en la vista, realizamos varias mejoras sobre esta. Se redujo el tamaño del logo para dejar más espacio a la lista y se eliminó el color de fondo de la lista ya que el resultado era más estético. Por otra parte, el botón se personalizó siguiendo la guía de colores de redBorder. Podemos ver el prototipo y el resultado final de la lista en la Figura 4.7 4.5 Vistas de RAW Dentro del gestor de redBorder, cada módulo posee su propia vista RAW donde se listan los eventos correspondientes. Esta vista la conforman dos componentes: 18 Capítulo 4. Interfaz Figura 4.7 Prototipo junto con la implementación final de la vista de inicio de sesión con gestores almacenados. • Gráfica: muestra una gráfica con la evolución del número de eventos con respecto al tiempo de llegada. Esta gráfica nos indica la evolución del sistema durante la ventana de tiempo que tengamos seleccionada. •Lista de eventos: listado con los eventos recibidos. Al igual que con la vista Tops, que se detallará más adelante, se ha realizado una adaptación de estas para mostrar solo la información más relevante, dejando la interfaz limpia y fácil de leer. 4.5.1 Menú de configuración En la vista RAW, este menú nos permite modificar la granularidad de los eventos que recibimos, agrupando en mayor o menor medida los eventos. Las granularidades disponibles en la vista RAW son: • 1 minuto • 5 minutos • 15 minutos • 30 minutos • 1 hora • 8 horas • 1 día • 5 días • 1 semana 4.5.2 Lista de eventos La lista de eventos muestra la información relevante de cada uno de ellos. Dado que cada módulo tiene distintas columnas para sus eventos, la información ofrecida está personaliza en función de las columnas disponibles. No obstante, todos siguen la estructura definida en la Figura 4.8. Para los eventos del módulo IPS, es decir, eventos de seguridad, se ha destacado la gravedad, traza y sensor que lo ha detectado. Resaltando estos elementos en la lista conseguimos de un vistazo la información 4.5 Vistas de RAW 19 Figura 4.8 Estructura de la lista de eventos para la vista RAW. más relevante. Como observamos en la implementación de esta vista en la Figura 4.9, la gravedad destaca visualmente, ya que consideramos que en primera instancia, es la información más importante asociada a un evento. Figura 4.9 Implementación de la vista RAW para el módulo de IPS. 20 Capítulo 4. Interfaz A continuación, tenemos la lista completa de información de cada evento del módulo IPS: • Severidad: situada a la izquierda de cada fila de la lista, se representa con un número del uno al tres, dependiendo de la gravedad del evento. • Traza del evento: descripción del evento de seguridad. Para resaltarlo se ha utilizado una tipografía en negrita. •Sensor que detecta el evento: nombre del sensor. • Hora del evento: fecha en la que se ha producido el evento. Si el día en el que ha ocurrido el evento es el actual, solo se muestra la hora y el minuto. En otro caso, se muestra también el día. • Número de eventos: número de veces que se ha producido un evento en la granularidad seleccionada. Para los eventos de tráfico del módulo de Flow, se ha destacado la información de la capa de red. En este caso, resaltamos el protocolo utilizado, así como la dirección origen y destino de paquete. Para especificar el sentido de la comunicación, se ha diseñado el icono situado a la izquierda de las direcciones IP. Podemos ver la implementación final de esta vista en la Figura 4.10 Figura 4.10 Implementación de la vista RAW para el módulo de Flow. Las lista completa de las columnas de cada evento incluidas en esta vista para el módulo Flow es la siguiente: •Protocolo: muestra el nombre del protocolo que se ha utilizado en la comunicación. •Dirección IP origen y destino. • Hora del evento: fecha en la que se ha producido el evento. Si el día en el que ha ocurrido el evento es el actual, solo se muestra la hora y el minuto. En otro caso, se muestra también el día. •Tráfico del evento: número de bytes que ha generado el evento. Para hacer transparente la paginación al usuario, esta lista implementa la técnica de lista infinita.Esta consiste en que cuando el usuario está llegando al final de la lista, se comienza a cargar el siguiente grupo de eventos. Claros ejemplos de uso de esta técnica son las aplicaciones de Twitter®e Instagram®. También se ha querido agregar la funcionalidad de cargar nuevos eventos. Cuando entramos en esta vista, la lista comienza a pedir eventos a partir del momento actual hacia atrás. Pasado un tiempo, es posible que hayan llegado nuevos eventos, por lo que es muy importante poder recibirlos sin necesidad de volver a 4.6 Vistas de Tops 21 cargar la vista entera. Para ello, se implementa otra téctica muy utilizada, tirar y refrescar. De este modo, la interacción para cargar nuevos elementos consiste en deslizar el dedo hacía abajo en el principio de la lista. Al levantar el dedo la lista comenzará a actualizarse. Véase la Figura 4.11. Figura 4.11 Vista cargandor tras realizar la acción de deslizar el dedo ``arrastrando'' la lista para obtener nuevos elementos. 4.5.3 Gráfica de evolución Para la vista RAW, la gráfica muestra la evolución temporal de los eventos que han sido detectados. Estas gráficas ofrecen una visión de la tendencia del número de eventos en nuestro sistema. Gracias a este gráfico, es fácil visualizar comportamientos inusuales, ya que al poder cambiar la ventana temporal podemos comparar un rango de tiempo con situaciones pasadas. Para el módulo de Flow, como muestra la Figura 4.12, el eje de ordenadas representa el total de tráfico en bytes en un instante determinado. En el caso del módulo IPS, , este eje representa el número de eventos que han sucedido en un instante. 4.5.4 Detalles de un evento Como se ha comentado, en las vistas de la aplicación móvil se ha reducido la información ofrecida, pero cada evento tiene una gran cantidad de información asociada. Para satisfacer la necesidad de conocer todos los detalles, se ha diseñado una vista con todos los datos asociados. Tras el prototipado y una primera versión, se incorporó un botón en la barra superior de navegación para compartir el detalle de un evento. Este botón genera la URL necesaria para identificar un evento en el gestor correspodiente. En la Figura 4.13 podemos ver el prototipo y la implementación final de esta vista. 4.6 Vistas de Tops A diferencia de la vista RAW en el que establecemos una granularidad y vamos cargando nuevos eventos a medida que alcanzamos el final de la lista, en la vista Tops establecemos una ventada de tiempo. En el gestor existen unas ventanas de tiempo predefinidas, además de la opción de escoger cualquier período de tiempo. En la aplicación móvil hemos restringido las ventanas de tiempo a los siguientes valores: 22 Capítulo 4. Interfaz Figura 4.12 Gráfico de la vista RAW del módulo Flow. Figura 4.13 Prototipo y versión final de la vista de detalles de eventos RAW, incluyendo el botón de compartir. • Última hora. • Últimas tres horas. • Últimas 24 horas. • Última semana. •Último mes. • Último año. 4.6.1 Menú de configuración En la vista Tops, este menú nos permite modificar la columna de la que queremos obtener la información. Las columnas varían en función del módulo, ya que vienen definidas por el tipo de evento que se recibe. El el caso del módulo Flow, el número de columnas asociadas a cada evento es grande, por lo que se han agrupado estas bajo categorías para mejorar la navegación. Al pulsar en los títulos de las categorías estas se 4.6 Vistas de Tops 23 expanden permitiendo seleccionar la columna que deseemos. La implementación final la podemos ver en la Figura 4.14. Figura 4.14 Menú de configuración de la vista Tops con algunas categorías expandidas. 4.6.2 Lista de eventos Esta vista agrupa la información por columnas, por lo que en este caso, la estructura de los elementos de la lista de eventos son prácticamente idénticos. La única diferencia entre los módulos de IPS y Flow es el total. La información que representa cada elemento es: • Porcentaje: porcentaje que representa dicho valor de una columna con respecto al total de eventos o tráfico generado por dicha column en un período de tiempo definido. •Valor de la columna. • Total: en el módulo IPS, el número de veces que se ha producido un evento con dicho valor para la columna seleccionada en la ventana de tiempo actual. En el caso del módulo Flow, este valor es el número de bytes generados con dichas condiciones. En esta vista nos encontramos con la problemática de definir la ventana de tiempo que se quiere utilizar. Descartamos colocar esta opción en el menú de configuración, ya que para esta vista, el listado de columnas puede ser largo por lo que se prefirió no introducir seis elementos más al menú. Finalmente diseñamos esta vista como un panel deslizante de Android ® . Este tipo de interfaz nativa permite definir varias vistas accesibles de forma lateral, es decir, deslizando con el dedo a izquierda y derecha para movernos. Este tipo de vistas las utilizamos cada día, solo debemos de pensar en el escritorio de Android ® en el que nos movemos de forma lateral. Combinando estas ideas, en la Figura 4.15 podemos ver el prototipo final de la vista es el mostrado junto con su implementación final. En la implementación final, el porcentaje pasó de incluir el valor numérico, a ser indicado visualmente mediante las líneas azules posicionadas en la zona superior de cada evento. 4.6.3 Gráfica y filtrado Al igual que en la vista RAW, al colocar el móvil en posición horizontal obtenemos una vista gráfica con la evolución temporal de los eventos de la ventana de tiempo que tengamos seleccionada. 24 Capítulo 4. Interfaz Figura 4.15 Prototipo de la vista Tops junto con la implementación final de esta. Para este tipo de vista es interesante conocer la evolución de cada valor de las columnas de un evento por separado, pudiendo comparar varios valores de una columna en la ventana temporal elegida. Con el fin de poder vistualizar estos valores por separado, se permite al usuario seleccionar varios elementos en la vista de lista (posición vertical). Una vez seleccionados, al girar el móvil obtenemos la gráfica de cada valor. Cada uno de ellos se identifica con un color, como se puede ver en la figura Figura 4.16. Figura 4.16 Gráfica de tops con varios valores para la columna de dirección IP origen en la última hora. 4.7 Alarmas 25 4.7 Alarmas La sección de alarmas es muy importante en la aplicación móvil y por ello se ha incluido un icono para acceder a ella en la barra superior de navegación de las vistas Tops y RAW. Este icono despliega una lista con las alarmas actuales, destacando el fondo que las que aún no han sido leídas. Las alarmas se definen en el gestor, donde se les atribuye un nombre y las condiciones para que sean lanzadas. Cada alarma incluye un límite superior o inferior, el cual se debe de sobrepasar durante un intervalo de tiempo, también definido en el gestor. Es posible aplicar filtros a los eventos para acotar más la alarma, ya que cuanto más concisa sea una alarma, menor será el número de falsos positivos. En primera instancia se diseñó la vista de manera compacta, para poder visualizar varias alarmas sin tener que desplazarnos por la lista. Los datos mostrados sobre la alarma fueron: el nombre de esta y el valor numérico y la hora en la que fue lanzada. Tras un tiempo de uso, decidimos que la información era confusa ya que no mostraba ninguna relación del valor numérico con respecto al límite definido. Por ello se incluyeron varios campos, quedando los siguientes campos de la alarma: •Nombre: nombre de la alarma definido al crearla en el gestor. •Límite: límite numérico definido en el gestor para esta alarma. • Valor: valor númerico de la alarma en el momento en el que fue lanzada. También incluye el porcentaje que la alarma ha sobrepasado con respecto al límite. • Intervalo de lanzamiento: se sustituye la hora por el intervalo, ya que en el gestor se establece el intervalo de tiempo durante el que el valor numérico debe sobrepasar el límite. • Gravedad de la alarma y tipo: incluye el tipo de la alarma (si es de límite superior o inferior), sobre un fondo del color de la gravedad de la alarma. El gestor y la aplicación móvil comparte la gama de colores para indicar la severidad de una alarma. Otro problema encontrado fue la gran cantidad de alarmas que se mostraban en la lista. Una vez que se ha solventado el problema por el que la alarma se ha lanzado, no tiene sentido seguir almacenando esta. Se agregó un botón al final de cada elemento de la lista para borrar la notificación. Finalmente, en la figura Figura 4.17 podemos ver el prototipo inicial y como fue implementada. 4.8 Monitorización La información que recibimos a través de sensores y distintos elementos de red es crucial, pero estos nodos también deben de ser monitorizados, ya que la desconexión o saturación de alguno de ellos puede provocar pérdidas en nuestro sistema. 4.8.1 Árbol de nodos Muestra la estructura de sensores y dominios que el usuario autenticado puede visualizar. Al igual que el menú de configuración de la vista Tops, esta estructura es navegable permitiendo expandir el árbol al pulsar sobre los distintos elementos. Al pulsar sobre un nodo con entidad física, como un sensor, la aplicación redirige al usuario a la vista de información sobre el nodo, donde entontramos distintas métricas sobre el estado de este. 4.8.2 Mapa de nodos Desde el gestor se puede indicar la posición física de un nodo mediante sus coordenadas geográficas. Es por ello que la aplicación también incluye un mapa para visualizar los nodos de esta manera. Al pulsar sobre un nodo en el mapa, se despliega una ventana con la información básica. Al pulsar sobre esta ventana nos muestra la vista de información sobre el nodo. El problema de esta vista, es que los nodos pueden no disponer de su posición geográfica, por lo que no aparecerán en el mapa. Es por ello que esta vista es un complemento a la vista de árbol, ya que en esta si se muestran todos. 4.8.3 Información sobre el estado de un nodo El gestor de redBorder, así como los sensores incluyen una serie de monitores físicos y virtuales. Existen múltiples tipos de monitores, siendo los más utilizados: 32 Capítulo 5. Implementación 5.2.1 ActiveAndroid ActiveAndroid es una librería de conversión de objetos de Java a entidades de una base de datos relacional. Este tipo de librerías son más conocidas por sus siglas en inglés: Object-Relational mapping (ORM). Es de código abierto y su documentación está disponible en [7]. Esta librería abstrae al programador de la necesidad de definir la conexión, cadenas de comandos y creación de la base de datos, es decir, toda integración con esta queda relegada a la librería que incluye métodos para crear, borrar y editar tuplas. Se utiliza para la gestión de las alarmas almacenadas en el dispositivo móvil. Rendimiento en la inicialización de la aplicación Se detectó un problema a la hora de iniciar la aplicación y es que esta librería comprueba todos los ficheros del proyecto. El problema es que esta comprobación incluía también a las librerías externas, como la de compatiblidad con versiones anteriores de Android®, lo que ralentizaba en gran medida la carga. Para solventar este problema, se duplicó esta librería localmente y se agregó una opción para deshabilitar la comprobación de librerías externas. Este cambio se propuso al creador de la librería, y a día de hoy se está conversando sobre su inclusión. Para más información sobre el estado de esta conversación: https: //github.com/pardom/ActiveAndroid/pull/247. Dada la necesidad de reducir el tiempo de carga, la librería que se está utlizando actualmente en el proyecto es la versión modificada, disponible en https://github.com/Angelmmiguel/ActiveAndroid. 5.2.2 Restrung Las peticiones y respuestas del gestor se realizan en formato JSON. Para trabajar con los resultados, es necesario convertir la cadena de texto de la respuesta a variables de Java ® . Una manera de realizar esta conversion es mediante la clase CaPLP#D2+i. No obstante, trabajar con este tipo de objetos es tedioso y muy poco intuitivo. _2bi`mM; es una librería para gestionar peticiones a un servidor y convertir la respuesta en formato JSON a objetos de Java. Para ello, creamos una clase que extiendiendo de #bi`+iCaPL_2bTQMb2 , define la estructura del objeto JSON de la respuesta. Cuando realicemos peticiones al servidor, _2bi`mM; convertirá la respuesta a instancia de dicha clase. Actualmente la librería ha cambiado su nombre a Appsly Android REST, pero al cambiar la estructura de las peticiones, se mantuvo la versión anterior. Esta librería es de código abierto y su documentación está disponible en [6]. 5.2.3 Google Maps Android Libería para la integración de mapas en la aplicación. Esta funcionalidad se utiliza en la vista de monitorización de nodos para la visualización de estos en el mapa, definido en la Subsección 4.8.2. Esta librería requiere de un identificador del servicio, ya que require de la obtención de datos de la aplicación JTb de Google ® . Podemos ver la inclusión de este identificador en el archivo AndroidManifest.xml incluído en el Apéndice B. 5.2.4 AnotherExpandableListView Durante la implementación de la vista de lista de monitorización de nodos se agregaron varias modificaciones a las listas expandibles de Android ® . Para asimilar el diseño a la lista de árbol del gestor, se agregaron flechas a la izquierda de los elementos que incluyen una animación al abrir y cerrar un elemento. El resultado visual fue satisfactorio y muy sencillo de utilizar. Es por ello que se extrajo la funcionalidad agregada en una librería para que cualquier desarrollador de Android®pudiera utilizarla. El código de esta librería está disponible en https://github.com/Angelmmiguel/AnotherExpandableListView. 5.2.5 Android Pull-to-refresh Esta librería provee a la aplicación de un nuevo elemento gráfico, una lista que se puede arrastrar hacía abajo para lanzar un evento de actualización. Esta se utiliza en la mayoría de vistas de lista para actualizar los eventos. Esta librería es de código abierto, y está disponible en https://github.com/naver/android-pull-to-refresh. Su utilización es muy sencilla y permite modificar varios detalles gráficos como el formato visual de la barra de progreso de carga. 5.3 Proyecto de redBorder Mobile 33 Pulsación larga El funcionamiento es similar al de una lista de Android ® ya que incluye deslizamiento por la lista, pulsación de elementos... No obstante, al implementar la vista de Tops, no estaba disponible la opción de pulsación larga en un elemento de la lista. Este evento era necesario para el filtrado de eventos en la vista gráfica. Se realizaron varios cambios sobre la librería y se propusieron al autor de esta. Este los aceptó y ahora esta funcionalidad está disponible para quienes la utilicen. Para más información sobre estos cambios, https://github.com/naver/android-pull-to-refresh/pull/13 Parada de la actualización de la lista Otro problema con esta lista se presentó a la hora de trabajar con la vista gráfica. Cuando se realizaba una actualización mediante arrastre de la lista y se giraba el dispositivo antes de que esta terminara de actualizarse, la aplicación se cerraba debido a un error ya que la lista ya no estaba disponible. Tras estudiar el caso, se agregó un método para parar la actualización de la lista cuando fuera necesario. Este cambio también fue aceptado por el autor de la librería como se puede ver en https://github.com/naver/ android-pull-to-refresh/pull/18. 5.2.6 HoloGraph library HoloGraph es una librería de gráficos para Android. No es la librería de este tipo que más funcionalidad tiene, pero si la más llamativa visualmente. Por esa característica fue la elegida entre varias, además de por ser de código libre. Su documentación está disponible en [5]. Esta librería provee de elementos visuales para generar gráficos de línea, barras y circulares en nuestra aplicación Android®. Su uso se ha limitado a los gráficos de línea para las vistas de RAW y Tops, y gráficos circulares para la vista de detalles del estado de un nodo. Gestión de eventos temporales La manera de trabajar con gráficos de línea en el gestor de redBorder ® es mediante series temporales. En estas, el eje de abcisas representa el tiempo y el de ordenadas el valor de una determinada columna de un evento. Trabajar de esta manera con la librería se hacía muy complejo ya que esta no entiende de series temporales. Para solventar esta dificultad, se duplicó el proyecto de HoloGraph y se introdujeron mejoras para facilitar el trabajo con series temporales. Estos cambios no se propusieron al creador de la librería ya que los requisitos de funcionalidad eran muy específicos para la aplicación de redBorder ® . Es por ello que la librería original siguió avanzando por separado y que actualmente la librería utilizada es la duplicada, disponible en: https://bitbucket.org/ angelmm/holographlibrary 5.3 Proyecto de redBorder Mobile Definición 5.3.1 (Groovy) lenguaje de programación en el que se basa el sistema de automatización Gradle. La aplicación está escrita íntegramente en Groovy, Java y XML, siguiendo la estructura básica de una aplicación Android que incluye: • Carpeta `2b : incluye todos los recursos de la aplicación como imágenes, ficheros de vistas, de idiomas, de menús y de dimensiones. •Carpeta b`+: contiene el código fuente de la aplicación. •M/`QB/JMB72biXtKH: fichero básico de definición de la aplicación. Necesario para Android. •#mBH/X;`/H2: archivo de compilación de Gradle. 5.3.1 AndroidManifest.xml Definición 5.3.2 (Actividad) en inglés Activity, es una clase que gestiona la interacción de un usuario en una parte de la aplicación. Una actividad incluye en una ventana la vista que se debe de cargar, así como uno o varios fragmentos. Cada actividad tiene su propio ciclo de vida. Más información en [1]. 34 Capítulo 5. Implementación Definición 5.3.3 (Servicio) componente de la aplicación sin interfaz gráfica que se ejecuta en segundo plano aunque la aplicación principal se haya cerrado u ocultado. Definición 5.3.4 (Receptor) actividad de la aplicación que puede recibir eventos externos a esta. Estos eventos pueden ser de otras aplicaciones o del propio sistema operativo. Dentro de este fichero necesario para Android®, se deben de registrar: • Todas las +iBpB//2b que conforman la aplicación y pueden ser llamadas e inicidas. • Los permisos, es decir, funcionalidades del dispositivo a las que puede acceder desde la aplicación. • Nombre de la aplicación y una versión numérica, así como un alias de esta en formato de cadena de texto. •a2`pB+BQb que la aplicación utiliza, como la autenticación y el servicio de notificaciones. •_2+2TiQ`2b disponibles en la aplicación. El contenido de este fichero se encuentra en el Apéndice B. 5.3.2 Permisos Definición 5.3.5 (Notificación PUSH) mensajes entre un servidor y una aplicación en el que existe un nodo intermedio que almacena dichos mensajes durante un tiempo hasta que el receptor esté disponible. La lista de permisos disponibles se encuentra en la documentación oficial de Android, concretamente en [4]. De todos ellos, los permisos solicitados por la aplicación son los siguientes: •INTERNET yACCESS_NETWORK_STATE: necesario para conectar con el gestor de redBorder. • AUTHENTICATE_ACCOUNTS,GET_ACCOUNTS,MANAGE_ACCOUNTS yUSE_CREDENTIALS: necesario para el almacenamiento y lectura de las credenciales del usuario para conectar a los distintos gestores. • ACCESS_COARSE_LOCATION,ACCESS_FINE_LOCATION,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE ycom.google.android.providers.gsf.permission.READ_GSERVICE: necesario para el uso de mapas en la vista de elementos monitorizados. • com.google.android.c2dm.permission.RECEIVE: permite a la aplicación recibir notificaciones PUSH. 5.4 Código fuente Para falicitar el desarrollo, se ha organizado el proyecto en múltiples paquetes en función del propósito de las clases que contiene. 5.4.1 Actividades Definición 5.4.1 (Intent) en Android ® , se entienden los intents como una abstracción para solicitar al sistema operativo la realización de una operación. Esta puede ser desde un cambio de actividad, al envío de datos entre aplicaciones. Las actividades de la aplicación se encuentran en el directorio raíz del código fuente. Cada vista con interfaz gráfica tiene como base una +iBpB// que define las funciones básicas de esta e instancia la propia interfaz o los distintos 7`;K2MiQb que la componen. Para cambiar de actividad en Android ® se utilizan los llamados BMi2Mib . Estos nos permiten cambiar de actividad y enviar datos entre estas, como parámetros que el usuario haya introducido o cualquier variable de la actividad anterior. En esta aplicación podemos dividir las actividades en dos tipos: Actividades simples Este tipo de actividades no tienen fragmentos asociados, es la propia actividad la que procesa la interfaz y gestiona todo los eventos de interacción del usuario. Este caso se da en las vistas de inicio de sesión y detalles. 5.4 Código fuente 35 Actividades compuestas Esta estructura más compleja es la utilizada para las vistas de Tops y RAW. En estas vistas la +iBpB// instancia dos 7`;K2MiQb . Uno de ellos procesa la interfaz que corresponde en función de la posición del dispositivo (vista de lista para vertical y gráfico para horizontal). El otro fragmento no tiene interfaz y se encarga de obtener los datos del servidor y almacenarlos temporalmente. 5.4.2 Modelos Los modelos representan la información con la que la aplicación trabaja, como eventos o usuarios. Este concepto se ha extraído del patrón de arquitectura de software Modelo-Vista-Controlador. Todos los modelos se encuentran en el paquete M2iX`2/#Q`/2`X`2/#Q`/2`XKQ/2Hb. La gran ventaja de la utilización de modelos es la integración con las librerías Restrung y ActiveAndroid, ya que las peticiones y las tuplas de la base de datos quedan instanciadas como objetos de estas clases. Generalmente contienen las variables y las funciones de obtención e inicialización de variables. En el caso de los modelos que se inicializan con respuestas del gestor, las clases heredan de #bi`+iCaPL_2bTQMb2 , definida en la librería de Restrung. También heredan de esta las clases que representan los eventos recibidos desde el gestor como _q1p2Mi y _q1p2Mi6HQr . A modo de ejemplo, se incluye la clase de lb2` en el Apéndice C. Las clase de alarmas, incluida en el Apéndice D y que utiliza ActiveAndroid para su gestión, hereda de la clase JQ/2H que establece distintas anotaciones para generar la tabla y las columnas en la base de datos. Dentro de este paquete también se incluyen los modelos utilizados para el procesamiento de menús, concretamemte las clases J2MmAi2K*mbiQK y J2MmAi2K1tTM/#H2*mbiQK . Estas definen todas las propiedades necesarias, así como los constructores para inicializar cada elemento. Como ejemplo se incluye la clase J2MmAi2K*mbiQK en el Apéndice E. 5.4.3 Colecciones Las colecciones representan conjuntos de modelos. Son utilizadas para la recepción de los eventos desde el gestor, por lo que como ocurre con algunos modelos, heredan de #bi`+iCaPL_2bTQMb2 . Además de incluir una variable de tipo GBbi donde se encuentra todos los eventos, también incluye otras necesarias en las peticiones al gestor. Como ejemplo, las variables definidas para los eventos de IPS de la vista RAW son las mostradas en el Código 5.1. Para el caso de los eventos de Flow y la vista Tops solo cambia el tipo de objeto con el que se instacia la variable de tipo GBbi. Código 5.1 Variables definidas para los eventos de IPS de la vista RAW.. Tm#HB+ +Hbb _q1p2Mi*QHH2+iBQM 2ti2M/b #bi`+iCaPL_2bTQMb2 & ff GBbi Q7 2p2Mib T`Bpi2 GBbiI_q1p2Mi= 2p2Mibc ff aiimb Q7 i?2 [m2`v Ui`m2 Q` 7Hb2V T`Bpi2 ai`BM; biimbc ff P77b2i Q7 2H2K2Mib iQ T;BMi2 T`Bpi2 ai`BM; Q77b2ic ff 1M/ iBK2 Q7 i?2 [m2`v T`Bpi2 ai`BM; 2M/niBK2c ff XXX ' 5.4.4 Adaptadores de listas Cada elemento gráfico de tipo lista en Android ® requiere de un adaptador que se encarga de generar las vistas de cada uno de los elementos de esta. Todos los adaptadores se encuentran en el paquete T+F;2 M2iX`2/#Q`/2`X`2/#Q`/2`X/Ti2`b. 36 Capítulo 5. Implementación Cada adaptador hereda de la clase "b2/Ti2` de Android ® que define una serie de métodos necesarios para la gestión de la lista: •;2i*QmMi: devuelve el número de elementos. •;2iAi2K: devuelve el objeto asociado a un elemento. •;2ioB2r: procesa la vista de un elemento y la devuelve. Cabe destacar que el método ;2ioB2r sigue el patrón oB2r>QH/2` recomendado por la comunidad de desarrollo de Android (más información en [3]). Este patrón almacena las referencias de los componentes gráficos de un elemento de la lista. Esto permite el reciclado de las vistas de los elementos, ya que no necesitan buscar de nuevo las referencias, lo que aumenta el rendimiento de carga de las lista, evitando ralentizaciones al navegar por esta. El código 5.2 ilustra el uso de este patrón en el adaptador de la lista de eventos de la vista RAW. Código 5.2 Uso del patrón ViewHolder en la lista de eventos de la vista RAW.. f S`Bpi2 +Hbb pB2r ?QH/2` iQ BMBiBi2 M/ `2mb2 i?2 pB2rb BM i?2 HBbioB2r f T`Bpi2 biiB+ +Hbb oB2r>QH/2` & Tm#HB+ AK;2oB2r b2p2`Bivc Tm#HB+ h2tioB2r bB;Mim`2c Tm#HB+ h2tioB2r b2MbQ`c Tm#HB+ h2tioB2r ?Qm`c Tm#HB+ h2tioB2r 2p2Mibc Tm#HB+ _2HiBp2GvQmi r`Tc ' !Pp2``B/2 Tm#HB+ oB2r ;2ioB2rUBMi TQbBiBQM- oB2r pB2r- oB2r:`QmT pB2r:`QmTV & oB2r pB 4 pB2rc oB2r>QH/2` ?QH/2` 4 MmHHc _q1p2Mi 2p2Mi 4 U_q1p2MiV ;2iAi2KUTQbBiBQMVc ff A7 r2 +M `2+v+H2 i?2 pB2r- r2 /QM^i +`2i2  M2r pB2r B7UpB 44 MmHHV& ffh?2 pB2r Bb MQi  `2+v+H2/ QM2, r2 ?p2 iQ BM7Hi2 pB 4 HBXBM7Hi2U_XHvQmiX2p2MinBi2K- pB2r:`QmT- 7Hb2Vc ?QH/2` 4 M2r oB2r>QH/2`UVc ?QH/2`Xr`T 4 U_2HiBp2GvQmiVpBX7BM/oB2r"vA/U_XB/X2p2Minr`TVc ?QH/2`Xb2p2`Biv 4 UAK;2oB2rVpBX7BM/oB2r"vA/U_XB/Xb2p2`BivVc ?QH/2`XbB;Mim`2 4 Uh2tioB2rVpBX7BM/oB2r"vA/UM2iX`2/#Q`/2`X`2/#Q`/2`X_X B/XbB;Mim`2Vc ?QH/2`Xb2MbQ` 4 Uh2tioB2rVpBX7BM/oB2r"vA/UM2iX`2/#Q`/2`X`2/#Q`/2`X_XB/X b2MbQ`Vc ?QH/2`X?Qm` 4 Uh2tioB2rV pBX7BM/oB2r"vA/UM2iX`2/#Q`/2`X`2/#Q`/2`X_XB/X iBK2biKTVc ?QH/2`X2p2Mib 4 Uh2tioB2rVpBX7BM/oB2r"vA/UM2iX`2/#Q`/2`X`2/#Q`/2`X_XB/X 2p2MibVc pBXb2ih;U?QH/2`Vc ' 2Hb2 & ff oB2r `2+v+H2/ 5 ff MQ M22/ iQ BM7Hi2 ff MQ M22/ iQ 7BM/oB2rb #v B/ ?QH/2` 4 UoB2r>QH/2`V pBX;2ih;UVc 5.4 Código fuente 37 ' ff XXX ff *Ɵ/B;Q MQ `2H2pMi2 T` 2bi2 2D2KTHQ ff XXX ff _2im`M i?2 pB2r `2im`M pBc ' 5.4.5 Colectores de datos Como se ha comentado, tanto en RAW como en Tops tenemos dos tipos de vistas en función de la posición del dispositivo. El intercambio entre la vista de lista y gráfico debe de ser rápido para no perder la atención del usuario. Concretamente para Tops, cuando filtramos en la lista esta asocia un color a cada elemento, por lo que al girar el dispositivo y ver el gráfico debemos de recordar la asociación de colores. Otra razón más para agilizar el intercambio entre estas. El mayor tiempo de espera al cambiar la orientación es el de respuesta de las peticiones al servidor. Para solventar este problema de tiempos de carga, se ha definido el paquete T+F;2 M2iX`2/#Q`/2`X`2/#Q`/2`X/i*QHH2+iQ`. Este paquete incluye dos clases 2 que heredan de la clase 6`;K2Mi . Estos fragmentos se inicializan junto con una de las vistas y no son eliminados al cambiar entre estas. Se encargan de realizar las llamadas al servidor y almacenar las respuestas para evitar volver a solicitar los datos al cambiar la orientación del dispositivo. Se incluye la clase .i*QHH2+iQ`_q en el Apéndice F. 5.4.6 Gestor de gráficos >QHQ:`T? es la librería elegida para la generación de los gráficos de la aplicación. Sin embargo, dado su uso en varias secciones de la aplicación, se agrupó la gestión y representación de gráficos dentro del paquete M2iX`2/#Q`/2`X`2/#Q`/2`X;`T?. El paquete define la morfología de la respuesta del servidor. Para ello, al igual que los modelos, utiliza la librería _2bi`mM; para inicializar los objetos a partir de la respuesta del gestor. Cada serie de datos está representada por la clase :`T?*QHH2+iBQM . Para los gráficos de la vista de RAW solo tendremos una serie, pero en el caso de la vista Tops la clase :`T?JmHiBTH2*QHH2+iBQM contendrá la lista de series en una variable de tipo List. A su vez, cada serie incluye multiples eventos representados por la clase :`T?a2`B2 . Cada evento incluye el valor de este y el tiempo en el que ha ocurrido. Esta estructura tan compleja es necesaria para la librería _2bi`mM; .LaFigura 5.4 muestra la estructura de la respuesta del servidor y su representación en la aplicación móvil. Este paquete incluye la clase gestora :`T?JM;2` , que se encarga de inicializar los elementos de la interfaz y a partir de los datos y mediante la citada librería, procesar los gráficos. Los métodos más importantes son dos: •;2i_r:`T? : partiendo de un objeto de tipo :`T?*QHH2+iBQM instanciado por la respuesta del servidor, limpia la gráfica actual y procesa los nuevos puntos. •;2ihQT:`T? : a partir de un objeto de tipo JmHiBTH2:`T?*QHH2+iBQM , itera sobre cada serie representándola con el color del filtro que se ha aplicado en la lista. Estas dos funciones también se encargan de inicializar los valores mostrados en los ejes de coordenadas, que como se ha comentado, es una funcionalidad agregada a la librería para este proyecto. :`T?JM;2` contiene una clase privada que gestiona los eventos táctiles de arrastre. Estos eventos permiten al usuario cambiar la ventana de tiempo para los gráficos de la vista RAW. El contenido de :`T?JM;2` se incluye en el Apéndice G 2Una para las vistas de RAW y otra para las de Tops 38 Capítulo 5. Implementación Figura 5.4 Estructura de clases de la respuesta del servidor para el procesamiento de gráficos. 5.4.7 Notificaciones PUSH Para recibir las notificaciones de tipo PUSH en nuestro dispositivo necesitamos hacer uso del servicio de Google Cloud Messaging (GCM) 3 de Google ® . Este servicio permite la comunicación mediante mensajes de este tipo entre en un servidor y los clientes. Este se asociada a una cuenta de desarrollador de Google ® , pudiendo suponer un coste si se supera un número de mensajes al mes. Al registrar el servicio con Google ® , se nos proporciona un identificador de servicio que utilizará el servidor. A su vez, se asocia la aplicación móvil con la cuenta para permitir el envío de mensajes a esta. Para poder enviar mensajes a un dispositivo concreto, este debe de quedar registrado mediante otro identificador, que será el que utilizará el servidor para comunicarse con el. Este registro se realiza en la vista de inicio de sesión siguiendo el diagrama mostrado en la Figura 5.5. Todas las clases relacionadas con este servicio se encuentran en el paquete T+F;2 M2iX`2/#Q`/2`X`2/#Q`/2`X;+K. Como muestra el diagrama, :*J_2;Bbi2` es la clase que se encarga de gestionar el registro del dispositivo en el servicio GCM y su código está incluido en el Apéndice H. También se encarga de almacenar el identificador, así como de leerlo y comprobar cuando es necesario solicitarlo. Las condiciones para solicitar un nuevo identificador son: • No haber obtenido el identificador antes. • La versión de la aplicación ha cambiado con respecto a cuando se solicitó el identificador. Dentro de este paquete también tenemos la clase :+K"`Q/+bi_2+2Bp2` . Esta se encarga de recibir los mensajes que el servidor ha enviado. Para ello, inicia el servicio :+KAMi2Mia2`pB+2 que procesa el mensaje. En nuestro caso, estos mensajes contienen información sobre las alarmas, por lo que :+KAMi2Mia2`pB+2 almacena estas y muestra una notificación en el dispositivo cuando es necesario. 5.5 Implementación de las vistas 5.5.1 Inicio de sesión Cuando un usuario inicia la aplicación de redBorder, esta sigue el diagrama de la Figura 5.6 para representar una vista u otra en función de la existencia de cuentas de redBorder en el dispositivo. Si no existen cuentas, como muestra el Código 5.3, se lanza un BMi2Mi para cambiar de actividad a la definida en la clase mi?2MiB+iQ`+iBpBiv. 3Más información sobre el servicio en https://developers.google.com/cloud-messaging/gcm 5.5 Implementación de las vistas 39 Figura 5.5 Digrama de flujo del registro de un dispositivo en el servicio GCM. Figura 5.6 Digrama de flujo del inicio de sesión de redBorder mobile. 40 Capítulo 5. Implementación Código 5.3 Lanzamiento de la actividad de creación de nueva cuenta. B7 U++QmMibXH2M;i? 44 yV & ff QTb5 q2 /QM^i ?p2 Mv- H2i^b +`2i2 QM2 AMi2Mi mi? 4 M2r AMi2MiUi?Bb- mi?2MiB+iQ`+iBpBivX+HbbVc mi?XTmi1ti`Umi?2MiB+iQ`+iBpBivX_:nAan..AL:nL1qn**PlLh- i`m2Vc bi`i+iBpBivUmi?Vc ' La clase mi?2MiB+iQ`+iBpBiv se encarga de mostrar el formulario expuesto en la Subsección 4.4.1,y de crear la cuenta en el sistema si la autenticación es correcta. Una vez que el servidor retorna el asentimiento de autenticación y los valores del usuario, el Código 5.4 se encarga de crear la cuenta en el dispositivo. Código 5.4 Método para la creación de una cuenta en Android. T`Bpi2 pQB/ 7BMBb?GQ;BMUAMi2Mi BMi2MiV & ff LK2 Q7 i?2 ++QmMib BM i?2 bvbi2K ai`BM; ++QmMiLK2 4 BMi2MiX;2iai`BM;1ti`U++QmMiJM;2`XE1un**PlLhnLJ1Vc ff AMBi T`K2i2`b 7`QK b2`p2` `2bTQMb2 ai`BM; ++QmMiSbbrQ`/ 4 BMi2MiX;2iai`BM;1ti`US_Jnla1_nSaaVc ai`BM; b2`p2`nF2v 4 BMi2MiX;2iai`BM;1ti`U_:na1_o1_nE1uVc ai`BM; b2`p2`nKQ/mH2b 4 BMi2MiX;2iai`BM;1ti`U_:na1_o1_nJP.lG1aVc ff *`2i2 i?2 ++QmMi 7BMH ++QmMi ++QmMi 4 M2r ++QmMiU++QmMiLK2- BMi2MiX;2iai`BM;1ti`U ++QmMiJM;2`XE1un**PlLhnhuS1VVc ff a2i i?2 iQF2M ai`BM; mi?iQF2M 4 BMi2MiX;2iai`BM;1ti`U++QmMiJM;2`XE1unlh>hPE1LVc ai`BM; mi?iQF2MhvT2 4 ]_1.@PLGu]c B7 U;2iAMi2MiUVX;2i"QQH2M1ti`U_:nAan..AL:nL1qn**PlLh- 7Hb2VV & ff *`2iBM; i?2 ++QmMi QM i?2 /2pB+2 M/ b2iiBM; i?2 mi? iQF2M r2 ;Qi ff ULQi b2iiBM; i?2 mi? iQF2M rBHH +mb2 MQi?2` +HH iQ i?2 b2`p2` iQ mi?2MiB+i2 i?2 mb2`V K++QmMiJM;2`X//++QmMi1tTHB+BiHvU++QmMi- ++QmMiSbbrQ`/- MmHHVc K++QmMiJM;2`Xb2ilb2`.iU++QmMi- _:n1JAG- 2KBHVc K++QmMiJM;2`Xb2ilb2`.iU++QmMi- _:n.PJAL- /QKBMVc K++QmMiJM;2`Xb2ilb2`.iU++QmMi- _:na1_o1_nE1u- b2`p2`nF2vVc K++QmMiJM;2`Xb2ilb2`.iU++QmMi- _:na1_o1_nJP.lG1a- b2`p2`nKQ/mH2bVc K++QmMiJM;2`Xb2imi?hQF2MU++QmMi- mi?iQF2MhvT2- mi?iQF2MVc ' 2Hb2 & ff lT/iBM; +`2/2MiBHb K++QmMiJM;2`Xb2iSbbrQ`/U++QmMi- ++QmMiSbbrQ`/Vc K++QmMiJM;2`Xb2imi?hQF2MU++QmMi- mi?iQF2MhvT2- mi?iQF2MVc ' b2i++QmMimi?2MiB+iQ`_2bmHiUBMi2MiX;2i1ti`bUVVc b2i_2bmHiU_1alGhnPE- BMi2MiVc ff _2im`M iQ HQ;BM AMi2Mi HQ;BM 4 M2r AMi2MiUi?Bb- GQ;BM+iBpBivX+HbbVc bi`i+iBpBivUHQ;BMVc 7BMBb?UVc ' 5.5 Implementación de las vistas 41 Todas las clases necesarias para la autenticación y gestión de cuentas se encuentra dentro del paquete M2iX`2/#Q`/2`X`2/#Q`/2`X++QmMib . El paquete M/`QB/X++QmMib incluye las clases de las que se debe heredar para trabajar con cuentas en Android®. La clase mi?2MiB+iBQMa2`p2` realiza las llamadas al gestor de redBorder ® , instanciando la clase lb2` con los datos devueltos por el servidor si la autenticación ha sido correcta. En el caso de que esta no sea correcta, se muestra un mensaje en la interfaz incluyendo la cadena de texto del error retornado por el servidor. La clase principal para la gestión de las cuentas de redBorder una vez creadas es mi?2MiB+iQ` .Esta clase hereda de #bi`+i++QmMimi?2MiB+iQ` y define los siguientes métodos: •//++QmMi : instancia la clase mi?2MiB+iQ`+iBpBiv con el formulario y la lógica para la creación de la cuenta de usuario. •+QM7B`K*`2/2MiBHb : también instancia la clase mi?2MiB+iQ`+iBpBiv , pero esta vez con el objetivo de que el usuario vuelva a introducir las credenciales. Se utiliza para actualizar las credenciales cuando el gestor devuelve un error por usuario no autorizado. •;2imi?hQF2M: retorna el token de autenticación almacenado en la cuenta seleccionada. Esta clase a su vez, utiliza los métodos de mi?2MiB+iBQMa2`p2` para las llamadas al servidor. El código de mi?2MiB+iQ` está incluído en el Apéndice I. Por último, la clase mi?2MiB+iBQMa2`pB+2 se encarga de recibir las creaciones de cuentas de tipo redBorder®desde los ajustes de nuestro dispositivo Android®. 5.5.2 Vistas de RAW La implementación de estas vistas incluye tanto al fichero principal _q+iBpBiv como a sus fragmentos, incluidos en el paquete M2iX`2/#Q`/2`X`2/#Q`/2`X`r. La actividad _q+iBpBiv se encarga de la representación de los menús laterales y de la gestión de fragmentos. Ampliando la información de la Subsección 5.4.5, el diagrama de iniciación de esta actividad es el mostrado en la Figura 5.7. Figura 5.7 Digrama de flujo de RAWActivity. 48 Capítulo 5. Implementación f ?B/2 Q` b?Qr i?2 MQiB7B+iBQMb f T`Bpi2 pQB/ iQ;;H2LQiB7B+iBQMbUV& B7UMQiB7B+iBQMbV& ff "+F T`2bb2/ MQiB7B+iBQMb 4 7Hb2c QM"+FS`2bb2/UVc ' 2Hb2 & MQiB7B+iBQMb 4 i`m2c "mM/H2 `;b 4 M2r "mM/H2UVc `;bXTmia2`BHBx#H2U6`;K2Mi`;mK2MibX_:nla1_- mb2`Vc ff AMBiBi2 i?2 7`; 7`;nMQiB7B+iBQM 4 M2r LQiB7B+iBQM6`;K2MiUVc 7`;nMQiB7B+iBQMXb2i`;mK2MibU`;bVc ;2iamTTQ`i6`;K2MiJM;2`UVX#2;BMh`Mb+iBQMUVX`2TH+2U_XB/X7`;n`r- 7`;nMQiB7B+iBQM- 6_:nLPhA6A*hAPLaVX//hQ"+Fai+FU6_:n LPhA6A*hAPLaVX+QKKBiUVc ' ' Si la vista de alarmas ya está visible y se pulsa en el icono, lo que ocurre es que se llama al método QM"+FS`2bb2/UV que provocará que la aplicación vuelva al estado anterior, terminando el ciclo de vida del fragmento. Esto es posible gracias a que cuando se agregó el fragmento a la actividad, se agregó a la pila de estados mediante el método //hQ"+Fai+FU6_:nLPhA6A*hAPLaV. Un problema que nos encontramos al trabajar con varias cuentas en un mismo dispositivo era discernir a que gestor correspondía cada alarma. Para solventar este problema, el gestor define una cadena aleatoria que lo identifica unívocamente llamada server_key. Este valor es retornado al iniciar sesión y cuando se recibe una notificación. El modelo de usuario también incluye dicha cadena, como podemos ver en el código del modelo user incluído en el Apéndice C La clase LQiB7B+iBQM6`;K2Mi es la que se encarga de procesar la lista de alarmas, así como de eliminar las notificaciones de la barra de notificaciones y estado. Para la obtención de las alarmas, se utiliza otra clase: H`Kb . Esta define varios métodos útiles para la gestión de alarmas como obtener las alarmas no vistas para un determinado gestor. El código de esta clase se incluye en el Apéndice K 6 Presupuesto A continuación se detalla un presupuesto sobre el coste de desarrollo de este proyecto: Tabla 6.1 Presupuesto del proyecto redBorder Mobile. Descripción Precio/Hora Número de horas Total (Euros) Estudio del proyecto, investigación y definición de la estructura 12 20 240 Conceptualización y diseño de la interfaz 12 35 420 Implementación del proyecto 12 200 2400 Mejora continua y soporte 12 60 720 Total 315 3780 En total en este proyecto se han invertido trecientas quince horas de trabajo. 49 7 Conclusiones 7.1 Conclusiones Tras un tiempo con la intención de aprender sobre tecnologías móviles, este proyecto ha sido todo un reto. Desarrollar para Android es relativamente sencillo, pero trabajar en mejoras de rendimiento es más complejo e interesante al mismo tiempo. Partiendo de una interfaz ya existente, se ha adaptado esta y su lógica de interacción a una aplicación móvil capaz de ofrecer al usuario una vista rápida del estado de su red, así como notificaciones en tiempo real de cualquier problema que pudiera estar ocurriendo. El tener una interfaz sobre la que basarse es una ventaja y un inconveniente. La conceptualización de ideas y el diseño de la interfaz móvil se ha visto acelerado gracias a esto, pero a la vez, las personas que han utilizado el gestor web ya tienen interiorizado una manera de trabajar. Es por ello que la interacción móvil debía de corresponderse con la del gestor, ya que es lo que esperaban los clientes. Trabajar en este entorno de trabajo ha sido una gran experiencia. Desde el primer momento me he sentido integrado y escuchado por el equipo, por lo que el proceso desarrollo de esta aplicación ha sido muy satisfactorio a nivel personal y profesional. La impresión del equipo ha sido muy buena, ya que el los clientes se han visto interesados en la aplicación y han estado consultando el estado actual de esta. En definitiva, la aplicación ha cumplido su objetivo, que era disponer de una herramienta móvil para la gestión de la plataforma y en consecuencia, agregar valor al producto. 7.2 Líneas de mejora Como línas de mejora se proponen varias: • Inclusión de más tipos de gráficos, como gráficos de barras, de área... • Agregar más módulos de redBorder®, que se agregaron tras el comienzo del proyecto. • Mejorar la interfaz en tabletas, ya que se podría aprovechar el espacio para mostrar los gráficos y las listas de eventos al mismo tiempo. • Agregar algunos parámetros de configuración básicos del gestor. • Modificar el código y desarrollar una aplicación multiplataforma para el funcionamiento en el sistema operativo iOS ® , ya que varios clientes preguntaron la existencia de la aplicación en dicha plataforma. 51 Apéndice A Fichero de configuración de Gradle Código A.1 Contenido del fichero build.gradle. #mBH/b+`BTi & `2TQbBiQ`B2b & Kp2M*2Mi`HUV ' /2T2M/2M+B2b & +HbbTi? ^+QKXM/`QB/XiQQHbX#mBH/,;`/H2,RXjXy^ ' ' TTHv THm;BM, ^M/`QB/^ `2TQbBiQ`B2b & Kp2M*2Mi`HUV Kp2M & m`H ]?iiT,ff+HBMF2`X9d/2;X+QKfM2tmbf+QMi2Mif`2TQbBiQ`B2bfbMTb?Qib] ' ' ff GB;`2`Ōb /2 H THB++BƟM /2T2M/2M+B2b & +QKTBH2 ^+QKXM/`QB/XbmTTQ`i,bmTTQ`i@p9,RNXRXY^ +QKTBH2 7BH2h`22U/B`, ^HB#b^- BM+Hm/2, ^ XD`^V +QKTBH2 ^+QKX;QQ;H2XM/`QB/X;Kb,THv@b2`pB+2b,9XjXkj^ +QKTBH2 T`QD2+iU^,+iBp2M/`QB/^V +QKTBH2 T`QD2+iU^,?QHQ;`T?HB#``v,>QHQ:`T?GB#``v^V +QKTBH2 T`QD2+iU^,M/`QB/@TmHH@iQ@`27`2b?,HB#``v^V +QKTBH2 T`QD2+iU^,MQi?2`1tTM/#H2GBbioB2r^V ' M/`QB/ & +QKTBH2a/Fo2`bBQM RN #mBH/hQQHbo2`bBQM ]RNXRXy] HBMiPTiBQMb & +?2+F_2H2b2"mBH/b 7Hb2 #Q`iPM1``Q` 7Hb2 ' 53 54 Apéndice A. Fichero de configuración de Gradle bB;MBM;*QM7B;b & /2#m; & ff .27BM2 H m#B++BƟMMQK#`2 v +QMi`b2ƛ /2H 7B+?2`Q /2 H ff +Hp2 T` 7B`K` H THB++BƟM 2M 2H 2MiQ`MQ /2 /2b``QHHQX ff a2 QKBi2 2H +QMi2MB/Q /2 2bi TQ` KQiBpQb /2 b2;m`B//X ' bB;M2/SE & ff .27BM2 H m#B++BƟMMQK#`2 v +QMi`b2ƛ /2H 7B+?2`Q /2 H ff +Hp2 T` 7B`K` H THB++BƟM 2M 2H 2MiQ`MQ /2 T`Q/m++BƟMX ff a2 QKBi2 2H +QMi2MB/Q /2 2bi TQ` KQiBpQb /2 b2;m`B//X ' ' bQm`+2a2ib & KBM & KMB72biXb`+6BH2 ^M/`QB/JMB72biXtKH^ DpXb`+.B`b 4 (^b`+^) `2bQm`+2bXb`+.B`b 4 (^b`+^) B/HXb`+.B`b 4 (^b`+^) `2M/2`b+`BTiXb`+.B`b 4 (^b`+^) `2bXb`+.B`b 4 (^`2b^) bb2ibXb`+.B`b 4 (^bb2ib^) ' ' #mBH/hvT2b & /2#m; & /2#m;;#H2 i`m2 bB;MBM;*QM7B; bB;MBM;*QM7B;bX/2#m; T`Q;m`/6BH2 ^T`Q;m`/X+7;^ ' `2H2b2 & /2#m;;#H2 7Hb2 bB;MBM;*QM7B; bB;MBM;*QM7B;bXbB;M2/SE T`Q;m`/6BH2 ^T`Q;m`/X+7;^ ' ' ' Apéndice B AndroidManifest.xml Código B.1 Contenido del fichero AndroidManifest.xml. I\tKH p2`bBQM4]RXy] 2M+Q/BM;4]mi7@3]\= IKMB72bi tKHMb,M/`QB/4]?iiT,ffb+?2KbXM/`QB/X+QKfTFf`2bfM/`QB/] T+F;24]M2iX`2/#Q`/2`X`2/#Q`/2`] M/`QB/,p2`bBQM*Q/24]k8y] M/`QB/,p2`bBQMLK24]kX8 ai#H2] = Imb2b@b/F M/`QB/,KBMa/Fo2`bBQM4]RR] M/`QB/,i`;2ia/Fo2`bBQM4]RN] f= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMXALh1_L1h] f= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMX**1aanL1hqP_Enahh1] f= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMXlh>1LhA*h1n**PlLha]f= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMX:1hn**PlLha]f= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMXJL:1n**PlLha]f= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMXla1n*_1.1LhAGa]f= Imb2b@T2`KBbbBQM M/`QB/,MK24]+QKX;QQ;H2XM/`QB/XT`QpB/2`bX;b7XT2`KBbbBQMX _1.n:a1_oA*1a]f= I5@@ h?2 7QHHQrBM; irQ T2`KBbbBQMb `2 MQi `2[mB`2/ iQ mb2 :QQ;H2 JTb M/`QB/ SA pk- #mi `2 `2+QKK2M/2/X @@= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMX**1aan*P_a1nGP*hAPL]f= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMXoA"_h1]f= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMX**1aan6AL1nGP*hAPL]f= Imb2b@T2`KBbbBQM M/`QB/,MK24]M/`QB/XT2`KBbbBQMXqE1nGP*E] f= Imb2b@T2`KBbbBQM M/`QB/,MK24]+QKX;QQ;H2XM/`QB/X+k/KXT2`KBbbBQMX_1*1Ao1] f= IT2`KBbbBQM M/`QB/,MK24]+QKX2tKTH2X;+KXT2`KBbbBQMX*k.nJ1aa:1] M/`QB/,T`Qi2+iBQMG2p2H4]bB;Mim`2] f= Imb2b@T2`KBbbBQM M/`QB/,MK24]+QKX2tKTH2X;+KXT2`KBbbBQMX*k.nJ1aa:1] f= ITTHB+iBQM M/`QB/,HHQr"+FmT4]i`m2] M/`QB/,B+QM4]!/`r#H2fB+nHmM+?2`] M/`QB/,H#2H4]!bi`BM;fTTnMK2] M/`QB/,i?2K24]!bivH2fTTh?2K2] M/`QB/,MK24]XTTHB+iBQM]= Imb2b@HB#``v M/`QB/,MK24]+QKX;QQ;H2XM/`QB/XKTb] f= 55 56 Appendix B. AndroidManifest.xml I+iBpBiv M/`QB/,MK24]M2iX`2/#Q`/2`X`2/#Q`/2`XGQ;BM+iBpBiv] M/`QB/,H#2H4]!bi`BM;fTTnMK2] M/`QB/,HmM+?JQ/24]bBM;H2hQT] M/`QB/,i?2K24]!bivH2fh?2K2XLQhBiH2] = IBMi2Mi@7BHi2`= I+iBQM M/`QB/,MK24]M/`QB/XBMi2MiX+iBQMXJAL] f= I+i2;Q`v M/`QB/,MK24]M/`QB/XBMi2MiX+i2;Q`vXGlL*>1_] f= IfBMi2Mi@7BHi2`= If+iBpBiv= I+iBpBiv M/`QB/,MK24]M2iX`2/#Q`/2`X`2/#Q`/2`X_q+iBpBiv] M/`QB/,+QM7B;*?M;2b4]Q`B2MiiBQM%b+`22MaBx2] M/`QB/,H#2H4]!bi`BM;fiBiH2n+iBpBivnBTb] = If+iBpBiv= I+iBpBiv M/`QB/,MK24]M2iX`2/#Q`/2`X`2/#Q`/2`X.2iBH+iBpBiv] M/`QB/,H#2H4]!bi`BM;fiBiH2n+iBpBivn/2iBH] M/`QB/,HmM+?JQ/24]bBM;H2hQT] M/`QB/,T`2Mi+iBpBivLK24]M2iX`2/#Q`/2`X`2/#Q`/2`X_q+iBpBiv] M/`QB/,b+`22MP`B2MiiBQM4]TQ`i`Bi] = I5@@ h?2 K2i@/i 2H2K2Mi Bb M22/2/ 7Q` p2`bBQMb HQr2` i?M 9XR @@= IK2i@/i M/`QB/,MK24]M/`QB/XbmTTQ`iXS_1Lhn*hAoAhu] M/`QB/,pHm24]M2iX`2/#Q`/2`X`2/#Q`/2`X_q+iBpBiv] f= If+iBpBiv= I+iBpBiv M/`QB/,MK24]M2iX`2/#Q`/2`X`2/#Q`/2`XhQT+iBpBiv] M/`QB/,+QM7B;*?M;2b4]Q`B2MiiBQM%b+`22MaBx2] M/`QB/,H#2H4]!bi`BM;fiBiH2n+iBpBivniQT] = If+iBpBiv= I+iBpBiv M/`QB/,MK24]M2iX`2/#Q`/2`X`2/#Q`/2`Xai`2K+iBpBiv] M/`QB/,H#2H4]!bi`BM;fiBiH2n+iBpBivnbi`2K] = IBMi2Mi@7BHi2`= I+iBQM M/`QB/,MK24]M/`QB/XBMi2MiX+iBQMXoA1q] f= I+i2;Q`v M/`QB/,MK24]M/`QB/XBMi2MiX+i2;Q`vX.16lGh] f= I+i2;Q`v M/`QB/,MK24]M/`QB/XBMi2MiX+i2;Q`vX"_Pqa"G1] f= I/i M/`QB/,?Qbi4]`2/#Q`/2`XM2i] M/`QB/,Ti?S`27Bt4]f2p2Mif] M/`QB/,b+?2K24]?iiTb] f= IfBMi2Mi@7BHi2`= If+iBpBiv= I5@@ JQMBiQ` @@= I+iBpBiv M/`QB/,MK24]M2iX`2/#Q`/2`X`2/#Q`/2`XJQMBiQ`+iBpBiv] M/`QB/,+QM7B;*?M;2b4]Q`B2MiiBQM%F2v#Q`/>B//2M] M/`QB/,H#2H4]!bi`BM;fiBiH2n+iBpBivnKQMBiQ`] = If+iBpBiv= I+iBpBiv M/`QB/,MK24]M2iX`2/#Q`/2`X`2/#Q`/2`XJQMBiQ`.2iBH+iBpBiv] 57 M/`QB/,H#2H4]!bi`BM;fiBiH2n+iBpBivnKQMBiQ`n/2iBH] M/`QB/,HmM+?JQ/24]bBM;H2hQT] M/`QB/,T`2Mi+iBpBivLK24]M2iX`2/#Q`/2`X`2/#Q`/2`XJQMBiQ`+iBpBiv] = IK2i@/i M/`QB/,MK24]M/`QB/XbmTTQ`iXS_1Lhn*hAoAhu] M/`QB/,pHm24]M2iX`2/#Q`/2`X`2/#Q`/2`XJQMBiQ`+iBpBiv] f= If+iBpBiv= I5@@ mi?2MiB+iBQM b2`pB+2 @@= I+iBpBiv M/`QB/,MK24]M2iX`2/#Q`/2`X`2/#Q`/2`X++QmMibXmi?2MiB+iQ`+iBpBiv ] M/`QB/,H#2H4]!bi`BM;fTTnMK2] M/`QB/,i?2K24]!bivH2fh?2K2XLQhBiH2] = If+iBpBiv= Ib2`pB+2 M/`QB/,MK24]M2iX`2/#Q`/2`X`2/#Q`/2`X++QmMibX mi?2MiB+iBQMa2`pB+2]= IBMi2Mi@7BHi2`= I+iBQM M/`QB/,MK24]M/`QB/X++QmMibX++QmMimi?2MiB+iQ`] f= IfBMi2Mi@7BHi2`= IK2i@/i M/`QB/,MK24]M/`QB/X++QmMibX++QmMimi?2MiB+iQ`] M/`QB/,`2bQm`+24]!tKHfmi?2MiB+iQ`] f= Ifb2`pB+2= I5@@ :*J @@= I`2+2Bp2` M/`QB/,MK24]X;+KX:+K"`Q/+bi_2+2Bp2`] M/`QB/,T2`KBbbBQM4]+QKX;QQ;H2XM/`QB/X+k/KXT2`KBbbBQMXa1L.] = IBMi2Mi@7BHi2`= I+iBQM M/`QB/,MK24]+QKX;QQ;H2XM/`QB/X+k/KXBMi2MiX_1*1Ao1] f= I+i2;Q`v M/`QB/,MK24]+QKX2tKTH2X;+K] f= IfBMi2Mi@7BHi2`= If`2+2Bp2`= Ib2`pB+2 M/`QB/,MK24]X;+KX:+KAMi2Mia2`pB+2] f= IK2i@/i M/`QB/,MK24]+QKX;QQ;H2XM/`QB/X;KbXp2`bBQM] M/`QB/,pHm24]!BMi2;2`f;QQ;H2nTHvnb2`pB+2bnp2`bBQM] f= IK2i@/i M/`QB/,MK24]+QKX;QQ;H2XM/`QB/XKTbXpkXSAnE1u] M/`QB/,pHm24]a1 PJAh1 SP_ a1:l_A..]f= IK2i@/i M/`QB/,MK24]n."nLJ1] M/`QB/,pHm24]H`KbX/#] f= IK2i@/i M/`QB/,MK24]n."no1_aAPL] M/`QB/,pHm24]RR] f= IfTTHB+iBQM= IfKMB72bi= 64 Apéndice E. Modelo para elementos del menú ff *QMbi`m+iQ` iQ #mBH/ M Bi2K Tm#HB+ J2MmAi2K*mbiQKUBMi niBiH2V& i?BbUniBiH2- MmHH-@R- MmHH- 7Hb2- 7Hb2- 7Hb2Vc ' ff *QMbi`m+iQ` iQ #mBH/ M pi` Tm#HB+ J2MmAi2K*mbiQKUai`BM; mb2`- "BiKT pi`V& i?BbU@R- mb2`- @R- pi`- 7Hb2- 7Hb2- i`m2Vc ' ' Apéndice F Colector de datos para la vistas de RAW Código F.1 Contenido del fichero dataCollector/DataCollectorRAW.java. T+F;2 M2iX`2/#Q`/2`X`2/#Q`/2`X/i*QHH2+iQ`c BKTQ`i M/`QB/XTTX+iBpBivc BKTQ`i M/`QB/X+QMi2MiX*QMi2tic BKTQ`i M/`QB/XQbXbvM+hbFc BKTQ`i M/`QB/XQbX"mM/H2c BKTQ`i M/`QB/XbmTTQ`iXp9XTTX6`;K2Mic BKTQ`i M/`QB/XmiBHXGQ;c BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`XS`Q/m+ic BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X+QHH2+iBQMbX_q1p2Mi*QHH2+iBQMc BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X+QHH2+iBQMbX_q1p2Mi6HQr*QHH2+iBQMc BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X;`T?X:`T?*QHH2+iBQMc BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X;`T?X:`T?a2`B2c BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`XKQ/2HbXlb2`c BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X`2biX_qai`BM;bc BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X`2biX_2[m2biS`Kbc BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`XmiBHbX6`;K2Mi`;mK2Mibc BKTQ`i DpXmiBHX``vGBbic BKTQ`i DpXmiBHXGBbic BKTQ`i DpXmiBHXP#D2+ibc BKTQ`i BiX`2bi`mM;X`2biXbvM+XbvM+ibFbXSA:2ibvM+hbFc BKTQ`i BiX`2bi`mM;X`2biX+HB2MiXSA*`2/2MiBHb.2H2;i2c BKTQ`i BiX`2bi`mM;X`2biX+HB2MiX*QMi2tir`2SA.2H2;i2c BKTQ`i BiX`2bi`mM;X`2biX+HB2MiX_2bi*HB2Mic BKTQ`i BiX`2bi`mM;X`2biX+HB2MiX_2bi*HB2Mi6+iQ`vc BKTQ`i BiX`2bi`mM;X`2biX2t+2TiBQMbXAMpHB/*`2/2MiBHb1t+2TiBQMc f *Hbb iQ `2iBM M/ ;2i i?2 /i 7Q` Qi?2` 7`;K2MibX mi?Q`, M;2H J o2`bBQM, RXy f Tm#HB+ +Hbb .i*QHH2+iQ`_q 2ti2M/b 6`;K2Mi & f 65 66 Appendix F. Colector de datos para la vistas de RAW hvT2 2p2Mib iQ +QM7B;m`2 i?2 +HH#+F f T`Bpi2 biiB+ BMi huS1n_qn1o1Lha 4 Rc Tm#HB+ biiB+ BMi huS1n_qn:_S> 4 kc ff .i 7`QK mb2`b T`Bpi2 lb2` mb2`c T`Bpi2 BMi ;`MmH`Bivc T`Bpi2 BMi T`Q/m+ic T`Bpi2 BMi b2`B2c ff GBbi Q7 bvM+ibF T`Bpi2 GBbiIbvM+hbF= ibFbc f @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ _2[m2bib p`B#H2b M/ BMi2`7+2b @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ f f AMi2`7+2 iQ +QMM2+i i?2 +HH#+Fb iQ i?2 KBM +iBpBivX f Tm#HB+ biiB+ BMi2`7+2 `2[m2bi*HH#+Fb & f h?2 bK2 K2i?Q/b BM bvM+ibFX f pQB/ QMS`21t2+mi2UVc pQB/ QMS`Q;`2bblT/i2UBMi T2`+2MiVc pQB/ QM*M+2HH2/UVc pQB/ QM*`2/2MiBHb1``Q`UVc pQB/ QMSQbi1t2+mi2UBMi ;`MmH`Biv- BMi T`Q/m+i- BMi ivT2- #QQH2M +H2` - #QQH2M 7BMBb?Vc ' f AMi2`7+2 iQ +QMM2+i i?2 ;`T? `2[m2bi iQ i?2 KBM +iBpBiv f Tm#HB+ biiB+ BMi2`7+2 ;`T?*HH#+Fb & f _2im`M i?2 /i f pQB/ QM:`T?.iU:`T?*QHH2+iBQM /iVc ' T`Bpi2 ;`T?*HH#+Fb K;`T?*HH#+Fbc T`Bpi2 `2[m2bi*HH#+Fb K*HH#+Fbc f @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6`;K2Mi HBp2 +v+H2 67 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ f f .2i2+i i?2 QMii+? 2p2Mi iQ i?2 KBM +iBpBivr2 Kmbi /2i2+i B7 i?2 +iBpBiv `2 BKTH2K2MiBM; i?2 +HH#+Fb f !Pp2``B/2 Tm#HB+ pQB/ QMii+?U+iBpBiv +iBpBivV & bmT2`XQMii+?U+iBpBivVc GQ;X/U].i*QHH2+iQ`_q]- ]QMii+?UV]Vc ff *?2+F i?2 +HH#+Fb B7 U5U+iBpBiv BMbiM+2Q7 `2[m2bi*HH#+FbV %% 5U+iBpBiv BMbiM+2Q7 ;`T?*HH#+FbVV & ff h?`Qrb  2t+2TiBQM i?`Qr M2r AHH2;Haii21t+2TiBQMU]+iBpBiv Kmbi BKTH2K2Mi i?2 +HH#+Fb BMi2`7+2X]Vc ' 2Hb2 & ff a2i i?2 +HH#+Fb i?BbXK*HH#+Fb 4 U`2[m2bi*HH#+FbV +iBpBivc i?BbXK;`T?*HH#+Fb 4 U;`T?*HH#+FbV +iBpBivc ' ' f h?Bb K2i?Q/ Bb +HH2/ QMHv QM+2 r?2M i?2 6`;K2Mi Bb 7B`bi +`2i2/X q2 `2iBM i?Bb 7`;K2Mi QM +QM7B;*?M;2b f !Pp2``B/2 Tm#HB+ pQB/ QM*`2i2U"mM/H2 bp2/AMbiM+2aii2V & bmT2`XQM*`2i2Ubp2/AMbiM+2aii2Vc ff :2i i?2 /i 7`QK i?2 "mM/H2 "mM/H2 `;b 4 ;2i`;mK2MibUVc mb2` 4 Ulb2`V`;bX;2ia2`BHBx#H2U6`;K2Mi`;mK2MibX_:nla1_Vc ;`MmH`Biv 4 `;bX;2iAMiU6`;K2Mi`;mK2MibX_:n:_LlG_AhuVc T`Q/m+i 4 `;bX;2iAMiU6`;K2Mi`;mK2MibX_:nS_P.l*hVc b2`B2 4 `;bX;2iAMiU6`;K2Mi`;mK2MibX_:na1_A1Vc ibFb 4 M2r ``vGBbiIbvM+hbF=UVc ff _2iBM i?2 7`;K2Mi b2i_2iBMAMbiM+2Ui`m2Vc ' f h?Bb K2i?Q/ +HH2/ r?2M i?2 i?2 7`;K2Mi Bb /2bi`Qv2/- MQi `2iBM2/ f !Pp2``B/2 Tm#HB+ pQB/ QM.2bi`QvUV & bmT2`XQM.2bi`QvUVc ff *M+2H +imH ibFb +M+2HUVc 68 Appendix F. Colector de datos para la vistas de RAW ' f @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .i K2i?Q/b @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ f ff :`MmH`Biv Tm#HB+ pQB/ b2i:`MmH`BivUBMi ;`MmH`BivV & i?BbX;`MmH`Biv 4 ;`MmH`Bivc ff *H2M i?2 Q77b2i i?BbXQ77b2i 4 yc ' ff lb2` Tm#HB+ pQB/ b2ilb2`Ulb2` mb2`V & i?BbXmb2` 4 mb2`c ' ff S`Q/m+i Tm#HB+ pQB/ b2iS`Q/m+iUBMi T`Q/m+iV & i?BbXT`Q/m+i 4 T`Q/m+ic ' f @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ hbF 7`;K2Mib SA @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ f f aiQT i?2 /QrMHQ/ iFb B7 `2 bQK2QM2 +iBp2 f Tm#HB+ pQB/ +M+2HUV & ff aiQT HH MQM@7BMBb?2/ ibFb 7Q`UbvM+hbF ibF , ibFbV& ff aiQT HH i?2 ibF M22/2/ B7UibFX;2iaiimbUV 54 bvM+hbFXaiimbX6ALAa>1.  5ibFX Bb*M+2HH2/UVV & ibFX+M+2HUi`m2Vc ' ' ff *H2M i?2 HBbi ibFbX+H2`UVc ' f @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ _2[m2bi K2i?Q/b #b2/ QM _2bi`mM; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ f ff .i ASa M/ 6HQr Tm#HB+ _q1p2Mi*QHH2+iBQM 2p2Mibc Tm#HB+ _q1p2Mi6HQr*QHH2+iBQM 2p2Mibn7HQrc 69 T`Bpi2 BMi Q77b2i 4 yc T`Bpi2 HQM; 2M/niBK2c f :2i i?2 _q 2p2Mib 7`QK  #27Q`2 `2[m2biX A7 +H2M Bb i`m2- Q77b2i M/ 2M/niBK2 `2 +H2M2/ !T`K +H2M A7 i`m2- +H2M i?2 Q77b2i- i?2 2M/niBK2 M/ i?2 HBbiX f Tm#HB+ pQB/ ;2i_r1p2MibU7BMH #QQH2M +H2MV & ff _2[m2bi i?2 T`K2i2`b _2[m2biS`Kb T`Kb 4 M2r _2[m2biS`KbUmb2`X;2i.QKBMUV Y ]fTBf] Y S`Q/m+iX;2iS`Q/m+iUT`Q/m+iVVc ff AMb2`i i?2 mi?niQF2M Q7 i?2 mb2` T`KbX//L2rS`KU]mi?niQF2M]- mb2`X;2imi?niQF2MUVVc T`KbX//L2rS`KU]Q77b2i]- ai`BM;XpHm2P7UQ77b2iVVc T`KbX//L2rS`KU];`MmH`Biv]- _qai`BM;bX;2i_q:`MmH`BivU ;`MmH`BivVVc ff q2 /QM^i M22/ iQ b2M/ i?2 2M/niBK2 i 7B`bi `2[m2bi B7 U5+H2MV & T`KbX//L2rS`KU]2M/niBK2]- ai`BM;XpHm2P7U2M/niBK2VVc ' B7 UT`Q/m+i 44 S`Q/m+iXASaV & ff AMBiBi2 i?2 +HH#+F *QMi2tir`2SA.2H2;i2 +HH#+F 4 M2r *QMi2tir`2SA.2H2;i2I _q1p2Mi*QHH2+iBQM=U;2i+iBpBivUV- _q1p2Mi*QHH2+iBQMX+HbbV & !Pp2``B/2 Tm#HB+ pQB/ QM_2bmHibU_q1p2Mi*QHH2+iBQM `2bTQMb2V & ff?M/H2 `2bmHib ?2`2 BM i?2 KBM i?`2/ ff _2+2Bp2 i?2 2p2Mib 2p2Mib 4 `2bTQMb2c Q77b2i 4 AMi2;2`XT`b2AMiU`2bTQMb2X;2iP77b2iUVVc 2M/niBK2 4 GQM;XT`b2GQM;U`2bTQMb2X;2i1M/niBK2UVVc B7 UK*HH#+Fb 54 MmHHV & K*HH#+FbXQMSQbi1t2+mi2U;`MmH`Biv- T`Q/m+ihuS1n_qn 1o1Lha- +H2M- 7Hb2Vc ' 2Hb2 & GQ;X/U]*HH#+F]- ]MmHH]Vc ' ' !Pp2``B/2 Tm#HB+ pQB/ QM1``Q`Uh?`Qr#H2 2V & ff?M/H2 2``Q`b ?2`2 BM i?2 KBM i?`2/ ff h?2 TT +M^i ++2bb iQ i?2 b2`p2` ff a?Qr M 2``Q` ff 6AsJ1 /2H2i2 i?2 i`+2 QM 7BMH SS 70 Appendix F. Colector de datos para la vistas de RAW 2XT`BMiai+Fh`+2UVc ' 'c ff /27iHi 2``Q` QM +`2/2MiBHb ff 6AsJ1 //  K2i?Q/ iQ +QMi`QH i?Bb QM `r iQ biQT i?2 HQ/BM; Bi2K SA*`2/2MiBHb.2H2;i2 +`2/2MiBHb.2H2;i2 4 M2r SA*`2/2MiBHb.2H2;i2UV & !Pp2``B/2 Tm#HB+ pQB/ QMAMpHB/*`2/2MiBHbUAMpHB/*`2/2MiBHb1t+2TiBQM 2V & K*HH#+FbXQM*`2/2MiBHb1``Q`UVc ' 'c ff :2i i?2 `2[m2bi 2t2+mi2bvM+UT`KbX;2il`HUV- +HH#+F- +`2/2MiBHb.2H2;i2- M2r P#D2+iUVVc ' 2Hb2 & ff AMBiBi2 i?2 +HH#+F *QMi2tir`2SA.2H2;i2 +HH#+F 4 M2r *QMi2tir`2SA.2H2;i2I _q1p2Mi6HQr*QHH2+iBQM=U;2i+iBpBivUV- _q1p2Mi6HQr*QHH2+iBQMX +HbbV & !Pp2``B/2 Tm#HB+ pQB/ QM_2bmHibU_q1p2Mi6HQr*QHH2+iBQM `2bTQMb2V & ff?M/H2 `2bmHib ?2`2 BM i?2 KBM i?`2/ B7 U`2bTQMb2X;2i1p2MibUV 54 MmHH  5`2bTQMb2X;2i1p2MibUVX Bb1KTivUVV & ff _2+2Bp2 i?2 2p2Mib 2p2Mibn7HQr 4 `2bTQMb2c Q77b2i 4 AMi2;2`XT`b2AMiU`2bTQMb2X;2iP77b2iUVVc 2M/niBK2 4 GQM;XT`b2GQM;U`2bTQMb2X;2i1M/niBK2UVVc B7 UK*HH#+Fb 54 MmHHV & K*HH#+FbXQMSQbi1t2+mi2U;`MmH`Biv- T`Q/m+ihuS1n_q n1o1Lha- +H2M- 7Hb2Vc ' 2Hb2 & GQ;X/U]*HH#+F]- ]MmHH]Vc ' ' 2Hb2 & ff q2 /QM^i `2+2Bp2 Mv /i ff 6AsJ1 b2M/ M 2``Q` Q`  2t+2TiBQM ' ' !Pp2``B/2 Tm#HB+ pQB/ QM1``Q`Uh?`Qr#H2 2V & ff?M/H2 2``Q`b ?2`2 BM i?2 KBM i?`2/ ff h?2 TT +M^i ++2bb iQ i?2 b2`p2` 71 ff a?Qr M 2``Q` ff 6AsJ1 /2H2i2 i?2 i`+2 QM 7BMH SS 2XT`BMiai+Fh`+2UVc ' 'c SA*`2/2MiBHb.2H2;i2 +`2/2MiBHb.2H2;i2 4 M2r SA*`2/2MiBHb.2H2;i2UV & !Pp2``B/2 Tm#HB+ pQB/ QMAMpHB/*`2/2MiBHbUAMpHB/*`2/2MiBHb1t+2TiBQM 2V & K*HH#+FbXQM*`2/2MiBHb1``Q`UVc ' 'c ff :2i i?2 `2[m2bi 2t2+mi2bvM+UT`KbX;2il`HUV- +HH#+F- +`2/2MiBHb.2H2;i2- M2r P#D2+iUVVc ' ' f _27`2b? i?2 _q 2p2Mib QM i?2 HBbiX GQ/ #b2/  M2r ;`MmH`BivX f Tm#HB+ pQB/ ;2i_27`2b?_r1p2MibUV & ;2i_r1p2MibUi`m2Vc ' f :2i i?2 `r ;`T? 2p2Mib 7`QK i?2 b2`p2` f pQB/ ;2i_r:`T?UHQM; 2M/niBK2V & ff _2[m2bi i?2 T`K2i2`b _2[m2biS`Kb T`Kb 4 M2r _2[m2biS`KbUmb2`X;2i.QKBMUV Y ]fTBf] Y S`Q/m+iX;2iS`Q/m+iUT`Q/m+iV Y ]f] Y S`Q/m+iX;2ia2`B2Ub2`B2VVc ff AMb2`i i?2 mi?niQF2M Q7 i?2 mb2` T`KbX//L2rS`KU]mi?niQF2M]- mb2`X;2imi?niQF2MUVVc T`KbX//L2rS`KU];`MmH`Biv]- _qai`BM;bX;2i_q:`MmH`BivUi?BbX ;`MmH`BivVVc B7 U2M/niBK2 = yV & T`KbX//L2rS`KU]2M/niBK2]- ai`BM;XpHm2P7U2M/niBK2VVc ' GQ;XBU]_2[m2bi]- T`KbX;2il`HUVVc ff AMBiBi2 i?2 +HH#+F *QMi2tir`2SA.2H2;i2 +HH#+F 4 M2r *QMi2tir`2SA.2H2;i2I :`T?*QHH2+iBQM=U;2i+iBpBivUV- :`T?*QHH2+iBQMX+HbbV & !Pp2``B/2 Tm#HB+ pQB/ QM_2bmHibU:`T?*QHH2+iBQM `2bTQMb2V & ff?M/H2 `2bmHib ?2`2 BM i?2 KBM i?`2/ 72 Appendix F. Colector de datos para la vistas de RAW B7 UK;`T?*HH#+Fb 54 MmHHV & B7 UT`Q/m+i 44 S`Q/m+iXL1h6GPqV & ff :2i i?2 b2+QM/b Q7 i?2 ;`MmH`Biv BMi ;`MAMa2+QM/b 4 _qai`BM;bX;2ia2+QM/b6`QK:`MmH`BivU ;`MmH`BivVc ff .BpB/2 i?2 2H2K2Mib 7Q` U:`T?a2`B2 Bi2K , `2bTQMb2X;2ia2`B2UVV & HQM; Hbi 4 Bi2KX;2i1p2MiUVX;2i1p2MibUV 3c /Qm#H2 M2roHm2 4 U/Qm#H2V Hbi f ;`MAMa2+QM/bc ffBi2KX;2i1p2MiUVXb2i1p2MibUJi?X`QmM/UM2roHm2VVc Bi2KX;2iSQBMiUVXpHm2 4 Ji?X`QmM/UM2roHm2Vc ' ' K;`T?*HH#+FbXQM:`T?.iU`2bTQMb2Vc ' 2Hb2 & GQ;X/U]*HH#+F]- ]MmHH]Vc ' ' !Pp2``B/2 Tm#HB+ pQB/ QM1``Q`Uh?`Qr#H2 2V & ff?M/H2 2``Q`b ?2`2 BM i?2 KBM i?`2/ ff h?2 TT +M^i ++2bb iQ i?2 b2`p2` ff a?Qr M 2``Q` ff 6AsJ1 /2H2i2 i?2 i`+2 QM 7BMH SS 2XT`BMiai+Fh`+2UVc ' 'c SA*`2/2MiBHb.2H2;i2 +`2/2MiBHb.2H2;i2 4 M2r SA*`2/2MiBHb.2H2;i2 UV & !Pp2``B/2 Tm#HB+ pQB/ QMAMpHB/*`2/2MiBHbUAMpHB/*`2/2MiBHb1t+2TiBQM 2V & K*HH#+FbXQM*`2/2MiBHb1``Q`UVc ' 'c ff :2i i?2 `2[m2bi 2t2+mi2bvM+UT`KbX;2il`HUV- +HH#+F- +`2/2MiBHb.2H2;i2- M2r P#D2+i UVVc ' f h?Bb K2i?Q/ `2+2Bp2 i?2 T`Kb iQ BMBiBi2  bvM+ibF mbBM; i?2 TTbHv HB#``vX Ai //b i?2 ibF iQ i?2 HBbi iQ +M+2H B7 Bb M22/2/X f T`Bpi2 pQB/ 2t2+mi2bvM+Uai`BM; m`H- *QMi2tir`2SA.2H2;i2 +HH#+F- SA*`2/2MiBHb.2H2;i2 +`2/2MiBHb- P#D2+i T`KbV& 73 ff :2i i?2 `2[m2bi SA:2ibvM+hbF ;2i_2[m2bi 4 M2r SA:2ibvM+hbFUm`H- +HH#+F- +`2/2MiBHb- T`KbVc ff // i?2 `2[m2bi iQ i?2 HBbi ibFbX//U;2i_2[m2biVc ff 1t2+mi25 ;2i_2[m2biX2t2+mi2UVc ' Tm#HB+ pQB/ ;2i_r:`T?UV & ;2i_r:`T?UyVc ' Tm#HB+ pQB/ ;2i_r:`T?PH/UHQM; 2M/niBK2V & ;2i_r:`T?U2M/niBK2Vc ' ' 80 Appendix G. Gestor para la renderización de gráficos ff ap2 ;`MmH`Biv i?BbX`M;2 4 `M;2c ff LmK#2` Q7 b2`B2b iQ `2T`2b2Mi BMi MmKa2`B2b 4 yc ff #QQH2M MQ /i #QQH2M MQ.i 4 7Hb2c ff GBbi Q7 b2`B2b .i2SQBMibXJmHiBTH2.i2SQBMi b2`B2b 4 M2r .i2SQBMibXJmHiBTH2.i2SQBMiUV c ff *H2M i?2 ;`T? ;`T?X`2KQp2HHGBM2bUVc ;`T?XBMpHB/i2UVc B7U+QHH2+iBQMbX;2ia2`B2bUV 54 MmHHV & 7Q` U:`T?*QHH2+iBQM /i , +QHH2+iBQMbX;2ia2`B2bUVV & ff AM+`2K2Mi i?2 MmK#2` Q7 b2`B2b MmKa2`B2bYYc B7 U/iX;2ia2`B2UV 54 MmHH  5/iX;2ia2`B2UVXBb1KTivUV  5 MQ.iV & ff a2i i?2 Bi2Kb BM i?2 ;`T? ff _2p2`i i?2 Q`/2` *QHH2+iBQMbX`2p2`b2U/iX;2ia2`B2UVVc ff *`2i2  M2r Bi2K .i2SQBMibXGBbi.i2SQBMi HBbiSQBMib 4 M2r .i2SQBMibX GBbi.i2SQBMiUVc ff GQ/ i?2 7B`bi HBbi TQBMib 4 M2r ``vGBbiI.i2SQBMibX.i2SQBMi=UVc 7Q` U:`T?a2`B2 b2`B2 , /iX;2ia2`B2UVV & TQBMibX//Ub2`B2X;2iSQBMiUVVc ' ff ap2 i?2 TQBMib HBbiSQBMibXTQBMib 4 TQBMibc ff a2i i?2 +QHQ` #b2/ QM 7BHi2`b B7 U7BHi2`bXbBx2UV = yV & 7Q` U.i*QHH2+iQ`hQTX7BHi2`hQT 7BHi2` , 7BHi2`bV & B7 U7BHi2`X;2ioHm2bUVX;2iUyVX2[mHbU/iX;2iLK2UVVV & HBbiSQBMibX+QHQ` 4 7BHi2`X;2i*QHQ`UVc ' ' ' ff // i?2 b2`B2 81 b2`B2bXb2`B2bX//UHBbiSQBMibVc ' 2Hb2 & MQ.i 4 i`m2c ' ' ' 2Hb2 & MQ.i 4 i`m2c ' ff *?2+F B7 r2 ?p2 bQK2 /i B7UMQ.iV& ff q2 /QM^i ?p2 /i ff >B/2 HQ/2` HQ/2`Xb2ioBbB#BHBivUoB2rX:PL1Vc ff b?Qr M 2``Q` /pB+2Xb2ioBbB#BHBivUoB2rXoAaA"G1Vc ' 2Hb2 & ff r2 ?p2 /i- b2i i?2 b+H2 M/ ;Q iQ `2T`2b2Mi55 ff /27mHi pHm2 Q7 s pHm2b BMi ivT2soHm2bc ff ai`BM; 7Q` bi`i iBK2 ai`BM; bi`iniBK2biKTc ff a2i i?2 7Q`Kii2` /Ti2/ iQ i?2 iBK2xQM2 aBKTH2.i26Q`Ki 7Q`Kii2` 4 M2r aBKTH2.i26Q`KiU]vvvv@JJ@// >>,KK, bb ^lh*^]Vc 7Q`Kii2`Xb2ihBK2wQM2UhBK2wQM2X;2ihBK2wQM2U]lh*]VVc ff bi`i iBK2 *H2M/` +H2M/` 4 *H2M/`X;2iAMbiM+2UhBK2wQM2X;2ihBK2wQM2U]lh*]V Vc ff 2M/ iBK2 *H2M/` 2M/ 4 *H2M/`X;2iAMbiM+2UhBK2wQM2X;2ihBK2wQM2U]lh*]VVc f q?2M i?2 mb2` b2H2+i KQ`2 ;`T? r2 Kmbi ;2i i?2 /i iQ i?2 +Q``2+i `M;2- bQ r2 Kmbi BMBiBi2 i?2 iBK2 iQ +m``2Mi M/ mb2 Q77b2i iQ bm#i`+i i?2 iBK2, //UXXXXXX Q77b2iV f ff a2i i?2 bi`i iBK2 BM i?2 ;`T? #b2/ QM i?2 _M;2 brBi+? U`M;2V & +b2 hQTai`BM;bXGahR, 82 Appendix G. Gestor para la renderización de gráficos ivT2soHm2b 4 GBM2:`T?X>Pl_anL.nJALlh1ac +H2M/`X//U*H2M/`X>Pl_- @RVc bi`iniBK2biKT 4 7Q`Kii2`X7Q`KiU+H2M/`X;2ihBK2UVVc #`2Fc +b2 hQTai`BM;bXGahj, ivT2soHm2b 4 GBM2:`T?X>Pl_anL.nJALlh1ac +H2M/`X//U*H2M/`X>Pl_- @jVc bi`iniBK2biKT 4 7Q`Kii2`X7Q`KiU+H2M/`X;2ihBK2UVVc #`2Fc +b2 hQTai`BM;bXGahk9, ivT2soHm2b 4 GBM2:`T?X>Pl_anL.nJALlh1ac +H2M/`X//U*H2M/`X.unP6nu1_- @RVc bi`iniBK2biKT 4 7Q`Kii2`X7Q`KiU+H2M/`X;2ihBK2UVVc #`2Fc +b2 hQTai`BM;bXGahnq11E, ivT2soHm2b 4 GBM2:`T?X.uanL.n>Pl_ac +H2M/`X//U*H2M/`X.unP6nu1_- @dVc bi`iniBK2biKT 4 7Q`Kii2`X7Q`KiU+H2M/`X;2ihBK2UVVc #`2Fc +b2 hQTai`BM;bXGahnJPLh>, ivT2soHm2b 4 GBM2:`T?X.uac +H2M/`X//U*H2M/`X.unP6nu1_- @jyVc bi`iniBK2biKT 4 7Q`Kii2`X7Q`KiU+H2M/`X;2ihBK2UVVc #`2Fc +b2 hQTai`BM;bXGahnZl_h1_, ivT2soHm2b 4 GBM2:`T?X.uac +H2M/`X//U*H2M/`X.unP6nu1_- @RkyVc bi`iniBK2biKT 4 7Q`Kii2`X7Q`KiU+H2M/`X;2ihBK2UVVc #`2Fc /27mHi, ivT2soHm2b 4 GBM2:`T?X.uac +H2M/`X//U*H2M/`Xu1_- @RVc bi`iniBK2biKT 4 7Q`Kii2`X7Q`KiU+H2M/`X;2ihBK2UVVc #`2Fc ' ff // i?2 Hbi M/ i?2 7B`bi TQBMi iQ b2i i?2 `M;2 83 .i2SQBMibX.i2SQBMi 7B`bi 4 M2r .i2SQBMibX.i2SQBMiUVc 7B`biXiBK2biKT 4 bi`iniBK2biKTc 7B`biXpHm2 4 yc .i2SQBMibX.i2SQBMi Hbi 4 M2r .i2SQBMibX.i2SQBMiUVc HbiXiBK2biKT 4 7Q`Kii2`X7Q`KiU2M/X;2ihBK2UVVc HbiXpHm2 4 yc 7Q`U.i2SQBMibXGBbi.i2SQBMi HBbiSQBMib , b2`B2bXb2`B2bV& HBbiSQBMibXTQBMibX//Uy- 7B`biVc HBbiSQBMibXTQBMibX//UHbiVc ' ff // i?2 TQBMib `2T`2b2MiXb2iJmHiBTH2a2`B2bUb2`B2bVc ff _2T`2b2Mi `2T`2b2MiXb2i_M;2hBK2U+H2M/`- 2M/Vc `2T`2b2MiXb2ihvT2soHm2bUivT2soHm2bVc ff a2i KmHiBTH2 b2`B2b `2T`2b2MiXb2iJmHiBTH2Ui`m2Vc ff _2M/2` i?2 ;`T? `2T`2b2MiX`2M/2`UVc ff >B/2 HQ/2` HQ/2`Xb2ioBbB#BHBivUoB2rX:PL1Vc ' `2im`M i`m2c ' f AMBiBi2 i?2 ;`T? f Tm#HB+ pQB/ b2i:`T?UGBM2:`T? ;`T?V & ff a2i i?2 ;`T? i?BbX;`T? 4 ;`T?c ff b2i i?2 iQm+? 2p2Mi HBbi2M2` i?BbX;`T?Xb2iPMhQm+?1p2MiGBbi2M2`UM2r QMhQm+?1p2MiGBbi2M2`UVVc ' f a2i i?2 HQ/2` iQ ?B/2 f Tm#HB+ pQB/ b2iGQ/2`UGBM2`GvQmi #`V & HQ/2` 4 #`c ' f a2i i?2 /pB+2 84 Appendix G. Gestor para la renderización de gráficos f Tm#HB+ pQB/ b2i/pB+2UGBM2`GvQmi /V & i?BbX/pB+2 4 /c ' f a2i i?2 b+H2 BM i?2 `2T`2b2MiiBQM f Tm#HB+ pQB/ b2ia+H2Ua+H2 b+H2V& `2T`2b2MiXb2ia+H26+iQ`Ub+H2Vc ' f @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ :2bim`2 1p2Mib @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ f f AMbiM+2 Q7 BMi2`7+2 iQ ?M/H2 i?2 iQm+? 2p2Mi f T`Bpi2 +Hbb QMhQm+?1p2MiGBbi2M2` BKTH2K2Mib GBM2:`T?X PMhQm+?1p2MiGBbi2M2` & !Pp2``B/2 Tm#HB+ pQB/ QMhQm+?1p2MiUJQiBQM1p2Mi 2p2MiV & ff G2i i?2 a+H2:2bim`2.2i2+iQ` BMbT2+i HH 2p2MibX ffKa+H2.2i2+iQ`XQMhQm+?1p2MiU2p2MiVc KLmK#2`SQBMi2`b 4 2p2MiX;2iSQBMi2`*QmMiUVc ff :2i i?2 +iBQM KbF 7BMH BMi +iBQM 4 2p2MiX;2i+iBQMJbF2/UVc ff arBi+? i?2 +iBQM brBi+? U+iBQMV & ff h?2 7B`bi TQBMi 2Mi2` BM i?2 b+`22M +b2 JQiBQM1p2MiX*hAPLn.PqL, & 7BMH 7HQi t 4 2p2MiX;2isUVc 7BMH 7HQi v 4 2p2MiX;2iuUVc KGbihQm+?s 4 tc KGbihQm+?u 4 vc K+iBp2SQBMi2`A/ 4 2p2MiX;2iSQBMi2`A/UyVc #`2Fc ' +b2 JQiBQM1p2MiX*hAPLnJPo1, & 7BMH BMi TQBMi2`AM/2t 4 2p2MiX7BM/SQBMi2`AM/2tU K+iBp2SQBMi2`A/Vc 7BMH 7HQi t 4 2p2MiX;2isUTQBMi2`AM/2tVc 85 7BMH 7HQi v 4 2p2MiX;2iuUTQBMi2`AM/2tVc B7 UKLmK#2`SQBMi2`b 44 RV & KhQiH.BbiM+2 Y4 Ji?X#bUt @ KGbihQm+?sVc KJQp2K2Mi Y4 t @ KGbihQm+?sc ffGQ;XBU]oHm2b]- ai`BM;XpHm2P7UKhQiH.BbiM+2V Y ],] Y ai`BM;XpHm2P7UKJQp2K2MiVVc ;`T?Xb2isUKJQp2K2MiVc KGbihQm+?s 4 tc KGbihQm+?u 4 vc ' #`2Fc ' +b2 JQiBQM1p2MiX*hAPLnlS, & K+iBp2SQBMi2`A/ 4 ALoGA.nSPALh1_nA.c B7 UKJQp2K2Mi =4 .AahL*1nhPnaGA.1nG16hV & ff MBKi2 i?2 ;`T? ;`T?XMBKi2UV Xi`MbHiBQMsU;`T?X;2iqB/i?UVV Xb2i.m`iBQMUjyyV Xbi`iUVc ff q2 Kmbi `2HQ/ i?2 /i rBi? KQ`2 pHm2b ffGQ;XBU]_2HQ/BM;]- ai`BM;XpHm2P7UKhQiH.BbiM+2V Y ]-] Y ai`BM;XpHm2P7UKGbihQm+?sV Y ]-] Y ai`BM;XpHm2P7U TQBMiAMa+H2UKGbihQm+?sVVVc ff _2KQp2 HH HBM2b M/ B7 U;2bim`2GBbi2M2` 54 MmHHV & ;2bim`2GBbi2M2`XQMGQ/BM;UVc ff AM+`2K2Mi i?2 Q77b2i Q77b2iYYc ff h?2 2M/niBK2 Bb i?2 KBMSQBMi ;2bim`2GBbi2M2`XQM_2[m2bi.iU7Hb2- `2T`2b2MiX ;2iJBMSQBMiUVVc ' ' 2Hb2 B7UKJQp2K2Mi I4 @.AahL*1nhPnaGA.1nG16h  Q77b2i = RV& ff *`;KQb 2p2MiQb 7mim`Qb bB 2H Q77b2i 2b KvQ` [m2 R B7U;2bim`2GBbi2M2` 54 MmHHV& ff MBKi2 i?2 ;`T? ;`T?XMBKi2UV Xi`MbHiBQMsU@;`T?X;2iqB/i?UVV 86 Appendix G. Gestor para la renderización de gráficos Xb2i.m`iBQMUjyyV Xbi`iUVc ;2bim`2GBbi2M2`XQMGQ/BM;UVc ff .2+`2K2Mi i?2 Q77b2i Q77b2i@@c ff h?2 2M/niBK2 Bb i?2 KtSQBMi Y `M;2 #b2/ QM ;`MmH`Biv *H2M/` 2M/n`2[ 4 *H2M/`X;2iAMbiM+2UhBK2wQM2X ;2ihBK2wQM2U]lh*]VVc ff h?2 TQBMi rb BM b2+QM/b 2M/n`2[Xb2ihBK2AMJBHHBbU`2T`2b2MiX;2iJtSQBMiUV RyyyVc brBi+?U;`MmH`BivV& +b2 _qai`BM;bX:_LlG_AhunRnJALlh1, ff a2i i?2 iBK2b 2M/n`2[X//U*H2M/`X>Pl_- jVc #`2Fc +b2 _qai`BM;bX:_LlG_Ahun8nJALlh1, 2M/n`2[X//U*H2M/`X.unP6nu1_- RVc #`2Fc +b2 _qai`BM;bX:_LlG_AhunR8nJALlh1, 2M/n`2[X//U*H2M/`X.unP6nu1_- jVc #`2Fc +b2 _qai`BM;bX:_LlG_AhunjynJALlh1, 2M/n`2[X//U*H2M/`X.unP6nu1_- 8Vc #`2Fc +b2 _qai`BM;bX:_LlG_AhunRn>Pl_, 2M/n`2[X//U*H2M/`X.unP6nu1_- dVc #`2Fc +b2 _qai`BM;bX:_LlG_Ahun3n>Pl_, 2M/n`2[X//U*H2M/`X.unP6nu1_- RkyVc #`2Fc /27mHi, 2M/n`2[X//U*H2M/`Xu1_- RVc #`2Fc ' ff _2[m2bi i?2 /i ff a1L. AL a1*PL.a555 ;2bim`2GBbi2M2`XQM_2[m2bi.iU7Hb2- 2M/n`2[X ;2ihBK2AMJBHHBbUVfRyyyVc 87 ' ' 2Hb2 B7UKJQp2K2Mi I4 @.AahL*1nhPnaGA.1nG16h  Q77b2i 44 RV & ff q2 i`v iQ ;2i KQ`2 2p2Mib QM i?2 BMBi Q7 i?2 ;`T? ff LQi 2MQm;? KQp2K2Mi ;`T?XMBKi2UV Xi`MbHiBQMsUyV Xb2i.m`iBQMURyyV Xbi`iUVc ff a?Qr M 2``Q` hQbiXKF2h2tiU+QMi2ti- +QMi2tiX;2i_2bQm`+2bUVX;2iai`BM;U_Xbi`BM;X;`T?nMQn KQ`2n/iV- hQbiXG1L:h>nGPL:VXb?QrUVc ' 2Hb2 & ff LQi 2MQm;? KQp2K2Mi ;`T?XMBKi2UV Xi`MbHiBQMsUyV Xb2i.m`iBQMURyyV Xbi`iUVc ' ff *H2M /BbiM+2b KhQiH.BbiM+2 4 yc KJQp2K2Mi 4 yc KGbihQm+?s 4 yc #`2Fc ' +b2 JQiBQM1p2MiX*hAPLn*L*1G, & K+iBp2SQBMi2`A/ 4 ALoGA.nSPALh1_nA.c #`2Fc ' +b2 JQiBQM1p2MiX*hAPLnSPALh1_nlS, & 7BMH BMi TQBMi2`AM/2t 4 U2p2MiX;2i+iBQMUV  JQiBQM1p2MiX *hAPLnSPALh1_nAL.1snJaEV == JQiBQM1p2MiX*hAPLnSPALh1_nAL.1sna>A6hc 7BMH BMi TQBMi2`A/ 4 2p2MiX;2iSQBMi2`A/UTQBMi2`AM/2tVc B7 UTQBMi2`A/ 44 K+iBp2SQBMi2`A/V & ff h?Bb rb Qm` +iBp2 TQBMi2` ;QBM; mTX *?QQb2  M2r ff +iBp2 TQBMi2` M/ /Dmbi ++Q`/BM;HvX 7BMH BMi M2rSQBMi2`AM/2t 4 TQBMi2`AM/2t 44 y \ R , yc KGbihQm+?s 4 2p2MiX;2isUM2rSQBMi2`AM/2tVc KGbihQm+?u 4 2p2MiX;2iuUM2rSQBMi2`AM/2tVc K+iBp2SQBMi2`A/ 4 2p2MiX;2iSQBMi2`A/UM2rSQBMi2`AM/2tVc ' #`2Fc ' ' ' 88 Apéndice G. Gestor para la renderización de gráficos ' f *QMp2`i  TQBMi iQ i?2 a+H2 f Tm#HB+ 7HQi TQBMiAMa+H2U7HQi 7V & `2im`M U.i2SQBMibXALh1_oG 7V f ;`T?X;2iqB/i?UVc ' f @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ *HH#+Fb @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ f Tm#HB+ biiB+ BMi2`7+2 QM:2bim`2GBbi2M2` & ff h?2 pB2r Bb HQ/BM; Tm#HB+ pQB/ QMGQ/BM;UVc ff h?2 mb2` Bb `2[m2biBM; M2r /i Tm#HB+ pQB/ QM_2[m2bi.iU#QQH2M #27Q`2- HQM; 2M/niBK2Vc ' ' Apéndice H Gestor de registro del servicio GCM Código H.1 Contenido del fichero gcm/GCMRegister.java. T+F;2 M2iX`2/#Q`/2`X`2/#Q`/2`X;+Kc BKTQ`i M/`QB/XTTX+iBpBivc BKTQ`i M/`QB/X+QMi2MiX*QMi2tic BKTQ`i M/`QB/X+QMi2MiXa?`2/S`272`2M+2bc BKTQ`i M/`QB/X+QMi2MiXTKXS+F;2AM7Qc BKTQ`i M/`QB/X+QMi2MiXTKXS+F;2JM;2`c BKTQ`i M/`QB/XQbXbvM+hbFc BKTQ`i M/`QB/XmiBHXGQ;c BKTQ`i +QKX;QQ;H2XM/`QB/X;KbX+QKKQMX*QMM2+iBQM_2bmHic BKTQ`i +QKX;QQ;H2XM/`QB/X;KbX+QKKQMX:QQ;H2SHva2`pB+2bliBHc BKTQ`i +QKX;QQ;H2XM/`QB/X;KbX;+KX:QQ;H2*HQm/J2bb;BM;c BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`XGQ;BM+iBpBivc BKTQ`i DpXBQXAP1t+2TiBQMc f h?Bb +Hbb ;2i i?2 `2;Bbi`iBQM A. iQ mb2 :*J b2`pB+2b f Tm#HB+ +Hbb :+K_2;Bbi2` & ff ;HQ#Hb p`b 7Q` :*J Tm#HB+ biiB+ 7BMH ai`BM; 1sh_nJ1aa:1 4 ]K2bb;2]c Tm#HB+ biiB+ 7BMH ai`BM; S_PS1_hun_1:nA. 4 ]`2;Bbi`iBQMnB/]c T`Bpi2 biiB+ 7BMH ai`BM; S_PS1_hunSSno1_aAPL 4 ]TTo2`bBQM]c T`Bpi2 biiB+ 7BMH BMi SGuna1_oA*1an_1aPGlhAPLn_1Zl1ah 4 Nyyyc ff o`B#H2b ;HQ#H2b T` ;m`/` HQb /iQb Tm#HB+ biiB+ 7BMH ai`BM; a>_1.na1_oA.P_1a 4 ]b2`pB/Q`2b]c f h; Q7 HQ; K2bb;2b f biiB+ 7BMH ai`BM; h: 4 ]:*J .2KQ]c f 89 96 Apéndice I. Clase Authenticator `2bmHiXTmiai`BM;U++QmMiJM;2`XE1un**PlLhnhuS1- ++QmMiXivT2Vc `2bmHiXTmiai`BM;U++QmMiJM;2`XE1unlh>hPE1L- mi?hQF2MVc `2im`M `2bmHic ' ff A7 r2 ;2i ?2`2- i?2M r2 +QmH/M^i ++2bb i?2 mb2`^b TbbrQ`/ @ bQ r2 ff M22/ iQ `2@T`QKTi i?2K 7Q` i?2B` +`2/2MiBHbX q2 /Q i?i #v +`2iBM; ff M BMi2Mi iQ /BbTHv Qm` mi?2MiB+iQ`+iBpBivX 7BMH AMi2Mi BMi2Mi 4 M2r AMi2MiUK*QMi2ti- mi?2MiB+iQ`+iBpBivX+HbbVc BMi2MiXTmi1ti`U++QmMiJM;2`XE1un**PlLhnlh>1LhA*hP_n_1aSPLa1- `2bTQMb2Vc BMi2MiXTmi1ti`Umi?2MiB+iQ`+iBpBivX_:n**PlLhnhuS1- ++QmMiXivT2Vc BMi2MiXTmi1ti`Umi?2MiB+iQ`+iBpBivX_:nlh>nhuS1- mi?hQF2MhvT2Vc 7BMH "mM/H2 #mM/H2 4 M2r "mM/H2UVc #mM/H2XTmiS`+2H#H2U++QmMiJM;2`XE1unALh1Lh- BMi2MiVc `2im`M #mM/H2c ' ff LQrr2 /QM^i M22/ iQ /27BM2 i?2b2 K2i?Q/bX !Pp2``B/2 Tm#HB+ ai`BM; ;2imi?hQF2MG#2HUai`BM; bV & `2im`M MmHHc ' !Pp2``B/2 Tm#HB+ "mM/H2 mT/i2*`2/2MiBHbU++QmMimi?2MiB+iQ`_2bTQMb2 ++QmMimi?2MiB+iQ`_2bTQMb2- ++QmMi ++QmMiai`BM; b- "mM/H2 #mM/H2V i?`Qrb L2irQ`F1``Q`1t+2TiBQM & `2im`M MmHHc ' !Pp2``B/2 Tm#HB+ "mM/H2 ?b62im`2bU++QmMimi?2MiB+iQ`_2bTQMb2 ++QmMimi?2MiB+iQ`_2bTQMb2- ++QmMi ++QmMiai`BM;() bi`BM;bV i?`Qrb L2irQ`F1``Q`1t+2TiBQM & `2im`M MmHHc ' ' Apéndice J Adaptador de la vista de Tops Código J.1 Contenido del fichero top/TopPagerAdapter.java. T+F;2 M2iX`2/#Q`/2`X`2/#Q`/2`XiQTc BKTQ`i DpXmiBHX``vGBbic BKTQ`i DpXmiBHXGBbic BKTQ`i DpXmiBHXGQ+H2c BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`XS`Q/m+ic BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X_c BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X/i*QHH2+iQ`X.i*QHH2+iQ`hQTc BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X;`T?X:`T?JmHiBTH2*QHH2+iBQMc BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`XKQ/2HbXhQT1p2Mic BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X`2biX_qai`BM;bc BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`X`2biXhQTai`BM;bc BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`XmiBHbX6`;K2Mi`;mK2Mibc BKTQ`i M/`QB/X+QMi2MiX*QMi2tic BKTQ`i M/`QB/X+QMi2MiX`2bX*QM7B;m`iBQMc BKTQ`i M/`QB/XQbX"mM/H2c BKTQ`i M/`QB/XbmTTQ`iXp9XTTX6`;K2Mic BKTQ`i M/`QB/XbmTTQ`iXp9XTTX6`;K2MiJM;2`c BKTQ`i M/`QB/XbmTTQ`iXp9XTTX6`;K2Miaii2S;2`/Ti2`c BKTQ`i +QKX2+?QX?QHQ;`T?HB#``vXb+H2Xa+H2"Bibc BKTQ`i +QKX2+?QX?QHQ;`T?HB#``vXb+H2Xa+H2"vi2bc Tm#HB+ +Hbb hQTS;2`/Ti2` 2ti2M/b 6`;K2Miaii2S;2`/Ti2` & T`Bpi2 biiB+ 7BMH BMi LlJnAh1Ja 4 dc T`Bpi2 7BMH 6`;K2MiJM;2` K6`;K2MiJM;2`c T`Bpi2 *QMi2ti +QMi2ti 4 MmHHc T`Bpi2 BMi T`Q/m+ic T`Bpi2 BMi bQm`+2c T`Bpi2 GBbiIhQT.i= 7`;K2MinHBbic T`Bpi2 GBbiIhQT:`T?= 7`;K2MinHBbin;`T?c ff P`B2MiiBQM 97 98 Appendix J. Adaptador de la vista de Tops T`Bpi2 BMi Q`B2MiiBQMc f *QMbi`m+iQ` 7Q` +QMi`QH i?2 T;2b /Ti2` !T`K 7K 6`;K2MiJM;2` iQ +QMi`QH i?2 T;2` f Tm#HB+ hQTS;2`/Ti2`U6`;K2MiJM;2` 7K- *QMi2ti +- BMi Q`B2MiiBQM- BMi T`Q/m+i- BMi bQm`+2V & bmT2`U7KVc i?BbXK6`;K2MiJM;2` 4 7Kc i?BbX+QMi2ti 4 +c i?BbXQ`B2MiiBQM 4 Q`B2MiiBQMc i?BbXbQm`+2 4 bQm`+2c i?BbXT`Q/m+i 4 T`Q/m+ic ff AMBiBi2 i?2 HBbi i?BbX7`;K2MinHBbi 4 M2r ``vGBbiIhQT.i=UVc i?BbX7`;K2MinHBbin;`T? 4 M2r ``vGBbiIhQT:`T?=UVc ' !Pp2``B/2 Tm#HB+ 6`;K2Mi ;2iAi2KUBMi TQbBiBQMV & B7 Ui?BbXQ`B2MiiBQM 44 *QM7B;m`iBQMXP_A1LhhAPLnGL.a*S1V & `2im`M ;2ihQT:`T?6`;K2MiUTQbBiBQMVc ' 2Hb2 & `2im`M ;2ihQT.i6`;K2MiUTQbBiBQMVc ' ' f _2im`M i?2 hQT.i 7`;K2Mi Q7 i?2 +m``2Mi TQbBiBQM A7 i?2 7`;K2Mi /Q2bM^i 2tBbi- Bi rBHH #2 +`2i2/X !T`K TQbBiBQM SQbBiBQM Q7 i?2 7`;K2Mi r2 Kmbi `2im`M f 6`;K2Mi ;2ihQT.i6`;K2MiUBMi TQbBiBQMV & ff "QQH2M iQ b2i i?2 7`;K2Mi i +m``2Mi TQbBiBQM #QQH2M iSQbBiBQM 4 7Hb2c B7 U7`;K2MinHBbiXbBx2UV = TQbBiBQMV & ff A7 i?2 Bi2K BbM^i MmHH B7 U7`;K2MinHBbiX;2iUTQbBiBQMV 54 MmHHV & 7`;K2MinHBbiX;2iUTQbBiBQMVXb2iaQm`+2UbQm`+2Vc `2im`M 7`;K2MinHBbiX;2iUTQbBiBQMVc ' 99 ff h?2 Bi2K Bb MmHH- bQ r2 Kmbi BMbiMiBi2 Bi BM i?2 +Q``2+i TQbBiBQM iSQbBiBQM 4 i`m2c ' 2Hb2 B7 U5U7`;K2MinHBbiXbBx2UV 44 TQbBiBQMVV & ff *?2+F Bi bBx2 Y R 44 iQ TQbBiBQM BMi B 4 yc ff 6BHH i?2 ``v rBi? MmHH r?BH2 UB I TQbBiBQMV & 7`;K2MinHBbiX//UMmHHVc BYYc ' ' ff AMBiBi2 i?2 7`;K2Mi hQT.i 7`; 4 M2r hQT.iUVc "mM/H2 QTiBQMb 4 M2r "mM/H2UVc QTiBQMbXTmiAMiU6`;K2Mi`;mK2MibX_:nS_P.l*h- T`Q/m+iVc QTiBQMbXTmiAMiU6`;K2Mi`;mK2MibX_:naPl_*1- bQm`+2Vc QTiBQMbXTmiAMiU6`;K2Mi`;mK2MibX_:nSPaAhAPL- TQbBiBQMVc 7`;Xb2i`;mK2MibUQTiBQMbVc ff A7 r2 Kmbi iQ b2i Bi BM i?2 +m``2Mi TQbBiBQM B7 UiSQbBiBQMV & 7`;K2MinHBbiX`2KQp2UTQbBiBQMVc 7`;K2MinHBbiX//UTQbBiBQM- 7`;Vc ' 2Hb2 & ff // i i?2 7BMH Q7 i?2 ``v 7`;K2MinHBbiX//U7`;Vc ' `2im`M 7`;c ' f aiQT i?2 +m``2Mi TmHHhQ_27`2b? f Tm#HB+ pQB/ biQTSmHHhQ_27`2b?UV& ff A7 i?2 Q`B2MiiBQM Bb SP_h_Ah B7 Ui?BbXQ`B2MiiBQM 44 *QM7B;m`iBQMXP_A1LhhAPLnSP_h_AhV& 7Q`UhQT.i Bi2K , 7`;K2MinHBbiV& ff *?2+F B7 i?2 Bi2K Bb BMBiBi2/ B7UBi2K 54 MmHH  Bi2KXBboBbB#H2UVV & Bi2KX+M+2HSmHHhQ_27`2b?UVc ' ' ' 100 Appendix J. Adaptador de la vista de Tops ' f _2im`M i?2 hQT:`T? 7`;K2Mi Q7 i?2 +m``2Mi TQbBiBQM A7 i?2 7`;K2Mi /Q2bM^i 2tBbi- Bi rBHH #2 +`2i2/X !T`K TQbBiBQM SQbBiBQM Q7 i?2 7`;K2Mi r2 Kmbi `2im`M f 6`;K2Mi ;2ihQT:`T?6`;K2MiUBMi TQbBiBQMV & ff "QQH2M iQ b2i i?2 7`;K2Mi i +m``2Mi TQbBiBQM #QQH2M iSQbBiBQM 4 7Hb2c ff *?2+F B7 r2 ?p2 Bi2Kb BM i?2 ``v B7 U7`;K2MinHBbin;`T?XbBx2UV = TQbBiBQMV & ff A7 i?2 Bi2K BbM^i MmHH B7 U7`;K2MinHBbin;`T?X;2iUTQbBiBQMV 54 MmHHV & `2im`M 7`;K2MinHBbin;`T?X;2iUTQbBiBQMVc ' ff h?2 Bi2K Bb MmHH- bQ r2 Kmbi BMbiMiBi2 Bi BM i?2 +Q``2+i TQbBiBQM iSQbBiBQM 4 i`m2c ' 2Hb2 B7 U5U7`;K2MinHBbin;`T?XbBx2UV 44 TQbBiBQMVV & ff *?2+F Bi bBx2 Y R 44 iQ TQbBiBQM BMi B 4 yc ff 6BHH i?2 ``v rBi? MmHH r?BH2 UB I TQbBiBQMV & 7`;K2MinHBbin;`T?X//UMmHHVc BYYc ' ' ff *`2i2  M2r 6`; hQT:`T? 7`; 4 M2r hQT:`T?UVc "mM/H2 QTiBQMb 4 M2r "mM/H2UVc QTiBQMbXTmiAMiU6`;K2Mi`;mK2MibX_:nSPaAhAPL- TQbBiBQMVc 7`;Xb2i`;mK2MibUQTiBQMbVc B7UT`Q/m+i 44 S`Q/m+iXL1h6GPqV& 7`;Xb2ia+H2UM2r a+H2"BibUVVc ' ff A7 r2 Kmbi iQ b2i Bi BM i?2 +m``2Mi TQbBiBQM B7 UiSQbBiBQMV & 7`;K2MinHBbin;`T?X`2KQp2UTQbBiBQMVc 7`;K2MinHBbin;`T?X//UTQbBiBQM- 7`;Vc ' 2Hb2 & ff // i i?2 7BMH Q7 i?2 ``v 101 7`;K2MinHBbin;`T?X//U7`;Vc ' `2im`M 7`;c ' f q?2M i?2 mb2` brBT2 iQ Qi?2` rBM/Qr iBK2- r2 Kmbi `27`2b? i?2 +m``2Mi- M2ti M/ Hbi rBM/Qr !T`K +QMi2ti *QMi2ti Q7 i?2 TTHB+iBQM 6AsJ1 Bb M22/2/\ !T`K TQb TQbBiBQM Q7 i?2 +m``2Mi 7`;K2Mi !T`K bQm`+2 M2r aQm`+2 f Tm#HB+ pQB/ mT/i2S;2bU*QMi2ti +QMi2ti- BMi TQb- BMi bQm`+2V & i?BbXbQm`+2 4 bQm`+2c ff 6AsJ1 QMHv Y@R ff lT/i2 i?2 7`;K2Mib B7 Ui?BbXQ`B2MiiBQM 44 *QM7B;m`iBQMXP_A1LhhAPLnGL.a*S1V & 7Q`UhQT:`T? Bi2K , 7`;K2MinHBbin;`T?V& ff *?2+F B7 i?2 Bi2K Bb BMBiBi2/ B7UBi2K 54 MmHHV & Bi2KXQMaQm`+2*?M;2U+QMi2ti- bQm`+2Vc ' ' ' 2Hb2 & 7Q`UhQT.i Bi2K , 7`;K2MinHBbiV& ff *?2+F B7 i?2 Bi2K Bb BMBiBi2/ B7UBi2K 54 MmHHV & Bi2KXQMaQm`+2*?M;2U+QMi2ti- bQm`+2Vc ' ' ' ' f *?M;2 i?2 +m``2Mi Q`B2MiiBQM M/ /2H2i2 i?2 `272`2M+2b Q7 i?2 7`;K2Mib f Tm#HB+ pQB/ b2iP`B2MiiBQMUBMi Q`B2MiiBQM- BMi TQbBiBQMV & i?BbXQ`B2MiiBQM 4 Q`B2MiiBQMc ff A7 M2r +QM7B;m`iBQM Bb GM/b+T2- r2 Kmbi /2bi`Qv i?2 `272`2M+2 Q7 hQT.i6`;K2Mi B7 Ui?BbXQ`B2MiiBQM 44 *QM7B;m`iBQMXP_A1LhhAPLnGL.a*S1V & ff _2KQp2 i?2 7`;K2Mib K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT.i6`;K2MiU TQbBiBQMVVX+QKKBiUVc 102 Appendix J. Adaptador de la vista de Tops B7 UTQbBiBQM 44 yV & K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT.i6`;K2MiU TQbBiBQM Y RVVX+QKKBiUVc ' 2Hb2 B7 UTQbBiBQM 44 eV & K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT.i6`;K2MiU TQbBiBQM @ RVVX+QKKBiUVc ' 2Hb2 & K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT.i6`;K2MiU TQbBiBQM Y RVVX+QKKBiUVc K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT.i6`;K2MiU TQbBiBQM @ RVVX+QKKBiUVc ' ' 2Hb2 & ff q2 Kmbi /2bi`Qv i?2 `272`2M+2 Q7 hQT:`T?6`;K2Mi ff _2KQp2 i?2 7`;K2Mib K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT:`T?6`;K2MiU TQbBiBQMVVX+QKKBiUVc B7 UTQbBiBQM 44 yV & K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT:`T?6`;K2MiU TQbBiBQM Y RVVX+QKKBiUVc ' 2Hb2 B7 UTQbBiBQM 44 eV & K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT:`T?6`;K2MiU TQbBiBQM @ RVVX+QKKBiUVc ' 2Hb2 & K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT:`T?6`;K2MiU TQbBiBQM Y RVVX+QKKBiUVc K6`;K2MiJM;2`X#2;BMh`Mb+iBQMUVX`2KQp2U;2ihQT:`T?6`;K2MiU TQbBiBQM @ RVVX+QKKBiUVc ' ' MQiB7v.ia2i*?M;2/UVc ' !Pp2``B/2 Tm#HB+ BMi ;2iAi2KSQbBiBQMUP#D2+i Q#D2+iV & `2im`M SPaAhAPLnLPL1c ' f a2i i?2 2p2Mib BM i?2 +m``2Mi hQT.i f Tm#HB+ pQB/ b2i1p2MibUGBbiIhQT1p2Mi= 2p2Mib- #QQH2M mT/i2- #QQH2M TQbBiBQM- BMi Bi2KSQbBiBQMV & UUhQT.iV ;2iAi2KUBi2KSQbBiBQMVVXb2i1p2MibU2p2Mib- mT/i2- TQbBiBQMVc ' f a2i i?2 ;`T? Bi2Kb BM i?2 7`;K2Mi 103 !T`K b2`B2b _2bTQMb2 7`QK i?2 b2`p2` rBi? i?2 b2`p2` !T`K TQbBiBQM SQbBiBQM Q7 i?2 7`;K2Mi !T`K 7BHi2`b 6BHi2`b BM i?Bb TQbBiBQMX h?2v ``v +M #2 2KTiv f Tm#HB+ pQB/ b2i:`T?Ai2KbU:`T?JmHiBTH2*QHH2+iBQM b2`B2b- BMi TQbBiBQM- GBbiI.i*QHH2+iQ`hQTX7BHi2`hQT= 7BHi2`bV & UUhQT:`T?V ;2iAi2KUTQbBiBQMVVX/`r:`T?Ub2`B2b- TQbBiBQM- 7BHi2`bVc ' f _2im`M i?2 MmK#2` Q7 T;2b f !Pp2``B/2 Tm#HB+ BMi ;2i*QmMiUV & ff a?Qr d iQiH T;2bX `2im`M LlJnAh1Jac ' f _2im`M i?2 iBiH2 Q7 i?2 T;2 !T`K TQbBiBQM +imH T;2 TQbBiBQM !`2im`M h?2 iBiH2 Q7 i?2 T;2 f !Pp2``B/2 Tm#HB+ ai`BM; ;2iS;2hBiH2UBMi TQbBiBQMV & GQ+H2 H 4 GQ+H2X;2i.27mHiUVc brBi+? UTQbBiBQMV & +b2 y, `2im`M +QMi2tiX;2iai`BM;U_Xbi`BM;XiBiH2nb2+iBQMRVXiQlTT2`*b2UHVc +b2 R, `2im`M +QMi2tiX;2iai`BM;U_Xbi`BM;XiBiH2nb2+iBQMkVXiQlTT2`*b2UHVc +b2 k, `2im`M +QMi2tiX;2iai`BM;U_Xbi`BM;XiBiH2nb2+iBQMjVXiQlTT2`*b2UHVc +b2 j, `2im`M +QMi2tiX;2iai`BM;U_Xbi`BM;XiBiH2nb2+iBQM9VXiQlTT2`*b2UHVc +b2 9, `2im`M +QMi2tiX;2iai`BM;U_Xbi`BM;XiBiH2nb2+iBQM8VXiQlTT2`*b2UHVc +b2 8, `2im`M +QMi2tiX;2iai`BM;U_Xbi`BM;XiBiH2nb2+iBQMeVXiQlTT2`*b2UHVc +b2 e, `2im`M +QMi2tiX;2iai`BM;U_Xbi`BM;XiBiH2nb2+iBQMdVXiQlTT2`*b2UHVc ' `2im`M MmHHc ' ' Apéndice K Clase para la gestión de alarmas Código K.1 Contenido del fichero notifications/Alarms.java. T+F;2 M2iX`2/#Q`/2`X`2/#Q`/2`XMQiB7B+iBQMbc BKTQ`i +QKX+iBp2M/`QB/X[m2`vXa2H2+ic BKTQ`i M2iX`2/#Q`/2`X`2/#Q`/2`XKQ/2HbXH`Kc BKTQ`i DpXmiBHXGBbic f *Hbb iQ rQ`F rBi? H`Kb f Tm#HB+ +Hbb H`Kb & ff GBbi Q7 H`Kb GBbiIH`K= H`Kbc Tm#HB+ H`KbUV& ff AMBi i?2 H`Kb H`Kb 4 M2r a2H2+iUVX7`QKUH`KX+HbbVXQ`/2`"vU]B/ .1a*]VX2t2+mi2UVc ' f :2i MQi pB2r H`Kb f Tm#HB+ GBbiIH`K= ;2iLQioB2rH`KbUV& `2im`M M2r a2H2+iUVX7`QKUH`KX+HbbVXr?2`2U]oB2r 4 \]- yVX2t2+mi2UVc ' f :2i i?2 bBx2 Q7 MmK#2` Q7 MQi pB2r H`Kb f Tm#HB+ BMi ;2iLmK#2`LQioB2rH`KbUV& `2im`M ;2iLQioB2rH`KbUVXbBx2UVc ' f :2i i?2 bBx2 Q7 MmK#2` Q7 MQi pB2r H`Kb Q7  b2`p2` f 105 Índice de Códigos 5.1. Variables definidas para los eventos de IPS de la vista RAW. 35 5.2. Uso del patrón ViewHolder en la lista de eventos de la vista RAW. 36 5.3. Lanzamiento de la actividad de creación de nueva cuenta 38 5.4. Método para la creación de una cuenta en Android 40 5.5. Instanciación y agregación de un fragmento a la actividad 42 5.6. Fragmento del fichero de vista activity_raw.xml 42 5.7. Interaz definida por_q.i 42 5.8. Interaz definida por_q:`T? 43 5.9. Interaz definida porJQMBiQ`GBbi6`;K2Mi 44 5.10. FunciónQM.ioB2rGQ/definida enJQMBiQ`+iBpBiv 45 5.11. Interaz definida porJQMBiQ`JT6`;K2Mi 45 5.12. Clase para la representación de las ventanas de información en el mapa 46 5.13. Método para centrar el mapa 46 5.14. Modificación del ángulo máximo de un gráfico circular 47 5.15. Método para mostrar la lista de alarmas en la actividad_q*iBpBiv 47 A.1. Contenido del fichero build.gradle 53 B.1. Contenido del fichero AndroidManifest.xml 55 C.1. Contenido del fichero models/User.java 59 D.1. Contenido del fichero models/alarm.java 61 E.1. Contenido del fichero models/MenuItemCustom.java 63 F.1. Contenido del fichero dataCollector/DataCollectorRAW.java 65 G.1. Contenido del fichero graph/GraphManager.java 75 H.1. Contenido del fichero gcm/GCMRegister.java 89 I.1. Contenido del fichero accounts/authenticator.java 93 J.1. Contenido del fichero top/TopPagerAdapter.java 97 K.1. Contenido del fichero notifications/Alarms.java 105 113 Bibliografía [1] Varios autores, Activities in android developer reference,http://developer.android.com/reference/ android/app/Activity.html, Septiembre 2008. [2] ,Android developer reference,http://developer.android.com/develop/index.html, Septiembre 2008. [3] , Making listview scrolling smooth,http://developer.android.com/training/improving-layouts/ smooth-scrolling.html, Septiembre 2008. [4] ,Manifest permissions in android developer reference,http://developer.android.com/reference/ android/Manifest.permission.html, Septiembre 2008. [5] Daniel Nadeau, Holograph library documentation,https://bitbucket.org/danielnadeau/ holographlibrary/wiki/Home. [6] Javier Pacheco, Restrung documentation,https://github.com/47deg/appsly-android-rest/tree/restrung- 1.1, 2013. [7] Michael Pardo, Activeandroid documentation,http://www.activeandroid.com, 2013. 115 Índice alfabético Android, 2 iOS, 2 Proactividad, 1 Reactividad, 1 redBorder Flow, 3 redBorder IPS, 3 redBorder Monitor, 3 117 Glosario EDI Entorno de desarrollo integrado. 29 FCAPS Fault, Configuration, Accounting, Performance and Security. 1 GCM Google Cloud Messaging. 38 HTTP Hypertext Transfer Protocol. 7 OLAP On-Line Analytical Processing. 4 ORM Object-Relational mapping. 32 REST Representational State Transfer. 7 SDK Software Development Kit. 29 119