Вы находитесь на странице: 1из 41

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
carlosggg@usal.es

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
davidherpul@usal.es

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
javiermontejo@usal.es

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 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 Ventajas de Android frente a otros sistemas ................................................... 3
1.3. Arquitectura ........................................................................................................ 4
1.3.1 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
1.4. Paquetes .............................................................................................................. 5
2. HERRAMIENTAS DE DESARROLLO .................................................................... 7
2.1. IDEs .................................................................................................................... 7
2.2. Android SDK Y ADT ......................................................................................... 7
2.2.1 Emulador......................................................................................................... 8
2.3. Native Development Kit ..................................................................................... 8
3. MÁQUINA VIRTUAL DALVIK ............................................................................... 9
3.1. Funcionamiento ................................................................................................... 9
3.2. Diferencias respecto a la MV de Java ................................................................. 9
3.3. Optimización ....................................................................................................... 9
4. 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


4.5. Broadcast Receivers .......................................................................................... 16
4.6. Otros .................................................................................................................. 16
5. 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
6. GOOGLE MAPS ....................................................................................................... 25
6.1. Clases básicas .................................................................................................... 25
6.1.1 MapView ...................................................................................................... 25
6.1.2 MapActivity .................................................................................................. 25
6.1.3 MapController............................................................................................... 25
6.2. Ejemplo ............................................................................................................. 26
7. FACILIDADES DE ANDROID ............................................................................... 29
7.1. Location ............................................................................................................ 29
7.2. Telephony.......................................................................................................... 29
7.3. Reconocimiento de gestos ................................................................................. 30
8. CONCLUSIONES ..................................................................................................... 31

iv 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
Activity es la clase responsable de una ventana dentro de una aplicación. Representa
los elementos visuales y reacciona a las acciones del usuario
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 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, 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 versió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 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


• 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.

3 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 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: 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.
• android.bluetooth: clases para el manejo de la tecnología bluetooth.
• android.database: contiene clases para explorar los datos devueltos por un
proveedor de contenidos.
• 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: proporciona herramientas gráficas de bajo nivel tales como
filtros de color, puntos, o rectángulo, que permiten dibujar en la pantalla.
• android.hardware: provee soporte para dispositivos hardware que pueden no
estar presente en todos los teléfonos móviles ( por ejemplo la cámara ).
• android.media: clases para controlar las diferentes interfaces de audio y video.
• android.net.wifi: gestión de la funcionalidad wifi del dispositivo.

5 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:: clases que manejan la disposición de los elementos en la pantalla
y la interacción con el usuario.
• android.view.accessibility: 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/ ).
• android.webkit: 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 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 un 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: 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.
• 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 una 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.

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 <intent-filter> en el archivo
AndroidManifest.xml.
Cada elemento <intent-filter> 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 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:
• 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

• <manifest>: 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.
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="android.miaplicacion"
android:versionCode="1" android:versionName="1.0" >
• <uses-permission>: 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.
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" >
• <permission>: 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
<permission-group> al que se dará un nombre, y después se asignará dicho
nombre a la propiedad android:permissionGroup de <permission>. Las
otras aplicaciones harán uso de cada permiso o de un grupo entero mediante <uses-
permission>.
• <uses-sdk>: 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.
• <application>: Indica mediante sus propiedades ciertos metadatos de la aplicación
como el título e icono. Es el nodo padre de <activity>, <services>,
<provider> y <receiver> ( y estos a su vez contienen definiciones de <intent-
filters> 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.

• <activity>: 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 <application>.
<activity android:name = ".Actividad1” >
• <uses-library>: 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.
<uses-library android:name="com.google.android.maps" >

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=0x7f020000;
public static final int icon=0x7f020001; }
public static final class id {
public static final int AnalogClock01=0x7f050004;
public static final int Button01=0x7f050002;
public static final int LinearLayout01=0x7f050000;
public static final int LinearLayout02=0x7f050003;
public static final int TextView01=0x7f050001; }
public static final class layout {
public static final int main=0x7f030000; }
// […]
}
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);

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);
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() {
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(Actividad.this, 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);
Hay que resaltar además que Button hereda de TextView, lo que le permite usar
los métodos de esta.
• 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 <include>, 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), boolean
isSatellite(), setStreetView(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 MapActivity por proceso, en caso contrario se pueden
obtener resultados inesperados.

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 punto dado como parámetro.


La clase GeoPoint representa un punto geográfico 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 );
Paint dibujoExter = new Paint();
dibujoExter.setColor( Color.RED );

GeoPoint geo = mapView.getMapCenter();

Point punto = new Point();


mapView.getProjection().toPixels(geo, punto);

canvas.drawCircle(punto.x, punto.y, 25, dibujoExter);


canvas.drawCircle(punto.x, 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);

double lat = 40.960659;


double lon = -5.669643;

punto = new GeoPoint( (int) (lat*1E6), (int) (lon*1E6) );

vistamapa = ( MapView )findViewById(R.id.mapview);


vistamapa.setBuiltInZoomControls(true);
controller = vistamapa.getController();
controller.setCenter(punto);
controller.setZoom(17);
Canvas canvas = new Canvas();
Simbolo simb = new Simbolo();
simb.draw(canvas, vistamapa, true);

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: 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").
• Geocoder: clase que permite traducir entre direcciones físicas y coordenadas en
latitud y longitud, y viceversa.
• LocationListener: 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 <fix|nmea>, 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);
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. Por ejemplo
getLine1Number() retorna el número de teléfono propio,
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/add-
ons/google-apis/reference/com/google/android/maps/package-summary.html

* Último acceso a todas las direcciones webs: 15 de Abril de 2010.

-33-