Ing. Téc. en Inform. de Sistemas Trabajo Teórico POO marzo, 2010
DESARROLLO DE APLICACIONES EN ANDROID Carlos García García David Hernández Pulido Javier Montejo Berlingen
Departamento de Informática y Automática Universidad de Salamanca (http://diaweb.usal.es)
Información de los autores: Carlos García García
Alumno de la asignatura de Programación Orientada a Objetos Ingeniería Técnica en Informática de Sistemas Departamento de Informática y Automática
[email protected] David Hernández Pulido
Alumno de la asignatura de Programación Orientada a Objetos Ingeniería Técnica en Informática de Sistemas Departamento de Informática y Automática
[email protected] Javier Montejo Berlingen
Alumno de la asignatura de Programación Orientada a Objetos Ingeniería Técnica en Informática de Sistemas Departamento de Informática y Automática
[email protected]
Este documento puede ser libremente distribuido. © 2010 Departamento de Informática y Automática - Universidad de Salamanca.
Resumen Hoy en día, una nueva generación de teléfonos móviles, conocidos como smartphones o teléfonos inteligentes, ocupan las primeros puestos en el mercado. Estos teléfonos son completamente capaces de ejecutar aplicaciones programadas por el usuario. El problema radica en grandes diferencias entre las plataformas de hardware que hacen que la portabilidad sea casi imposible. Android es un sistema operativo diseñado para smartphones, que proporciona una capa de abstracción completa, y haciendo por tanto t anto todas las aplicaciones portables, independientemente del hardware subyacente. También se ocupa de la gestión de los limitados recursos del teléfono en comparación con otros tipos de dispositivos. Este documento ofrece una visión en los aspectos básicos de Android. Aunque algunos aspectos generales de su integración en los teléfonos móviles son necesariamente mencionados, el objetivo principal es discutir acerca de cómo trata el paradigma de la orientación a objetos. A través del uso eficiente de las herramientas de programación orientada a objetos que nos proporciona, Android es capaz de ofrecer al programador un marco de trabajo que facilita enormemente su labor. Los aspectos básicos de cómo Android consigue este propósito a través de programación orientada a objetos se examinan a fondo, incluyendo algunos ejemplos de implementación que pensamos pueden ser esclarecedores.
Trabajo Teórico POO
i
Abstract Nowadays, a new generation of mobile phones, known as “smart-phones” are topping the markets. These phones are fully capable of running user-programmed applications. The problem comes from the large hardware differences between platforms which makes portability almost impossible. Android is a operating system designed for smart-phones, it provides a complete abstraction layer, and therefore making every application portable regardless of the underlying hardware. It also deals with the management of the limited resources of the phone. This document offers an insight in the basic aspects of Android. Although some general aspects of its integration in mobile phones is necessarily mentioned, the main goal is to discuss its object oriented paradigm. Through the efficient use of the tools that object oriented programming provides us, Android is able to offer the programmer a framework which eases enormously his work. The basics aspects of how Android reaches this goal through object oriented programming are discussed at length, including some implementation examples where we thought that they might be enlightening.
ii
Trabajo Teórico POO
Tabla de Contenidos 1.
INTRODUCCIÓN ....................................................................................................... ....................................................................................................... 1 1.1.
Historia ................................................................................................................ ................................................................................................................ 1
1.2.
Mercado ................................................................... .............................................................................................................. ........................................... 2
1.2.1 1.3.
Aplicaciones .................................................................... ................................................................................................... ............................... 4
1.3.2
Application Framework .................................................................................. .................................................................................. 4
1.3.3
Librerías .......................................................................................................... .......................................................................................................... 5
1.3.4
Runtime de android....................................................................... ......................................................................................... .................. 5
1.3.5
Kernel de Linux .............................................................................................. .............................................................................................. 5
2.1.
IDEs ......................................................................... .................................................................................................................... ........................................... 7
2.2.
Android SDK Y ADT ......................................................................................... 7
2.3.
4.
Paquetes ................................................................... .............................................................................................................. ........................................... 5
HERRAMIENTAS DE DESARROLLO .................................................................... 7
2.2.1 3.
Arquitectura ......................................................................... ........................................................................................................ ............................... 4
1.3.1
1.4. 2.
Ventajas de Android frente a otros sistemas ................................................... 3
Emulador......................................................................................................... Emulador.............................................................. ........................................... 8 Native Development Kit ..................................................................................... 8
MÁQUINA VIRTUAL V IRTUAL DALVIK ............................................................................... 9 3.1.
Funcionamiento ................................................................................................... ................................................................................................... 9
3.2.
Diferencias respecto a la MV de Java ................................................................. 9
3.3.
Optimización ....................................................................................................... ....................................................................................................... 9
ANATOMÍA DE UNA APLICACIÓN ANDROID ................................................. ................................................. 11 4.1.
Activity .............................................................................................................. .............................................................................................................. 11
4.1.1
Ciclo de vida ................................................................................. ................................................................................................. ................ 12
4.1.2
Tareas ............................................................................................................ ............................................................................................................ 13
4.2.
Intent e Intent Filters ......................................................................................... ......................................................................................... 14
4.2.1
Objeto Intent ................................................................................................. ................................................................................................. 14
4.2.2
Resolución de Intents.................................................................... .................................................................................... ................ 15
4.3.
Service ............................................................................................................... ............................................................................................................... 15
4.4.
Content Provider ............................................................................................... ............................................................................................... 15
Trabajo Teórico POO
iii
5.
6.
4.5.
Broadcast Receivers .......................................................................................... .......................................................................................... 16
4.6.
Otros .................................................................................................................. .................................................................................................................. 16
ESTRUCTURA DE UN PROYECTO ...................................................................... ...................................................................... 19 5.1.
Manifiesto ................................................................ ......................................................................................................... ......................................... 19
5.2.
Layout ............................................................................................................... 21
5.2.1
Contenedores ................................................................................................ 22
5.2.2
Widgets ......................................................................................................... ......................................................................................................... 23
5.2.3
Reutilización ................................................................................................. ................................................................................................. 24
GOOGLE MAPS ....................................................................................................... ....................................................................................................... 25 6.1. 6.1.1
MapView ...................................................................................................... 25
6.1.2
MapActivity .................................................................................................. .................................................................................................. 25
6.1.3
MapController............................................................................................... ............................................................................................... 25
6.2. 7.
8.
iv
Clases básicas....................................................................... .................................................................................................... ............................. 25
Ejemplo ............................................................................................................. ............................................................................................................. 26
FACILIDADES DE ANDROID ............................................................................... 29 7.1.
Location ................................................................... ............................................................................................................ ......................................... 29
7.2.
Telephony ...................................................................................................... .......................................................................................................... .... 29
7.3.
Reconocimiento de gestos ................................................................. ................................................................................. ................ 30
CONCLUSIONES ..................................................................................................... ..................................................................................................... 31
Trabajo Teórico POO
Tabla de Ilustraciones Ilustración 1 – Logo de la plataforma Android ..................................................................... 1 Ilustración 2 – Logo de la Open Handset Alliance ................................................................ 1 Ilustración 3 – Porcentaje de dispositivos móviles Android por cada versión a 12/4/2010 .. 2 Ilustración 4 – Gráfico de los S.O. para smartphones según el uso de la red de datos.......... 2 Ilustración 5 – Gráfica del número de nuevas aplicaciones para Android ............................ 3 Ilustración 6 – Componentes del S.O. Android ..................................................................... 4 Ilustración 7 – Logo de Eclipse ........................................................................... ............................................................................................. .................. 7 Ilustración 8 – IDE Eclipse y emulador de Android ejecutándose sobre un S.O. Linux ....... 8 Ilustración 9 – Diagrama de estados del ciclo de vida de una actividad ............................. 13 Ilustración 10 – Herramienta de creación de GUIs ............................................................. 21 Ilustración 11 – Ejemplo de aplicación creada mediante el uso de Google Maps............... 27
Trabajo Teórico POO
v
GLOSARIO Acelerómetro:
instrumento destinado a medir aceleraciones. Frecuentemente se utiliza para conocer la velocidad y desplazamiento de un cuerpo en uno o varios ejes dimensionales. ADT: Android Development Tools
es la clase responsable de una ventana dentro de una aplicación. Representa los elementos visuales y reacciona a las acciones del usuario Activity
Android Developer Challengue:
concurso creado por Google para fomentar el desarrollo
de aplicaciones en Android. Android Market: aplicación de red que permite publicar aplicaciones a los desarrolladores
para ponerlas a disposición de los l os usuarios. Bytecode:
código intermedio, más abstracto que el código máquina, y que necesita de un mediador o máquina virtual para poder ser transformado y ejecutado en el hardware. Dalvik: nombre de la máquina
virtual utilizada por el sistema operativo Android. JAR: acrónimo de Java Archive. Es una agrupación de varios ficheros Java y se usa generalmente para la distribución conjunta de clases y metadatos. Manifiesto: es un archivo XML que describe a la aplicación y sus componentes NDK: Native development kit. Smartphone: dispositivo móvil que supone una evolución de los teléfonos móviles, con la inclusión de pantalla táctil, teclado, te clado, conexión wifi, aplicaciones de usuario como navegador web o cliente de correo, entre otros. Widget: combinación de la palabra window gadget . Es un componente gráfico utilizado en interfaces de usuario, con el cual el usuario puede interactuar.
vi
Trabajo Teórico POO
1.
INTRODUCCIÓN
Android en un Sistema Operativo además de una plataforma de software basada en el núcleo de Linux (monolítico). Se ha diseñado en un principio para el control de dispositivos móviles mediante librerías Java, aunque su versatilidad le hace propicio para otros dispositivos empotrados. Para su creación se han teniendo en cuenta los avances tecnológicos en los diferentes terminales móviles, por ello el sistema soporta bluetooth, wifi y pantallas táctiles.
1.1. Historia La historia de este S.O. comienza en Junio del 2005, momento en el cual Google compró una pequeña compañía cuya finalidad era el desarrollo de aplicaciones para dispositivos móviles: Android Inc. Uno de los cofundadores de aquella compañía, Andy Rubin, pasaría posteriormente a ser el director de la división de plataformas móviles de Google. Aquella empresa era desconocida para el mundo de las tecnologías en aquellos años, a pesar de lo cual el grupo de fundadores tenía gran experiencia en plataformas web, telecomunicaciones y aplicaciones móviles.
Ilustración 1 – Logo de la plataforma Android
El 5 de Noviembre del 2007 se anuncia la creación de la Open Handset Alliance, una organización cuyo objetivo es la difusión de la plataforma móvil Android. Está formada por fabricantes de equipos y prestadores de servicios de tecnología que unieron fuerzas para lanzar el primer S.O abierto para móviles, que no estaría atado a su funcionamiento en una marca o dispositivo concreto, sino que gracias a su kernel de Linux, podría ser adaptado a casi cualquier dispositivo. Para sorpresa - y alegría - de muchos, cinco días después del anuncio Google lanza un SDK, que incluía un emulador de Android para ir probando las primeras líneas de código.
Ilustración 2 – Logo de la Open Handset Alliance
-1-
Desarrollo de aplicaciones en Android
Su lanzamiento inicial fue el 21 de Octubre de 2008 con la versión 1.0. Tras varias correcciones y nuevas implementaciones el sistema se encuentra en su versión 2.1 a fecha del 17 de Marzo de 2010. La siguiente gráfica obtenida de la web “Android Developers” muestra el porcentaje de dispositivos Android que utilizan una determinada versión:
Ilustración 3 – Porcentaje de dispositivos móviles Android por cada v ersión a 12/4/2010
Por cada nueva versión de la plataforma se ha ido añadiendo un nivel más a la API, estando dividida en Abril del 2010 en siete niveles.
1.2. Mercado Con el avance de las nuevas tecnologías se han incrementado las posibles funcionalidades del móvil en relación a las nuevas formas de comunicación lo que ha conllevado al desarrollo de nuevos sistemas operativos para smartphones. A continuación se observa un gráfico que muestra el panorama actual de los diferentes S.O. según el uso que hacen del tráfico de red:
Ilustración 4 – Gráfico de los S.O. para smartphones según el uso de la red de datos
A pesar de que Symbian –propiedad de Nokia - es el líder respecto a las ventas de móviles, no lo es en cambio en el uso de Internet, campo en el que domina iPhone OS, que en principio se plantea como el principal obstáculo de Android. Sin embargo, el hecho de que Android se haya creado con el objetivo de poder correr sobre terminales de distintos fabricantes abre un nuevo panorama en el mercado de las aplicaciones para móviles. Además, el hecho de la existencia del Android Market; un espacio para la distribución y venta de aplicaciones, abierto a todos los desarrolladores y sin intermediarios, permitirá la
Trabajo Teórico POO
2
García et al.
posibilidad de hacer un buen negocio apostando por esta plataforma. Es por ello que como se observa en la siguiente gráfica el número de aplicaciones para Android sigue creciendo, a pesar de que a fecha de escritura de este texto el número de terminales con S.O.Android no es todavía suficientemente elevado y las empresas e mpresas no están aun obteniendo los beneficios esperados.
Ilustración 5 – Gráfica del número de nuevas aplicaciones para Android
1.2.1 Ventajas de Android frente a otros sistemas sistemas •
•
•
•
•
•
•
3
Está apadrinado por Google, que actualmente es uno de los gigantes de la informática, por lo que esta intentará que todos los servicios que ofrece estén también disponibles para la plataforma Android. Un claro ejemplo es Google Maps, que aun estando la API también disponible para otros sistemas, solo en Android con el total de sus características. Más recientemente la red social Buzz de Google acaba de ser adaptada para este S.O. La liberación gratuita del SDK permite también a empresas con pocos recursos y jóvenes emprendedores desarrollar aplicaciones para los dispositivos que utilicen este S.O. Android Market facilita la difusión de las aplicaciones creadas, así como el pago por estas. Es un sistema que puede instalarse en una gran cantidad de dispositivos diferentes ( al contrario que el S.O. para móviles de Apple ), y este número va aumentando a medida que se sacan nuevos drivers, lo que facilita que el número de comunidades de usuarios y el soporte vaya aumentando. Es licenciable bajo GPL, lo que potencia el software libre. Esto significa que un programador puede realizar modificaciones en el código de los programas, al contrario que si este no estuviera disponible. Las APIs permiten crear casi cualquier cosa, facilitando el trabajo y motivando a los desarrolladores, además de la existencia de concursos financiados por diferentes empresas y organizaciones. La prueba la tenemos en la buena acogida que ha tenido el Android Developer Challengue, con gran participación y excelentes proyectos. Permite personalizar el teléfono móvil y su entorno de funcionamiento.
Trabajo Teórico POO
Desarrollo de aplicaciones en Android
•
Es multitarea permitiendo ejecutar aplicaciones en segundo plano. Esto ya lo consiguió hacer Nokia en un dispositivo móvil, pero aun así supone una ventaja con respecto a otros SS.OO. que todavía no poseen esta característica.
1.3. Arquitectura El sistema operativo Android está formado principalmente por los siguientes componentes:
Ilustración 6 – Componentes del S.O. Android
1.3.1 Aplicaciones
Android suministra un amplio espectro de aplicaciones para que el usuario pueda satisfacer sus necesidades, además de la posibilidad de añadir nuevas mediante el ya mencionado Android Market. Por defecto se incluye un cliente de correo electrónico, programa de SMS, calendario, mapas, navegador, contactos, etc… 1.3.2 Application Framework
Los desarrolladores tienen pleno acceso a las mismas APIs del framework usadas por las aplicaciones básicas. La arquitectura se ha diseñado para simplificar la reutilización de componentes: cualquier aplicación puede publicar sus capacidades para que otro programa pueda hacer uso de estas, sujeto a las limitaciones de seguridad impuestas. Este mismo mecanismo permite que los componentes c omponentes que puedan ser reemplazados por el usuario.
Trabajo Teórico POO
4
García et al.
1.3.3 Librerías
Incluye un conjunto de librerías C / C + + usadas por diversos componentes del sistema. Algunas son: System C Library ( implementación de la biblioteca C Standard ), bibliotecas de medios, bibliotecas de gráficos, bibliotecas 3D, SQLite, etc… 1.3.4 Runtime de android
Android incluye un set de bibliotecas base que proporcionan la mayor parte de la funcionalidad disponible en las bibliotecas base de Java. Cada aplicación Android corre en su propio proceso, con su propia instancia de la máquina virtual Dalvik. Esta MV ha sido escrita de forma que un dispositivo pueda correr múltiples máquinas virtuales de forma eficiente. Dalvik ejecuta archivos en el formato Dalvik Executable (.dex), el cual está optimizado para usar la menor cantidad de memoria que sea posible. La máquina virtual está basada en registros, y corre clases compiladas por Javac que han sido transformadas al formato.dex por la herramienta “ dx”. 1.3.5 Kernel de Linux
El sistema operativo está basado en la versión 2.6 del núcleo de Linux que actúa como una capa de abstracción entre el hardware y el del conjunto de software, además de prestar los servicios de seguridad, gestión de memoria, gestión de procesos, red y drivers.
1.4. Paquetes Android reutiliza a una gran cantidad de paquetes ya existentes como son los del lenguaje Java ( java.util, java.net, etc… ), pero a la vez también añade una gran cantidad de paquetes propios que aportan mayores posibilidades a las aplicaciones que sean desarrolladas mediante su uso. Estos son algunos que se han considerado relevantes: •
android:
contiene las clases correspondientes a los recursos ( imágenes, modelos de IG, atributos… ) utilizados por las aplicaciones.
•
android.app:
•
android.bluetooth: clases para el manejo de la tecnología bluetooth.
•
android.database:
proporciona clases que encapsulan el modelo general de una aplicación. Algunas de las clases más importantes – activity, application o service – se encuentran en este paquete. contiene clases para explorar los datos devueltos por un
proveedor de contenidos.
5
•
android.database.sqlite:
posee las clases necesarias para el manejo de bases de datos SQLite. Este es un sistema de gestión de bases de de datos que no está basado en el modelo cliente-servidor en el que el SGBD es un proceso independiente, sino que la biblioteca SQLite se enlaza con la aplicación pasando a ser parte integral de la misma. Este es el sistema comúnmente usado a la hora de instalar bases de datos locales en un dispositivo Android.
•
android.graphics:
•
android.hardware:
•
android.media: clases para controlar las diferentes interfaces de audio y video.
•
android.net.wifi: gestión de la funcionalidad wifi del dispositivo.
proporciona herramientas gráficas de bajo nivel tales como filtros de color, puntos, o rectángulo, que permiten dibujar en la pantalla. provee soporte para dispositivos hardware que pueden no estar presente en todos los teléfonos móviles ( por ejemplo la cámara ).
Trabajo Teórico POO
Desarrollo de aplicaciones en Android
•
android.opengl:
utilidades para la generación de gráficos 2D y 3D mediante la API OpenGL, ampliamente usada en otros campos para el desarrollo de videojuegos, CAD o realidad virtual.
•
android.os:
clases para el uso de los servicios básicos del sistema operativo, como son los mecanismos IPC.
•
android.text:
es un paquete dedicado al tratamiento de textos: copiar y pegar, texto con formato, etc…
•
android.util:
proporciona diversos útiles como la fecha, calendarios, locales ( idiomas ), tablas hash, etc…
•
android.view::
•
android.view.accessibility:
•
android.webkit:
clases que manejan la disposición de los elementos en la pantalla y la interacción con el usuario. paquete de accesibilidad al sistema para personas con capacidades disminuidas. Se antojaba bastante necesario, ya no solo para ayudar a los discapacitados sino también para otros usuarios como pueden ser los ancianos. Es por esto que le fue solicitado a Google un paquete con estas características, y a pesar de que todavía no está maduro y le queda mucho por desarrollar, ya se han desarrollado algunas aplicaciones con él. Un ejemplo es el proyecto Eyes-Free, pensado para gente con visibilidad nula o reducida, que se compone de un motor texto-voz ( imprescindible para un ciego si quiere enterarse de lo que le comunican por un SMS ) y de una funcionalidad que permite que no sea necesario mirar la pantalla táctil para hacer uso de ella ( Más información en http://obm.corcoles.net/20090429/usa-el-movil-sin-mirar-con-eyes-free/ ). http://obm.corcoles.net/20090429/usa-el-movil-sin-mirar-con-eyes-free/ ). herramientas para la navegación web. WebKit supone la base del navegador Safari, y fue liberado por Apple en 2005. Actualmente es usado entre otros en los navegadores Mozilla Firefox y Google Chrome y en el framework Qt. Proporciona un analizador sintáctico de HTML y un intérprete de JavaScript.
Trabajo Teórico POO
6
2.
HERRAMIENTAS DE DESARROLLO
Obviamente resultaría muy complicado programar una aplicación directamente desde el teléfono móvil por las limitaciones que este tiene: •
La pantalla es mucho más pequeña.
•
El teclado, en caso de tenerlo, es mucho más pequeño.
•
•
Los dispositivos de señalamiento, si existen, son molestos ( un lápiz ) o inexactos (dedos grandes y "multi-táctil LCD" no son una buena mezcla). La memoria y la velocidad de la CPU son mucho más ajustadas en comparación con la de un ordenador de sobremesa.
Es por ello que existen herramientas que permiten crear y probar las aplicaciones a lo largo de su desarrollo.
2.1. IDEs El IDE que acapara casi la totalidad de los productos desarrollados para Android es Eclipse, y por ello la mayor parte de la documentación que se puede encontrar en webs y manuales hace referencia a este entorno de desarrollo. Eclipse es multiplataforma y de código abierto y soporta varios lenguajes de programación. El paquete Eclipse IDE for Java Developers (descargable a través de http://www.eclipse.org/downloads/ ) incluye las herramientas esenciales para la programación en Java y se puede usar por tanto para desarrollar aplicaciones para Android en conjunción con el SDK de Android y el plugin ADT ( Android Development Tools ) for Eclipse. Toda la información relativa a estos dos elementos se puede encontrar en la web Android Developers.
Ilustración 7 – Logo de Eclipse
También existe la posibilidad de programar con otros IDEs, pero estos cuentan con un uso y apoyo mucho menores, y en consecuencia menor es la documentación al respecto siendo más
complicado resolver los problemas que surjan a la hora de configurar el entorno y desarrollar aplicaciones. El IDE NetBeans es el segundo en importancia – a mucha distancia de Eclipse - y es posible encontrar información sobre su configuración para Android en la siguiente dirección: http://wiki.netbeans.org/IntroAndroidDevNetBeans
2.2. Android SDK Y ADT Google aparte de liberar el SDK incluye en el mismo un emulador para fomentar la creación de aplicaciones. En este SDK podemos encontrar las l as librerías para programar, documentación y códigos de ejemplo. Está implementado para todas las plataformas y su versión actual es la 2.1. La diferencia entre unas versiones y otras son cuestiones de soporte y ampliaciones de la propia API.
-7-
Desarrollo de aplicaciones en Android
Además se ha desarrollado un plugin para el IDE Eclipse llamado ADT, el cual facilita mucho la depuración de programas para esta plataforma. 2.2.1 Emulador
Imita todo el hardware y software de un dispositivo móvil típico, aunque pueda tener algunas limitaciones. El emulador de Android proporciona una buena variedad de métodos de navegación: las teclas de control, que puede "presionar" con el ratón simulando el apuntador de un dispositivo móvil o el teclado para generar eventos para su aplicación. También ofrece una pantalla en la que se muestran las aplicaciones desarrolladas, junto con las otras aplicaciones Android, así como varias capacidades de depuración que permiten simular el recibimiento de llamadas telefónicas, mensajes de texto o conexiones mientras la aplicación se ejecuta. Durante el desarrollo de una aplicación, el emulador de Android puede iniciarse como una aplicación independiente desde una línea de comandos ( útil cuando quiera establecer los parámetros de la simulación ) o puede usarlo como parte de su entorno de desarrollo Eclipse, donde existen otros métodos de configuración.
Ilustración 8 – IDE Eclipse y emulador de Android ejecutándose sobre un S.O. Linux
Las únicas limitaciones que el emulador presenta en su versión actual ( Android SDK 2.1 ) son: •
No hay soporte para hacer o recibir llamadas de teléfono reales. Se puede simular llamadas telefónicas ( realizadas y recibidas ) a través del emulador de la consola.
•
No hay soporte para las conexiones USB ni Bluetooth.
•
No hay soporte para cámara de captura de video ( entrada ).
•
No hay soporte para los auriculares del dispositivo.
•
•
No hay soporte para determinar el nivel de carga de la batería y el estado de carga de CA. No hay soporte para determinar que se ha insertado/expulsado una tarjeta SD.
A pesar de todo está en constante mejora y muchas de estas limitaciones serán eliminadas.
2.3. Native Development Kit El NDK de Android es es un conjunto conjunto de herramientas que permite integrar componentes que hagan uso del código nativo en las aplicaciones Android. El NDK permite al desarrollador implementar las partes de su código utilizando lenguajes nativos como C y C + +. Esto puede proporcionar beneficios a ciertas clases de aplicaciones, en forma de reutilización de código existente.
Trabajo Teórico POO
8
3.
MÁQUINA VIRTUAL DALVIK
Android utiliza una máquina virtual propia llamada Dalvik, que ha sido diseñada para optimizar memoria y recursos de hardware en un entorno de teléfonos móviles. A diferencia de la máquina virtual de Java, basada en el uso de pilas, la máquina virtual Dalvik está basada en registros. Como curiosidad, indicar que el nombre Dalvik viene de un pueblo en Islandia, hogar de los antepasados del ingeniero que diseñó la máquina virtual.
3.1. Funcionamiento Dalvik es una máquina virtual intérprete que ejecuta archivos en el formato Dalvik Executable (*.dex), un formato optimizado para el almacenamiento eficiente y ejecución mapeable en memoria. Su objetivo fundamental es el mismo que cualquier máquina virtual, permite que el código sea compilado a un bytecode independiente de la máquina en la que se va a ejecutar, y la máquina virtual interpreta este bytecode a la hora de ejecutar el programa. El hecho de no utilizar la máquina virtual de Java (aparte de posibles aspectos legales y de propiedad) es la necesidad de optimizar al máximo los recursos y enfocar el funcionamiento de los programas hacia un entorno de escasos recursos en cuanto a memoria, procesador y almacenamiento. La máquina virtual Dalvik ( DalvikVM, Dalvik virtual machine ) está basada en registros y puede ejecutar clases compiladas por un compilador Java y que posteriormente han sido convertidas al formato nativo usando la herramienta “dx”. La máquina virtual corre por encima de un kernel Linux 2.6, sobre el cual delega las tareas relacionadas con la gestión de hilos y memoria a bajo nivel. La DalvikVM ha sido también optimizada para que haya múltiples instancias suyas funcionando con un coste muy bajo de memoria. El hecho de usar varias máquinas virtuales protege las aplicaciones, de forma que el fallo o cierre inesperado de una de ellas no afecte para nada a las demás. El hecho de funcionar sobre un núcleo Linux implica que es posible escribir aplicaciones en C/C++ que funcionen directamente sobre el kernel. Aunque es posible hacer esto, solo en ciertas ocasiones es ventajoso.
3.2. Diferencias respecto a la MV de Java Las máquina virtual de Java, disponible en la mayoría de los ordenadores hoy en día, está basada en el uso de pilas. Por contra, la DalvikVM está basada en registros. Esto es debido a que los procesadores de los teléfonos móviles están optimizados para la ejecución basada en registros. Además, las máquinas virtuales basadas en registros permiten una ejecución más rápida, a costa de programas que ocupan más espacio tras la compilación. A pesar de usar Java para la programación, el bytecode de Java no es ejecutable en un sistema Android Por otra parte, las librerías Java que utiliza Android son ligeramente distintas de las incluidas en Java Standard Edition (Java SE) o en Java Mobile Edition (Java ME). A pesar de las ligeras diferencias en su mayor parte el contenido de las librerias es idéntico.
3.3. Optimización Es capaz de reducir bastante el tamaño del programa buscando información duplicada en las diversas clases y reutilizándola. La “recogida de basura” (liberar el espacio de objetos ya no accesibles) ha sido perfeccionada a fin de mantener siempre libre la máxima memoria posible.
-9-
Desarrollo de aplicaciones en Android
Android hace un uso extenso del XML como forma de definir las interfaces gráficas y otros elementos. Los archivos XML tienen que ser linkeados igualmente a la hora de compilar y son convertidos igualmente a bytecode para mejorar el rendimiento.
Trabajo Teórico POO
10
4.
ANATOMÍA DE UNA APLICACIÓN ANDROID
Hay cuatro bloques básicos que componen una aplicación Android: •
Activity
•
Intent
•
Service
•
Content Provider
No todas las aplicaciones tienen porque tener los cuatro elementos, la mayoría tendrá una combinación de ellos, pero al menos ha de tener uno. Hay que enfatizar, que todos los elementos de Android son objetos y por tanto estos cuatro no son ninguna excepción. El comportamiento de cada uno de ellos está definido en su correspondiente clase base ( por ejemplo android.app.Service ) y todo elemento que queramos implementar será una subclase del elemento original. A través de la herencia evitamos volver a implementar aspectos comunes a todos los objetos del mismo tipo, mientras que podemos personalizar tanto como queramos su comportamiento sobrescribiendo los métodos de la clase padre. Los elementos que componen la aplicación han de figurar en un archivo llamado AndroidManifest.xml. Este archivo XML contiene la declaración de los componentes de la aplicación, sus capacidades y requisitos. Se tratará esto en más detalle de este archivo en secciones posteriores. Antes de entrar a hablar en detalle de cada uno de los componentes hacemos una breve presentación de cada uno. •
Activity:
•
Intent:
•
Una actividad es cada una de las pantallas dentro de una aplicación. Es la responsable de presentar los elementos visuales y reaccionar a las acciones del usuario. Toda actividad se inicia como respuesta a un Intent.
se puede considerar como un deseo de realizar una tarea. Cuando se lanza un Intent el sistema busca que actividades son capaces de dar respuesta a ese Intent y elige la más adecuada. Service: Un servicio es una
tarea que se ejecuta durante periodos prolongados y no
interacciona con el usuario. •
Content Provider:
Un proveedor de contenido es un almacén de información provisto de una API mediante la cual el usuario y aplicaciones pueden acceder al contenido sin necesidad de conocer los detalles del almacenamiento.
Podríamos añadir un quinto elemento, Broadcast Receiver, a los cuatro anteriores. Registramos un Broadcast Receiver para escuchar y procesar Intents generales, como la hora o la entrada de un mensaje, y posteriormente lanzar las Actividades o Servicios deseados. Pasamos ahora a tratar en mayor detalle cada uno de estos elementos constituyentes.
4.1. Activity Las actividades son probablemente el elemento más común en una aplicación para Android. Una actividad se puede definir como una única pantalla o interfaz dentro de una aplicación. Las actividades mostrarán una interfaz de usuario basada en vistas ( Views ) y responderá a eventos. En un sentido estricto, es posible construir una actividad sin interfaz de usuario, sin embargo no es lo apropiado ya que tenemos los Services y Content Providers destinados
-11-
Desarrollo de aplicaciones en Android
a esa finalidad. De cualquier forma hay que remarcar que la actividad es responsable de mostrar la interfaz gráfica, sin embargo ésta no forma parte de la actividad. Todos los elementos gráficos y visuales se definirán dentro de una vista, View. Ésto garantiza la separación del aspecto funcional del aspecto visual, facilitando en gran medida el desarrollo posterior. Cada actividad se implementa como una única subclase que hereda de la clase android.app.Activity. De esta forma, no necesitamos preocuparnos de muchos de los aspectos relacionados con el funcionamiento de las actividades ya que por herencia nuestra actividad contendrá ya esa funcionalidad. De nuevo estamos reaprovechando código común a una familia de objetos haciendo uso de la herencia. Normalmente una aplicación constará de varias actividades, por ejemplo una aplicación que gestiona mensajes puede tener una pantalla de configuración, otra para escribir mensajes, una tercera para elegir el contacto al cual se desea enviar el mensaje y otra más para navegar por los mensajes enviados y recibidos. Cada una de estas pantallas estará implementada por una actividad diferente. Una actividad puede iniciar otra actividad, por ejemplo al pulsar un botón. De esta forma iremos navegando por las distintas pantallas de la aplicación, siendo cada una de ellas una actividad. 4.1.1 Ciclo de vida
Las actividades son manejadas mediante una pila de actividades. Cuando una nueva actividad es iniciada la anterior es pausada y almacenada en una pila de actividades. Cuando la nueva actividad termine, la siguiente actividad en la pila es reactivada. Puesto que el sistema puede decidir finalizar una actividad pausada o detenida por motivos de memoria cada actividad es responsable de salvar su estado de forma que sea posible restaurarla tras haber sido pausada o detenida. Una actividad puede estar en cuatro estados: •
•
•
•
Activa: si la actividad está en primer plano en la pantalla, y por tanto en la parte superior de la pila de actividades está activa y ejecutándose. Pausada: si la actividad ha dejado de estar en primer plano pero aún es visible ( una nueva actividad que no ocupa toda la pantalla o es traslucida ha sido llamada ) pasa a estar pausada. Una actividad pausada se puede considerar completamente activa, conserva su estado y toda la información, pero puede ser finalizada por el sistema en casos extremos de falta de recursos. Detenida: si una actividad no es visible pasa a ser detenida. Puede mantener activa la información sobre su estado, aunque lo más probable es que sea finalizada por el sistema para liberar memoria y recursos. Hay que tener en cuenta que Android está diseñado para el campo de los teléfonos móviles y por tanto tiene en cuenta la más que probable escasez de memoria. Cualquier aplicación y actividad que no sea visible será detenida para liberar recursos. Sin embargo la actividad debe guardar su estado actual de ejecución de forma que cuando la actividad vuelva a ser la primera en la pila pueda recuperar el estado en el que estaba por última vez. Para ello existen métodos de la clase, como son onSaveIntanceState() y onRestoreInstanceState(), de esta forma, se puede guardar el estado de la Actividad antes de hacerla vulnerable a ser finalizada por el sistema. Finalizada: una vez que la actividad ha completado su ejecución libera todos los recursos que estaba utilizando y finaliza el ciclo. Si es llamada de nuevo iniciará el ciclo completamente a diferencia de una actividad detenida, la cual aún almacena su estado de ejecución a fin de recuperarlo cuando sea llamada de nuevo.
Trabajo Teórico POO
12
García et al.
Ilustración 9 – Diagrama de estados del ciclo de vida de u na actividad
Como se vio anteriormente una actividad puede iniciar otra dentro de la misma aplicación. De la misma forma puede iniciar otra de una aplicación externa. Si nuestra actividad necesita hacer uso de una posición en un mapa por ejemplo, podemos recurrir a otra actividad que gestiona mapas y posiciones, solo necesitamos hacer uso de los Intents , que veremos posteriormente. De esta forma estaremos haciendo uso de actividades externas que para el usuario aparecerán como integradas en nuestra aplicación. a plicación. 4.1.2 Tareas
Una tarea es lo que el usuario percibe como una aplicación. Es una pila de actividades que se han ido llamando sucesivamente, algunas de ellas posiblemente fuera de la aplicación original. No es posible reordenar o navegar por la pila de actividades, al igual que en cualquier pila solo podemos acceder y cerrar la actividad superior o crear una nueva encima.
13
Trabajo Teórico POO
Desarrollo de aplicaciones en Android
El sistema Android permite iniciar varias tareas. Cuando el usuario pulsa el botón HOME o BACK, toda la tarea es minimizada mientras el usuario ejecuta otras aplicaciones. Al volver, toda la tarea se restaura y de nuevo la última actividad de la pila pasa a estar activa y accesible para el usuario.
4.2. Intent e Intent Filters Una de las piezas claves de Android es la clase Intent. Un Intent describe lo que una aplicación desea que se haga, podría considerarse como declarar una necesidad. Por ejemplo, una aplicación puede requerir visualizar una página web. Para ello crearía un nuevo Intent con la acción VIEW y añadiría como datos la URI ( Uniform Resource Identifier ) de la página web deseada. Por otra parte hay una clase relacionada llamada IntentFilter. Mientras un Intent es un deseo de hacer algo, un Intent Filter es una declaración de las capacidades de una aplicación. De esta forma, en el ejemplo anterior el sistema registraría la creación de un Intent y buscaría qué aplicaciones son capaces de resolverlo. Una actividad puede declarar sus Intent Filters tan genéricos o específicos como desee, teniendo en cuenta los datos asociados al Intent. Por ejemplo una actividad se puede declarar capaz de visualizar imágenes JPG pero no serlo para PNG. Los Intent e Intent Filters son una manera de encapsular tareas, aislar dependencias y asegurar la reutilización de funcionalidades. •
•
•
Cada aplicación es responsable únicamente de su funcionamiento, sabiendo que para realizar cualquier tarea que no sea de su ámbito únicamente debe lanzar un Intent. De esta forma podemos construir aplicaciones centradas en una única actividad y cuyo trabajo puede ser reaprovechado por otras aplicaciones. Los Intents sirven como interfaz de comunicación entre aplicaciones, el equivalente a una API. Cualquier aplicación puede lanzar su Intent sin necesidad de conocer ningún detalle sobre la aplicación que lo va a resolver. No hay interdependencia entre aplicaciones, cualquier actividad puede ser reemplazada por otra que tenga sus mismos Intent Filter y este reemplazo será transparente para todos los procesos que usaban la funcionalidad original. Cuando una aplicación registra su Intent Filter y por tanto se declara capaz de manejar una tarea, esta aportando una funcionalidad que el resto de aplicaciones ya no necesitan implementar. Por tanto su código será reutilizado por todas las aplicaciones que lo necesiten para ejecutar el Intent deseado, cumpliendo así con una de las premisas básicas de la programación orientada a objetos, la reutilización.
4.2.1 Objeto Intent
El objeto Intent se compone de tres partes: acción, categoría y datos. Adicionalmente puede incluir un conjunto de elementos opcionales. •
•
•
Acción: es una cadena de texto completamente cualificada que indica la acción a realizar. Por ejemplo, android.intent.action.VIEW. Categoria:
metadatos
referidos
al
Intent,
por ejemplo, android.intent.category.LAUNCHER nos indica que el Intent puede iniciar una aplicación si así es requerido Datos: están definidos en forma de un objeto URI, por ejemplo, content://contacts/123
Trabajo Teórico POO
14
García et al.
En este ejemplo la actividad desea ver los datos de contacto de la persona con ID 123 para lo cual lanza el Intent correspondiente, con los campos indicados anteriormente. Cuando una actividad lanza un Intent, normalmente se trata de una invocación implícita. La actividad indica la tarea que desea realizar y el sistema asigna el Intent a la aplicación más apropiada. Otra forma de proceder es que la actividad indique explícitamente el destinatario del Intent, en este caso se tratará de una invocación explícita. Sin embargo esto no es recomendable ya que estamos creando una dependencia innecesaria, y el hecho de desinstalar el paquete del destinatario provocará errores en la aplicación emisora del Intent. 4.2.2 Resolución de Intents
Hay tres tipos de componentes Android que pueden registrarse para resolver Intents: Activity, BroadcastReceiver, y Service. Estos componentes se declaran capaces de tratar Intents registrando elementos
en el archivo AndroidManifest.xml. Cada elemento es parseado en un objeto IntentFilter. Cuando se instala el paquete, el sistema toma nota de los componentes que pueden tratar los diversos Intents. Una vez registrados, cada vez que se emita el Intent el sistema elegirá el elemento más adecuado para procesarlo según nuestras preferencias.
4.3. Service Un servicio es un proceso cuyo periodo de ejecución se extiende durante un tiempo largo y que carece de interfaz gráfica. Un buen ejemplo sería un reproductor de música. La interfaz y el proceso de elegir y activar una lista de reproducción estaría manejado por una actividad, sin embargo la reproducción en si estaría manejado por un servicio, ya que el usuario espera que la música siga sonando aunque lance nuevas actividades. En cualquier momento una actividad puede asociarse a un servicio para modificar su comportamiento o detenerlo. En el ejemplo anterior, el usuario podría regresar a la actividad que gestiona el reproductor para saltar la canción que está sonando. Los servicios pueden ser clasificados en locales l ocales y remotos. Un servicio local solo puede ser accedido por la aplicación que lo contiene. En el ejemplo anterior el servicio probablemente sería local ya que no tenemos ningún interés en que otras aplicaciones puedan detener la reproducción o pasar canciones. Un servicio remoto permite a otras aplicaciones asociarse con él mediante el método bindService() para de esta forma tomar el control. Si por ejemplo estuviéramos interesados en que sonara una canción en concreto cuando iniciamos el lector de mensajes el servicio de reproducción de música sería remoto. Como ya hemos dicho, un servicio carece de interfaz gráfica, sin embargo tiene la capacidad de lanzar notificaciones para informar al usuario.
4.4. Content Provider A la hora de almacenar datos, cada aplicación puede optar por su propio mecanismo, como pueden ser archivos, bases de datos, archivos de configuración o cualquier otro soporte. Un proveedor de contenido define una interfaz que recubre el método de almacenamiento, proporcionando unos métodos de forma que cualquier aplicación pueda acceder al contenido sin necesidad de conocer la implementación del almacenamiento, únicamente conociendo los métodos de acceso de ésta nueva API. De esta forma es mucho más sencillo compartir información con otras aplicaciones ya que proporcionan un nivel de abstracción respecto al
15
Trabajo Teórico POO
Desarrollo de aplicaciones en Android
almacenamiento y todas las aplicaciones acceden a la información a través de unas funciones comunes para todos los proveedores de contenido. Un claro ejemplo de proveedores de contenido, que viene ya implementado en cualquier sistema Android, es la gestión de los contactos. Cualquier aplicación puede acceder a los datos de la agenda a través de la API del proveedor de contenido. Se puede acceder a los datos contenidos en un proveedor de contenido a partir de su URI. Cada proveedor ha de definir su URI, por ejemplo: public static final Uri CONTENT_URI = Uri.parse("content://com.ruta.subruta/datos");
A partir de aquí, se puede acceder a los datos individuales mediante expresiones semejantes a las usadas en SQL. Se envía una consulta al proveedor de contenido y este devuelve un objeto cursor mediante el cual se pueden ir recolectando individualmente los datos, haciendo uso de las funciones get(...), update(...), insert(...), delete(...). Los proveedores de contenido son un elemento muy útil de abstracción, ya que ofrecen un método de acceso a los datos contenidos ocultando cualquier detalle interno. De esta forma estamos mejorando la cohesión del sistema sin provocar dependencias, cualquier aplicación sabe como acceder a los datos e igualmente puede ofrecer datos a los que todos pueden acceder permitiendo a la vez una completa libertad a la hora de implementar el almacenamiento.
4.5. Broadcast Receivers La mejor forma de ver un Broadcast Receiver es como un servicio capaz de registrar Intents referidos a eventos generales, como la llegada de un mensaje de texto o una llamada. Al igual que los servicios carece de interfaz de usuario, sin embargo es perfectamente posible hacer que el Broadcast Receiver ejecute una aplicación. De esta forma podemos programar actividades y servicios como respuesta a eventos. Otra particularidad es que el procesamiento de Intents no es exclusivo. Cuando una aplicación lanza un Intent, una y solo una actividad será elegida para tratarlo. En el caso de Broadcast Receivers, todos aquellos que se hayan registrado para responder a un Intent serán notificados y por tanto serán iniciados con el Intent correspondiente. Una actividad puede lanzar Intents para Broadcast Receivers, pero en ese caso no será posible establecer permisos o niveles de seguridad. El Intent es lanzado al sistema y todo aquel registrado para recibirlo lo recibirá. Algunos de los
Intents que pueden recibir por parte del sistema son por ejemplo ACTION_TIME_CHANGED cuando el usuario cambia la hora del dispositivo, o ACTION_PACKAGE_REMOVE cuando se desinstala un paquete.
Una forma de crear servicios que funcionen siempre que el teléfono está encendido es registrar un BroadcastReceiver que espere recibir el Intent BOOT_COMPLETED para lanzar el servicio. De esta forma se lanzará el servicio en cuanto se encienda el teléfono.
4.6. Otros Hemos mencionado, al hablar de las Actividades, que poseen una interfaz gráfica hacia el usuario y sin embargo la codificación del aspecto gráfico no se realiza dentro del objeto Actividad. Esto es así porque poseen la función setContentView(View) mediante la cual muestran la interfaz almacenada en un objeto de tipo View. No vamos a entrar en detalles sobre la composición e implementación de las diversas opciones gráficas en View pero queremos remarcar esta separación entre el aspecto funcional de la aplicación, la actividad; y el aspecto gráfico contenido en View. Esta separación es un Trabajo Teórico POO
16
García et al.
elemento básico de la programación orientada a objetos, cada objeto es responsable de una única tarea y se comunica con los demás mediante funciones establecidas. En cualquier momento podremos modificar cualquier aspecto de la actividad o de la vista sin afectar a la otra parte, siempre que respetemos los canales de comunicación.
17
Trabajo Teórico POO
5.
ESTRUCTURA DE UN PROYECTO
Es muy importante saber que archivos componen un proyecto Android antes de dedicarse a escribir código como un loco. Por ello se procederá a explicar a continuación cuales son los ficheros que contendrán el código, recursos o instrucciones de generación de una aplicación: aplic ación: •
•
•
•
•
•
AndroidManifest.xml: es un archivo que describe la aplicación. bin/: guardará la aplicación ya compilada. El archivo classes.dex será el ejecutable. Contendrá además las clases compiladas y al archivo *.ap_ que mantendrá los recursos de la aplicación. default.properties: contiene la configuración del proyecto. Es generado y modificado automáticamente por el IDE. Guarda similitudes con un makefile. libs/: mantiene los JARs ( Java ARchive es un tipo de archivo que permite ejecutar aplicaciones escritas en Java ) que la aplicación requiera para su ejecución. El fundamental es android.jar . El usado para crear aplicaciones que hagan uso de Google Maps es maps.jar . src/: guarda el código fuente de la aplicación, siendo por tanto donde se alojan las subclases de activity creadas. res/: contiene diversos recursos que se emplean en la aplicación. A su vez contiene otras carpetas para cada tipo, a destacar:
•
•
•
drawable/: permite añadir las imágenes que se desean usar en la aplicación, como fondo de un widget o como icono por ejemplo. values/: ficheros XML donde se definen cadenas, dimensiones, etc… layout/: contiene los archivos XML que definen el diseño de las diferentes interfaces gráficas de la aplicación.
menu/: especificaciones XML que definen menús.
xml/: archivos XML con otros fines.
assets/: sirve para guardar ficheros y datos, por ejemplo recursos, pero estos pierden su formato original y necesitan de la clase AssetManager para su uso. Por esa razón no se suele utilizar. gen/: contiene ficheros Java autogenerados, destacando R.java ( el cual contiene constantes numéricas, correspondiéndose cada una con uno de los recursos de la carpeta res/ y de la assets/). build.xml: contiene una sentencia de comandos para compilar la aplicación e instalarla en un dispositivo. No existe en Eclipse/ADT.
El archivo que se requiere para la ejecución de la aplicación en el dispositivo móvil es el de extensión .apk . Este es un fichero comprimido que contiene el .dex, el manifiesto, y los recursos
5.1. Manifiesto Es un archivo XML que describe e indica los componentes de la aplicación que se esté desarrollando. Se encuentra en el directorio fuente del proyecto, siendo estas sus principales nodos ( etiquetas ) y propósitos:
-19-
Desarrollo de aplicaciones en Android
•
Es el nodo padre o raíz, que contendrá al resto. Indica el nombre del paquete que el desarrollador crea para su aplicación.. Se usa también para guardar el número de versión de la aplicación si existiesen varias, y así poder saber cual es la más reciente ( versionCode ), lo cual es muy importante en el desarrollo de un proyecto software. Este no es sin embargo el número de versión que se muestra a los usuarios de la aplicación, sino el indicado en versionName. :
•
: Declara los permisos que la aplicación. necesita ( algunos ejemplos son INTERNET, READ_CONTACTS, CAMERA…). Por seguridad serán
presentados al usuario durante la instalación por si quisiese denegarlos, ya que sino se podría dar el caso de que una aplicación maligna tuviese permiso SEND_SMS y se dedicase a mandar mensajes de texto a otros terminales sin el conocimiento del usuario. •
: Define nuevos permisos que otras aplicaciones requerirán para poder
acceder a partes restringidas de esta. A dichos permisos se les podrá asignar un nivel de protección ( normal, dangerous, … ) para saber si durante la ejecución se pueden conceder con directamente o mediante una nueva confirmación del usuario e incluso se podrán agrupar varios dentro de un mismo grupo. Para esto se creará un al que se dará un nombre, y después se asignará dicho nombre a la propiedad android:permissionGroup de . Las otras aplicaciones harán uso de cada permiso o de un grupo entero mediante . •
•
:
El desarrollo de la plataforma Android hace que vaya aumentando el número de niveles de la API, proveyendo estos nuevas clases y/o paquetes, e incluso reemplazando partes que se han mejorado y quedan ahora obsoletas ( aunque la política empleada es la de mantener ambas partes para evitar la incompatibilidad de antiguas aplicaciones en nuevas versiones ). En ocasiones también se incluyen nuevos nodos y propiedades para el manifiesto. Es por esto que mediante tres propiedades de esta etiqueta se controlan sobre que versiones de la plataforma puede ejecutarse una aplicación. android:minSdkVersion especifica el nivel mínimo de la API en el que puede funcionar ( si no se cumple la aplicación no comenzará a ejecutarse ) y posee el valor 1 por defecto y android:maxSdkVersion: el máximo ( aunque es habitual no declarar valor máximo ). Por su parte, android:targetSdkVersion indica el nivel de la API sobre el cual está diseñado para ejecutarse la aplicación ( nivel óptimo ). Ocurre que a veces la aplicación pueda usar elementos o comportamientos de dicho nivel, en lugar de limitarse a los existentes en el nivel mínimo que limitan al programa. :
Indica mediante sus propiedades ciertos metadatos de la aplicación como el título e icono. Es el nodo padre de , , y ( y estos a su vez contienen definiciones de entre otros datos ). Este nodo especifica también si se está en modo debug o no, da nombre al proceso sobre el que correrá la aplicación o asigna un tema visual común a todas las actividades.
Trabajo Teórico POO
20
García et al.
•
:
indica múltiples propiedades de cada actividad, entre ellas las relacionadas con el multiproceso y la forma en que se mostrará la activity en la pantalla. Puede haber varias dentro de un . >
•
:
especifica una biblioteca compartida con la que el programa se ha de vincular. Los paquetes android. Son linkados por defecto, y solo es necesario importar los que se vayan a usar desde el código fuente. Sin embargo existen ciertas bibliotecas que no lo hacen automáticamente, como son el awt y los mapas de Google.
Por supuesto existen otras muchas expresiones para describir la aplicación, incluso algunas usadas únicamente para el desarrollo y testeo de la aplicación, siendo sin embargo las aquí mencionadas las de uso más común.
5.2. Layout Aunque es posible usando el lenguaje Java instanciar y posicionar widgets a nuestra activity, la forma más común de realizar dicha tarea será usar un fichero XML denominado Layout ( pueden crearse varios, lo suyo es uno por cada activity ). El principal motivo para hacer esto es que facilita la utilización de herramientas específicas de creación de modelos de GUI, en las que el usuario va disponiendo los widgets sobre la pantalla según le parezca y con las propiedades que desee, todo ello sin tener que programar puesto que el código sería simultáneamente generado por la herramienta usada. Además el hecho de crear la interfaz apartada de las funcionalidades permite facilitar la separación de la vista y el modelo de datos.
Ilustración 10 – Herramienta de creación de GUIs
En la imagen superior se observa que se ha creado una interfaz con tres widgets ( botón, texto y reloj ) que posee como fondo una imagen añadida por el usuario a los recursos. Para modificar la interfaz durante la ejecución necesitaremos del archivo R.java que corresponde
a una clase no heredable y autogenerada. Esta contiene otras clases estáticas ( una por tipo de recurso ) con identificadores para cada recurso ( layouts y widgets entre ellos ), permitiendo acceder a ellos desde el código Java de la aplicación.
21
Trabajo Teórico POO
Desarrollo de aplicaciones en Android
public final class R { public static final class attr { } public static final class drawable { public static final int fondo fondo=0x7f020000; =0x7f020000; public static final int icon icon=0x7f020001; =0x7f020001; } public static final class id { public static final int AnalogClock01 =0x7f050004; public static final int Button01 Button01=0x7f050002; =0x7f050002; public static final int LinearLayout01 =0x7f050000; public static final int LinearLayout02 =0x7f050003; public static final int TextView01 =0x7f050001; } public static final class layout { main=0x7f030000; =0x7f030000; } public static final int main // […] }
Ahora es muy sencillo poder hacer uso de los recursos en una aplicación. Por ejemplo se muestra como asignar el layout main ( el único que se ha creado ) a una clase activity. Basta con poner dentro del código de esa clase la siguiente línea: setContentView(R.layout.main setContentView(R.layout. main); );
5.2.1 Contenedores
Existen unos elementos llamados contenedores ( también denominados layouts, pero no
deben confundirse con los archivo Layout ) que ayudan a posicionar y agrupar los widgets dentro de ellos. Dichos contenedores pueden contener a su vez a otros. Así pues en cada archivo xml usado para definir un modelo de interfaz gráfica se suelen incluir diferentes contenedores ( normalmente por lo menos uno que ocupe toda la pantalla y que contenga al resto ) que ajusten totalmente lo que aparece en la ventana respecto a lo que quiere el diseñador. Estos son los más comunes: •
LinearLayout:
Alinea a los widgets uno detrás de otro vertical u horizontalmente ( según se especifique en la propiedad android:orientation. ). Permite además configurar el tamaño de estos: cada widget dentro de un contenedor posee .las propiedades android:layout_width y android:layout_height que especifican su anchura y altura. Estas propiedades pueden tomar tres valores: un valor numérico que indica los píxeles exactos; wrap_content que hace que el widget ocupe justo el tamaño que necesite; o fill_parent para que el widget se expanda para ocupar todo el espacio que quede disponible en el contenedor. Se puede ajustar también la distancia del widget a cada uno de los cuatro bordes del layout ( mediante las propiedades padding ).
•
RelativeLayout:
dispone a cada widget basándose en su relación con el resto, p. ej si quisiesemos a un widget A debajo y a la izquierda de otro B, y encima de C.
•
TableLayout:
permite crear una tabla invisible. . A su vez, este contenedor se compone de varios TableRow ( filas ) El número de filas será especificado por el programador, mientras que el número mínimo de columnas será igual al número de widgets de la fila más larga, siendo posible que un widget ocupe varias celdas de una misma fila.
Trabajo Teórico POO
22
García et al.
5.2.2 Widgets
Como ya se ha visto, el SDK de Android proporciona una colección de widgets, todos ellos con su correspondiente etiqueta XML y su clase, yendo estos desde los más simples hasta algunos más complejos como las galerías de imágenes. A continuación se listan algunos de los más comunes con ejemplos ilustrativos de código: •
TextView:
una etiqueta de texto no editable por el usuario. Se suele usar para identificar widgets adyacentes. La clase TextView posee los diferentes métodos para su modificación. En el siguiente ejemplo se observa como se procedería si se
quisiese cambiar el texto “HELLO” de la Ilustración 10 por otro durante la ejecución: TextView texto = (TextView)findViewById(R.id.TextView01 TextView01); ); texto.setText("HOLA" texto.setText("HOLA"); );
En la primera línea se observa como el método findViewById(), de la clase Activity, permite instanciar cualquier elemento de IG declarado en la carpeta de recursos, siendo necesario hacer un casting a la clase correspondiente. Ya en la segunda línea se ejecuta el cambio de texto haciendo uso de la instancia creada. •
Button:
es un botón del cual se pueden modificar todos los aspectos de su apariencia. Su objetivo es realizar una acción al ser pulsado. Para ejemplificar esto se va a mostrar como se haría para que al pulsar un botón se pase de la activity actual a otra distinta. Este sería el código de la acción a realizar:
private OnClickListener accionBoton = new OnClickListener() { onClick(View v) { public void onClick(View Intent intent = new Intent(); intent.setClass(Actividad. this, NuevaActividad. NuevaActividad. class); startActivity(intent); finish(); } };
Este código realiza el cambio mediante un intent, iniciando la nueva actividad y finalizando la actual. Para que sea esto lo que se ejecute al pulsar el botón es necesario añadir lo siguiente en la actividad: boton.setOnClickListener( accionBoton accionBoton); ); Hay que resaltar además que los métodos de esta. •
Button
hereda de
TextView,
lo que le permite usar
EditText: es una clase derivada de TextView empleada como texto editable. En el Layout se puede configurar mediante diversas propiedades para que actúe como el diseñador quiera: android:capitalize para poner o automáticamente la primera letra en mayúscula, android:autoText para obtener ayuda ortográfica, android:singleLine para controlar si el texto editable es de una o varias
líneas, etc… •
•
CheckBox:
casilla de verificación con dos estados: marcado y sin marcar. Su clase tiene un método, isChecked(), para comprobar su estado. Hereda indirectamente de Button a través de CompoundButton. RadioButton: hereda también de CompoundButton y se suelen usar en grupo mediante RadioGroup ( subclase de LinearLayout ). Esta última clase permite
conocer cuál de todos los botones que agrupa es el que está marcado ( getCheckedRadioButtonId() ), así como desmarcar todos ( clearCheck () ).
23
Trabajo Teórico POO
Desarrollo de aplicaciones en Android
•
Image View:
permite instar imágenes. Estas pueden corresponden a los recursos, pero también se puede establecer basándose en el contenido de una URI, usando el método SetImage().
5.2.3 Reutilización
A pesar de que Android ofrece una buena variedad de widgets con la posibilidad de poderlos modificar a gusto del diseñador, muchas veces esto no es suficiente. Sería más útil poder reutilizar una interfaz compleja con alguna utilidad concreta que se suela repetir comúnmente en las aplicaciones, por ejemplo un diálogo de identificación o login que cuente con un una etiqueta, un texto editable, un botón y una barra de progreso. Esta necesidad ha sido satisfecha en los Layouts de Android mediante el uso del nodo , que requiere que se le indique una referencia al Layout que se quiere incluir dentro de otro, e incluso hacer alguna modificación sobre él. Esto también es útil cuando existen varios Layouts con el mismo propósito pero diferentes estilos, pudiéndose incluir varios y hacer la elección de uso durante la ejecución. La reusabilidad de la funcionalidad de dichas interfaces suele ir de la mano de la Activity creada ( heredada ) para dicho propósito, que tendrá su propio fichero .java, volviéndolo a usar cuando se use dicha interfaz gráfica en otra aplicación.
Trabajo Teórico POO
24
6.
GOOGLE MAPS
Uno de los servicios más populares de Google es el por todos conocidos Google Maps. No es raro por tanto que Android lo integre a través del paquete com.google.android.maps. Sin embargo para poderlo utilizar es necesario obtener una clave de la API en la siguiente dirección: http://code.google.com/android/add-ons/google-apis/mapkey.html y añadir el correspondiente permiso en el manifiesto, puesto que no se trata de un paquete estándar. Resulta interesante hacer una mención a esta posibilidad que ofrece Android, puesto que a pesar de que existe en algunos otros sistemas, no lo hace con las mismas características. Además, la utilidad que se le puede dar a GMaps se acrecenta al pasar de un ordenador de sobremesa a un dispositivo móvil, puesto que en las situaciones en las que uno más necesitará de un mapa que le permita guiarse no tendrá posibilidad de echar mano de su PC.
6.1. Clases básicas Existen tres clases que son fundamentales a la hora de construir una aplicación que haga uso del servicio ofrecido por Google Maps. 6.1.1 MapView
Representa un mapa gracias a la información que obtiene del servicio del Google Maps. Esta clase hereda de android.view.ViewGroup y puede ser añadida al Layout .
Posee métodos para realizar los siguientes cometidos: •
•
Controlar
el
modo
de
vista:
setTraffic(boolean), isSatellite(), setStreetView(boolean)…
boolean
Mostrar diferentes controles para hacer uso del mapa: setBuiltInZoomControls(boolean), displayZoomControls()…
•
Guardar su estado: onSaveInstanceState(android.os.Bundle)
•
Control de eventos: onSizeChanged(...), onTouchEvent(...), …
6.1.2 MapActivity
Es la clase principal que contendrá el código con el que se haga uso de los diferentes servicios ofrecidos por Google Maps. Es una subclase de Activity, por lo que sus métodos y manejo es idéntico: creando una subclase a la medida de lo que necesite el desarrollador. La clase
MapView anteriormente comentada solo puede ser instanciada en una MapActivity que se haga cargo de la gestión de sus servicios y su eliminación. Esto se debe
a que depende de varios hilos para acceder a la red y el sistema de archivos en segundo plano, y dichos hilos deben ser guiados en conjunción con el ciclo de vida del MapActivity. Únicamente se admite un obtener resultados inesperados.
MapActivity
por proceso, en caso contrario se pueden
6.1.3 MapController
Gestiona el manejo de un mapa, como desplazamientos o zoom. Se obtiene como valor de retorno de MapView.getController(). Estos son algunos de sus métodos:
-25-
Desarrollo de aplicaciones en Android
animateTo (GeoPoint): Mueve el mapa hasta el La clase GeoPoint representa un punto geográfico
•
punto dado como parámetro. y su constructor recibe dos
enteros: la latitud y la longitud multiplicadas por 1E6. •
int setZoom(int):
Permite modificar el nivel de zoom. El parámetro tomará un valor entre 1 ( el más lejano ) y 21 ( el más cercano, estando solo disponible en ciertas ubicaciones ). Devuelve el nivel del zoom al que finalmente se ha situado.
•
stopAnimation(boolean):
Para cualquier animación que esté en progreso en ese momento, actualizando el centro del mapa a todo lo que la animación parcial haya llegado.
6.2. Ejemplo Se presenta ahora un sencillo ejemplo en el cual se va a obtener un mapa sobre la ciudad de Salamanca , pintandose dos círculos concéntricos encima de esta ( se omiten del código los paquetes importados ). Para esto es necesario conocer la existencia de la clases Overlay del paquete de GMaps. Esta permite dibujar elementos sobre el mapa y gestionar los eventos que sobre el dibujo acontezcan. El modo de uso es por herencia: se debe de hacer una subclase y crear las instancias de esta que sean necesarias. Posteriormente serán añadidas al mapa insertándolas en la lista devuelta por MapView.getOverlays(). Para su instanciación requiere de un objeto gráfico de la clase android.graphics.Canvas que será el que sea pintado en el MapView. Para el ejemplo propuesto este sería el código del Overlay: public class Simbolo extends Overlay { public void draw(Canvas canvas, MapView mapView, boolean shadow) { super.draw(canvas, mapView, shadow);
Paint dibujoInter = new Paint(); dibujoInter.setColor( Color.YELLOW Color.YELLOW ); ); Paint dibujoExter = new Paint(); dibujoExter.setColor( Color.RED Color.RED ); GeoPoint geo = mapView.getMapCenter(); Point punto = new Point(); mapView.getProjection().toPixels(geo, punto); canvas.drawCircle(punto.x, punto.y canvas.drawCircle(punto.x punto.y, 25, dibujoExter); canvas.drawCircle(punto.x canvas.drawCircle(punto. x, punto.y punto.y, 10, dibujoInter); } }
Se explica brevemente: se instancia un objeto Paint para cada círculo, se obtiene el centro del mapa y se traduce a píxeles, para posteriormente proceder a dibujar los dos círculos sobre dicho centro mediante el objeto Canvas pasado por parámetro. Ese código serviría para pintar sobre el mapa. Ahora solo queda proceder a la creación del mapa dentro de un MapActivity:
Trabajo Teórico POO
26
García et al.
public class mapa extends MapActivity { private MapView vistamapa = null; private MapController controller = null; private GeoPoint punto = null; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main setContentView(R.layout. main); ); double lat = 40.960659; double lon = -5.669643;
punto = new GeoPoint( (int) (lat*1E6), (int) (lon*1E6) ); vistamapa = ( MapView )findViewById(R.id.mapview )findViewById(R.id.mapview ); ); vistamapa.setBuiltInZoomControls( vistamapa .setBuiltInZoomControls(true); controller = vistamapa vistamapa.getController(); .getController(); controller.setCenter( controller .setCenter(punto punto); ); controller.setZoom(17); controller .setZoom(17); Canvas canvas = new Canvas(); Simbolo simb = new Simbolo(); simb.draw(canvas, vistamapa vistamapa, , true); vistamapa.getOverlays().add(simb); vistamapa.getOverlays().add(simb); } }
Este sería el resultado obtenido:
Ilustración 11 – Ejemplo de aplicación creada mediante el uso de Google Maps
27
Trabajo Teórico POO
7.
FACILIDADES DE ANDROID
Este capítulo pretende mostrar al lector algunos de los paquetes que Android provee para controlar el dispositivo para que pueda hacerse una idea de las posibilidades de esta plataforma.
7.1. Location Es el paquete que provee las clases necesarias para el manejo de GPS en Android. Para poder usarlo es necesario otorgar el permiso ACCESS_FIND_LOCATION a la aplicación. Sus elementos más relevantes son: •
Location: clase que representa una localización geográfica en un tiempo concreto.
•
LocationManager:
•
Geocoder:
•
LocationListener:
clase para gestionar el dispositivo de localización. Permite actualizaciones periódicas de la situación geográfica del dispositivo, o disparar un evento específico cuando el dispositivo entra en la proximidad de una zona geográfica determinada. Así por ejemplo para conocer la situació actual se utiliza LocationManager.getLastKnownLocation("gps"). clase que permite traducir entre direcciones físicas y coordenadas en latitud y longitud, y viceversa. interfaz que permite implementar una clase que captura los eventos asociados al dispositivo de localización.
Tiene múltiples utilidades, como pintar la posición del usuario en un mapa o transmitirla a otros dispositivos. Además es posible simular un GPS NMEA-compatible en el emulador, dado que la consola proporciona un comando que permite establecer la posición geográfica actual. Su sintaxis es la siguiente: geo , donde el primer parámetro sirve para especificar la longitud y latitud en grados, e incluso la altitud en metros si fuese necesario; mientras que el segundo permite enviar sentencias NMEA 0183.
7.2. Telephony No conviene que nos olvidemos que el S.O. Android en la mayoría de los casos se ejecutará sobre un teléfono móvil. Esto puede suponer ciertos problemas: •
•
•
Si la aplicación hace uso de un alto porcentaje de CPU sería un impedimento de cara a que se puedan recibir llamadas. Que las aplicaciones desarrolladas no colaboren convenientemente con el resto de aplicaciones y el S.O, por ejemplo no desvaneciéndose a segundo plano cuando hay una llamada entrante. No optimizar los recursos de forma que se agote la batería en poco tiempo ( el usuario no podría seguir usando el teléfono ), o que haya fugas de memoria que bloqueen el teléfono completamente, etc…
Pero no todo es malo, puesto que ese hecho le añadirá más funcionalidad: los usuarios pueden enviar y recibir llamadas, pero ahora además también podrán ser ayudados a ello. Supongamos por ejemplo que un empresario necesita una aplicación de gestión en su móvil. Dicha aplicación podría incorporar la posibilidad de poder llamar o mandar un mensaje directamente desde esta a los clientes y/o proveedores, con un solo click y sin tener que abandonar la aplicación. Es por esto que Android incorpora un paquete, android.telephony, que permite controlar la información del servicio telefónico y su manipulación: acceder a los contactos, -29-
Desarrollo de aplicaciones en Android
dividir un texto en varios SMS para que puedan ser enviados, gestionar el envío y recepción de mensajes, realizar llamadas, etc… El paquete en cuestión contiene varias clases para realizar dichas operaciones, aunque la que se encarga de regular y controlar el dispositivo es TelephonyManager. La forma de obtener un objeto de esta clase es la siguiente: TelephonyManager telefono=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE getSystemService(Context. TELEPHONY_SERVICE ); );
Esta forma es similar a la usada para el GPS o el servicio wifi. Teniendo en cuenta además que se trata de un servicio, habrá que hacer la correspondiente adición en el manifiesto. Una vez instanciada, podremos hacer uso de sus numeros métodos. métodos. Por ejemplo retorna el número de teléfono propio, getLine1Number() getNetworkOperatorName() devuelve el nombre del operador de telefonía utilizado, etc… Pero el método más importante es getCallState(). Este devuelve una constante que indica el estado de llamada del dispositivo, valor que deberá tenido en cuenta antes de realizar otras operaciones. Puede ser: •
CALL_STATE_IDLE: El teléfono no está en uso.
•
CALL_STATE_RINGING: Llamada solicitada.
•
CALL_STATE_OFFHOOK: Llamada en progreso.
A pesar de todo, el emulador no está preparado aun para simular muchas de las opciones del paquete, aunque provee un comando sms para simular envío de mensajes hacia el emulador.
7.3. Reconocimiento de gestos Algunos de los nuevos dispositivos móviles ahora incorporan acelerómetros y brújula; como ya llevan tiempo haciendo otras empresas como Apple en su Ipod y Nintendo con la Wii. Android, para no quedarse atrás, ha desarrollado la clase android.hardware.SensorManager que provee métodos para el reconocimiento y la creación de gestos que el usuario haga con el móvil ( por ejemplo un sacudido ). Esta tecnología puede tener muchas más utilidades de las que parece, principalmente para los videojuegos, supliendo la falta de teclado de los móviles táctiles con movimientos de este. A modo de curiosidad se le ofrece al lector visitar el siguiente enlace en el que se explica un proyecto que se está desarrollando para poder simular dichos gestos mediante el emulador usando el ratón, cometido que hasta ahora no había sido posible de ninguna forma: http://code.google.com/p/openintents/wiki/SensorSimulator
Trabajo Teórico POO
30
8.
CONCLUSIONES
El sistema operativo Android es un buen candidato para establecerse como opción principal dentro del sector de teléfonos móviles. Reúne múltiples características para convertirlo en la opción preferida. Es de código abierto, cualquier persona puede crear aplicaciones según su necesidad. Reutiliza un idioma de programación muy extendido, robusto y con abundante documentación como es Java. Optimiza la gestión de recursos, adecuándose a dispositivos de escasa memoria y procesador como son los teléfonos móviles. Por último cabe destacar el magnífico recurso que es la clase Intent. Permite al programador concentrarse en una tarea sabiendo que el resto están cubiertas por otras aplicaciones, estando la mayoría de ellas incluidas en las librerías de Android, como pueden ser el manejo de mapas, la gestión de contactos o la navegación web. De esta forma, todas estas funcionalidades adicionales quedan integradas en las aplicaciones propias, proporcionando al usuario una interfaz cohesionada, de forma que tareas recurrentes en múltiples aplicaciones sean siempre resueltas de la misma forma. A pesar de que las primeras versiones contenían abundantes errores, probablemente debidos a una publicación prematura, con el paso del tiempo el sistema ha madurado, siendo las últimas versiones muy estables y extendidas. En nuestra opinión lo que hace de Android un producto a tener muy en cuenta es el buen diseño de su arquitectura y funcionamiento. Incentivando (e incluso imponiendo) el uso de la reutilización de código, la separación de funcionalidades, sus múltiples niveles de abstracción que permiten modificar o reemplazar fácilmente sus componentes por separado y naturalmente el enfoque hacia un entorno de teléfonos móviles, buscando la máxima optimización posible de los recursos disponibles. Por todas estas razones auguramos un gran futuro para Android.
-31-
Bibliografía •
Murphy, Mark. L ( 2009 ): Beginning Android
•
Hashimi, Sayed Y. y Komatineni , Satya ( 2009 ): Pro Android
•
Meier, Reto ( 2009 ): Professional Android Application Development
•
Burnette, Ed ( 2008 ): Hello Android
•
Gramlich, Nicolas: AndBook
•
Android Developers: http://developer.android.com/
•
Wikipedia: http://es.wikipedia.org/
•
Kronox: http://kronox.org/
•
Androlib: http://www.androlib.com/
•
Eliax: http://eliax.com/index.cfm?post_id=4563
•
Google Mobile: http://www.google.com/mobile/maps/
•
OpenIntents: http://code.google.com/p/openintents/w/list
•
Package com.google.android.maps: http://code.google.com/intl/es-ES/android/addons/google-apis/reference/com/google/android/maps/package-summary.html
* Último acceso a todas las direcciones webs: 15 de Abril de 2010.
-33-