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

MANUAL BSICO DE ANDROID

ndice de contenido
1. INSTALACIN DE ANDROID EN ECLIPSE...............................................................................3
2. Hola Mundo....................................................................................................................................10
3.Programacin Android: Interfaz grfica Conceptos bsicos........................................................22
Context......................................................................................................................................23
4.Programacin Android: Interfaz grfica Layouts.........................................................................24
FrameLayout.............................................................................................................................24
LinearLayout.............................................................................................................................25
RelativeLayout..........................................................................................................................26
6. BOTONES Y EVENTOS...............................................................................................................28
Programacin Android: Interfaz grfica Componentes grficos y Eventos....................................31
Button........................................................................................................................................31
EditText.....................................................................................................................................32
ImageView................................................................................................................................33
CheckBox..................................................................................................................................33
7. Android: Escuchador y Manejador de eventos...............................................................................35
8. Android: Checkbox y RadioButtons con su evento de click..........................................................36
9. Programacin Android: Interfaz grfica Adapters ......................................................................41
10. Spinners en Android, de trer formas distintas..............................................................................49
Poblando Spinners.........................................................................................................................49
Desde arrays.xml.......................................................................................................................49
Desde SQLite............................................................................................................................50
Desde un objeto.........................................................................................................................51
Obteniendo el dato seleccionado...................................................................................................52
11. Programacin Android: Interfaz grfica Mens........................................................................53
Options Menu............................................................................................................................53
Context Menu............................................................................................................................54
Mas ejemplo de Mens..................................................................................................................57
Submen........................................................................................................................................59
12. Dilogos y notificaciones.............................................................................................................63
Notificaciones Toast..................................................................................................................63
Notificaciones en la barra de estado..........................................................................................65
Dilogos....................................................................................................................................66
13. Android: Una aplicacin con varios idiomas................................................................................69
14. Android: Disear aplicaciones para todas las dimensiones de pantalla........................................70
15. Estilos y Temas.............................................................................................................................71
Definiendo estilos.....................................................................................................................71
Herencia....................................................................................................................................72
Aplicar estilos y temas a la interfaz grfica..............................................................................72
16. Usando recursos............................................................................................................................75
Referenciando atributos de estilo..............................................................................................75
17. Recursos Strings........................................................................................................................77
Recursos string...............................................................................................................................77
19. Recursos Layout........................................................................................................................79
1

MANUAL BSICO DE ANDROID


20. Enviar datos entre actividades (Activity).....................................................................................81
21. Obtener datos de una subactividad...............................................................................................88
21. Manejando la rotacin de pantalla en Android.............................................................................93
EVITAR QUE NUESTRA ACTIVIDAD COMIENCE DE NUEVO AL ROTAR LA
PANTALLA.................................................................................................................................100
22. Tareas en segundo plano (I): Threads.........................................................................................104
23. Tareas en segundo plano (II): AsyncTask...................................................................................106
24. Android: Thread (Hilo) y Handler, proceso en segundo plano ..................................................110
25. Obtener informacin de un archivo............................................................................................113
26. Lectura de un archivo.................................................................................................................115
27. Listar contenido de un directorio................................................................................................117
28. Obtener informacin de la SDCard............................................................................................120
29. Base de datos (I): Creacin de una base de datos SQLite..........................................................122
30. Base de datos(II): Insertar, modificar y borrar datos de una base de datos SQLite...................125
31. Base de datos (III):Obtener datos de base de datos SQLite.......................................................127
32. Base de datos(IV): Trabajar con fecha/hora en base de datos SQLite........................................129
33.Botones grficos y algo de redes.................................................................................................132
Escner de redes WIFI)....................................................................................................................141
Escner de redes WIFI.................................................................................................................149
Crackeando redes Wifi.................................................................................................................157

MANUAL BSICO DE ANDROID

1. INSTALACIN DE ANDROID EN
ECLIPSE.
Para poder empezar a desarrollar aplicaciones en Android, primero debemos asegurarnos que
tenemos correctamente instalado y configurado nuestro JDK, podemos instalar la versin 5 6
desde http://www.oracle.com/technetwork/java /javase/downloads/index.html. La descarga ronda en
torno a unos 75MB.
Finalmente, la ltima herramienta que os voy a hacer descargar e instalar directamente es, cmo no,
el SDK de Android desde http://developer.android.com/sdk/index.html. Una vez dentro de la
pgina, seleccionad el archivo perteneciente a la plataforma Windows y a esperar unos 20MB de
descarga. Cuando lo instalis apuntad la ruta, luego se la tendremos que indicar a Eclipse.
Con todas las herramientas descargadas e instaladas vamos ahora a configurar nuestro Eclipse para
poder desarrollar aplicaciones en Android. Ejecutamos Eclipse y nos vamos a Help->Install New
Software. Una vez ah hacemos click en Add y en el dilogo que aparece ponemos name:
Android Plugin location: https://dl-ssl.google.com/android/eclipse/ (probamos con http si
no nos funciona con https) y hacemos click en OK. En la ventana Available Software ahora
debera aparecer Developer Tools, seleccionamos su checkbox asociado y deberan seleccionarse
los items Android DDMS y Android Development Tools, hacemos click en Next dos veces y
click en Finish, ya tenemos el plugin ADT instalado en nuestro Eclipse, ya falta menos!.

MANUAL BSICO DE ANDROID

Configuracin Eclipse
Tenemos que descargar el ltimo target disponible de Android para poder acceder a toda la
funcionalidad reciente y a todos los mdulos que nos proporciona Google (por ejemplo el API de
Google Maps). Para ello nos vamos a Inicio -> Todos los Programas -> Android SDK Tools ->
SKD Manager o podemos ir directamente desde Eclipse Window -> Android SDK and AVD
Manager, una vez ah vamos al apartado Available Packages seleccionamos todos los checkbox
tanto de Android Repository como de Third party Add-ons y le damos a Install Selected, esta
instalacin es la ms duradera pero en cuanto tengamos los target estaremos a punto de empezar.
Podramos haber instalado slo el target ms reciente pero es conveniente, ya que vamos a ser
desarrolladores, tener conocimiento tambin de todos los anteriores.

MANUAL BSICO DE ANDROID

Configuracin Eclipse Android


Una vez descargados todos los target hay que decirle a nuestro Eclipse la ruta donde hemos
instalado el SDK de Android, para ello vamos a Window -> Preferences seleccionamos
Android en el panel de la izquierda, hacemos click en Browser e indicamos la ruta del SDK que
instalamos con anterioridad (aquella que os dije que apuntarais), posteriormente hacemos click en
Apply y deberamos ver en la lista todos los target que disponemos para poder desarrollar
aplicaciones Android.

MANUAL BSICO DE ANDROID

Mdulos
Ya tenemos casi todo configurado, slo nos falta crearnos un emulador y empezamos con el primer
proyecto. Para ello vamos a Window -> Android SDK and AVD Manager -> Virtual Devices.
Hacemos click en New ponemos un nombre a nuestro emulador, por ejemplo FluDevice y le
cargamos un target, para empezar vamos a ponerle el target Android 2.2 API Level 8, las dems
opciones las dejamos por defecto.

MANUAL BSICO DE ANDROID

Creando nuevo dispositivo


Con esto finaliza el proceso de instalacin y configuracin de las herramientas para el desarrollo de
aplicaciones de Android en el IDE Eclipse. A continuacin, vamos a crear nuestro primer proyecto
en Android y a ejecutar un Hello World predefinido para comprobar que todo est en orden. Para
ello, en nuestro Eclipse vamos a la pestaa File -> New -> Android Project y rellenamos las
propiedades de nuestro nuevo proyecto Android. En Project Name ponemos HelloWorld,
seleccionamos el target Android 2.2 API level 8 (importante no seleccionar uno mayor al que
hemos seleccionado para crear nuestro emulador FluDevice). Como Application name tambin
ponemos Hello World y como paquete indicamos com.fluproject.HelloWorld. En Create Activity
ponemos Main ya que esta ser nuestra Activity principal y posteriormente pulsamos Finish. Ya
tenemos nuestro proyecto creado, ahora slo falta ejecutarlo.

MANUAL BSICO DE ANDROID

Creando nuevo proyecto


En la parte izquierda de nuestro entorno Eclipse se habr creado un proyecto nuevo llamado
HelloWorld. Hacemos click con el botn derecho del ratn sobre el proyecto y seleccionamos Run
As -> Android Application. Una vez pulsado observamos como se carga nuestro emulador y, tras
esperar unos cuantos segundos, vemos el resultado del HelloWorld.

Cdigo de prueba

MANUAL BSICO DE ANDROID

MANUAL BSICO DE ANDROID

2. Hola Mundo
Una vez que tenemos las herramientas necesarias para comenzar a programar en Android,
crearemos nuestro primer proyecto, para ello nos vamos a File - New - Project...

Aqu seleccionamos Android - Android Project, pulsamos sobre Next:

En esta ventana, en Project Name, ponemos el nombre de nuestro proyecto, en este caso
HolaMundo, quedando marcada la opcin Create new project in workspace. Pulsamos sobre Next:

10

MANUAL BSICO DE ANDROID

Aqu debemos seleccionar la versin de Android sobre la que queremos trabajar, en este caso voy a
seleccionar la versin 2.1, sin embargo, deberamos seleccionar la versin que necesitemos. Si elijo
la versin 2.1, el programa seguro que funcionar desde esta versin en adelante. Volvemos a pulsar
sobre Next. Ahora tenemos que elegir un nombre de paquete, en nuestro caso ejercicios.ejemplo, ya
que el programa nos obliga a que el nombre del paquete tenga dos identificadores. Tambin si
queremos que cree una Activity, que se llamara HolaMundoActivity, dejamos marcada esta opcin
para que la cree.

Pulsamos en Finish y ya tenemos creado nuestro proyecto.

11

MANUAL BSICO DE ANDROID

A continuacin vamos a ver algunas de las carpetas y archivos importantes en un proyecto, como
vemos aparecen en la parte izquierda de Eclipse:
src/ejercicios.ejemplo/HolaMundoActivity.java. Pulsamos doble clic sobre el nombre de
este archivo. Como vemos aqu ir todo nuestro cdigo Java, la lgica de nuestra aplicacin.
Tenemos la clase HolaMundoActivity que extiende la clase Activity y se sobreescribe el
mtodo onCreate(). Cada pantalla de la aplicacin se define mediante un objeto Activity.
Podemos tener las Activities que necesitemos.
01.import android.app.Activity;
02.
03.import android.os.Bundle;
04.
05.public class HolaMundoActivity extends Activity {
06.
07./** Called when the activity is first created. */
08.
09.@Override
10.
11.public void onCreate(Bundle savedInstanceState) {
12.
13.super.onCreate(savedInstanceState);
14.
15.setContentView(R.layout.main);
16.
17.}
18.
19.}
res/layout/main.xml. Aqu se definen los componentes de la interfaz grfica de la aplicacin
y se especifican todas sus propiedades. Se definen los layouts de la aplicacin que son
12

MANUAL BSICO DE ANDROID


elementos no visibles que determinan cmo se van a distribuir los diferentes componentes
de la interfaz grfica, que veremos ms adelante. Adems de main.xml en la carpeta res se
pueden guardar las interfaces grficas que sean necesarias para nuestra aplicacin.
1.<!--?xml version="1.0" encoding="utf-8"?-->
2.<linearlayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
3.
4.<textview android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello">
5.
6.</textview></linearlayout>
res/values/strings.xml. Aqu se definen una serie de cadenas de caracteres que podrn ser
llamadas desde nuestra aplicacin Java, as evitamos definir variables. En nuestro ejemplo
tenemos dos cadenas de caracteres definidas, hello y app_name, que podrn ser
referenciadas desde HolaMundoActivity, main, AndroidManifest. Se pueden definir dentro
de la carpeta res/values/ los archivos con recursos strings necesarios.
1.<!--?xml version="1.0" encoding="utf-8"?-->
2.<resources>
3.<string name="hello">Hello World, HolaMundoActivity!</string>
4.<string name="app_name">HolaMundo</string>
5.</resources>
AndroidManifest.xml. Aqu definimos la versin de nuestra aplicacin, el paquete al que
pertenece, la versin mnima de SDK que soporta, un icono (ic_launcher) y el nombre de la
aplicacin (app_name), los activities que tenemos y los permisos que debe tomar la
aplicacin. Si nos fijamos en el cdigo, aparece una Activity, HolaMundoActivity, que es la
nica que tenemos.
01.<!--?xml version="1.0" encoding="utf-8"?-->
02.<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="ejercicios.ejemplo" android:versioncode="1"
android:versionname="1.0">
03.<uses-sdk android:minsdkversion="7">
04.<application android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
05.<activity android:name=".HolaMundoActivity"
android:label="@string/app_name">
06.<intent-filter>
07.<action android:name="android.intent.action.MAIN">
08.<category
android:name="android.intent.category.LAUNCHER">
09.</category></action></intent-filter>
13

MANUAL BSICO DE ANDROID


10.</activity>
11.</application>
12.</uses-sdk></manifest>
gen/ejercicios.ejemplo/R.java. Este archivo es un ndice de todos los recursos del proyecto y
un atajo para referirse a estos recursos. Permite localizar de forma rpida e interactiva la
referencia especfica que estamos buscando. Enlaza lo que hagamos en XML con la
programacin en Java. No se debe modificar ya que es Eclipse quien se encarga de
modificarlo.
01./* AUTO-GENERATED FILE. DO NOT MODIFY.
02.*
03.* This class was automatically generated by the
04.* aapt tool from the resource data it found. It
05.* should not be modified by hand.
06.*/
07.
08.package ejercicios.ejemplo;
09.
10.public final class R {
11.public static final class attr {
12.}
13.public static final class drawable {
14.public static final int ic_launcher=0x7f020000;
15.}
16.public static final class layout {
17.public static final int main=0x7f030000;
18.}
19.public static final class string {
20.public static final int app_name=0x7f040001;
21.public static final int hello=0x7f040000;
22.}
23.}
Carpetas res/drawable. Aqu tenemos los iconos e imgenes que vamos a utilizar en nuestra
aplicacin. Debemos colocar las imgenes segn el tipo de pantalla del dispositivo. En
drawable-hdpi se colocarn las imgenes para dispositivos con alta resolucin, en drawablemdpi imgenes con resolucin media y en drawable-ldpi las dirigidas a dispositivos con
pantallas pequeas.
A continuacin vamos a arrancar el emulador de Android para probar nuestro Hola Mundo. El AVD
(Android Virtual Device) es una herramienta que nos permite emular en un ordenador el entorno
mvil en el cual se ejecutar nuestra aplicacin Android. En el momento de instalar el SDK no
tendremos ningn emulador, as que tendremos que crearlo. Nos vamos a Window - AVD Manager
o bien pulsamos sobre el siguiente botn:

14

MANUAL BSICO DE ANDROID


Tenemos la siguiente ventana, en la cual tenemos que pulsar sobre New para crear el nuevo AVD:

Al pulsar sobre New tenemos lo siguiente:

15

MANUAL BSICO DE ANDROID

Name. Aqu pondremos nombre a nuestro dispositivo virtual. Normalmente se le asigna un


nombre relacionado con la versin de Android para la que est configurado.
Target. Esta es la versin de Android que correr en el dispositivo virtual y deber ser como
mnimo la que se utilice para crear nuestros proyectos. Se pueden crear tantos emuladores
como versiones de Android tengamos instaladas en Eclipse.
Estos campos son obligatorios, opcionalmente podemos rellenar:
SD Card. Donde podremos el tamao de una tarjeta SD o bien cargar el archivo de una SD
existente. Normalmente pondremos el tamao de la tarjeta SD.
Skin. Aqu configuramos las caractersticas de la pantalla de nuestro dispositivo. Si el
16

MANUAL BSICO DE ANDROID


monitor del ordenador es grande dejaremos la opcin que viene por defecto, si no
seleccionaremos la opcin HVGA para adaptar el emulador al tamao de la pantalla que
tenemos.
El apartado de Hardware nos permite agregar caractersticas de hardware especficas del
dispositivo como acelermetro, cmara, teclado fsico, etc.
Personalmente voy a crear un emulador con las siguientes caractersticas:

Pulsamos sobre Create AVD y en la ventana del AVD Manager seleccionamos el emulador y
pulsamos sobre el botn Start..., en la ventana que sale pulsamos sobre el botn Launch y ahora ya
podemos probar nuestro programa en el emulador.
17

MANUAL BSICO DE ANDROID

Para probar una aplicacin la seleccionamos y bien pulsamos con el botn derecho del ratn sobre
el nombre del proyecto y seleccionamos la opcin Run as - Android Application o bien nos vamos
al men Run - Android Application. Y voil, aqu tenemos ejecutndose a nuestro "Hola mundo".

18

MANUAL BSICO DE ANDROID

Cmo probar nuestro programa en el mvil


Primero tendremos que modificar el AndroidManifest.xml y aadir lo siguiente:
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:debuggable="true">
Debemos asegurarnos de desactivar esta opcin cuando publicamos la aplicacin en Google Play.
Ahora nos vamos a nuestro dispositivo y entramos en Ajustes - Aplicaciones - Desarrollo, (si
tenemos Android 4.0 nos tenemos que ir a Ajustes - Opciones de desarrollador) y activamos la
opcin Depuracin de USB.
Configura el sistema para detectar el dispositivo:
En Windows necesitamos instalar un controlador USB para adb. En esta web puedes ver el
modo de instalacin segn la versin de Windows que tengas y los controladores para los
diferentes modelos de smartphones.
19

MANUAL BSICO DE ANDROID


Si estamos desarrollando para Mac OS X, funciona sin hacer nada.
Si utilizamos Ubuntu Linux, necesitamos aadir un archivo de reglas udev que contenga la
configuracin USB para cada tipo de dispositivo que queramos utilizar para probar las
aplicaciones. En este archivo, cada fabricante de dispositivos se identifica con un
identificador nico ID, puedes encontrar una lista de identificadores para los diferentes
proveedores aqu . Para establecer la deteccin de dispositivo haremos lo siguiente:
1. Inicia la sesin como root y crea este archivo /etc/udev/rules.d/51-android.rules. Utiliza este
formato para aadir la informacin de cada proveedor:
SUBSYSTEM=="usb", ATTR{idVendor}=="04e8", MODE="0666", GROUP="plugdev"
Este ejemplo sera para un mvil modelo Samsung, lo vemos en el campo ATTR, la asignacin de
MODE especifica los permisos de lectura/escritura y GROUP define a qu grupo pertenece el nodo
del dispositivo.
(La sintaxis de las reglas puede variar dependiendo del entorno, para saber ms sobre la escritura
de reglas para archivos udev visita la
direccin http://www.reactivated.net/writing_udev_rules.html).
2. Ahora en un terminal ejecutamos la orden: chmod a+r /etc/udev/rules.d/51-android.rules
Cuando conectemos el dispositivo al ordenador, podemos verificar que el dispositivo est conectado
ejecutando adb devices desde el directorio SDK platform-tools. Si est conectado, vers el nombre
del dispositivo en la lista de dispositivos.
Si utilizamos Eclipse, ejecutaremos la aplicacin como siempre. Se nos abrir una ventana en la
que podremos seleccionar entre el emulador y los dispositivos conectados para probar la aplicacin.
Seleccionamos nuestro dispositivo:

Y as instalaremos y ejecutaremos la aplicacin en nuestro mvil.


20

MANUAL BSICO DE ANDROID

Si utilizamos Android Debug Bridge (adb), podemos emitir comandos con la opcin -d para
apuntar al dispositivo conectado.

21

MANUAL BSICO DE ANDROID

3.Programacin Android: Interfaz grfica


Conceptos bsicos
Todos los componenetes de la interfaz de usuario de Android descienden de la clase View. Dichos
objetos estn organizados en forma de rbol y pueden contener nuevos objetos View, permitiendo
crear interfaces muy completas.

Los objetos View se pueden definir de dos maneras:


- Mediante un fichero XML colocado dentro del directorio res/layout, que es el que usaremos
normalmente.
- En tiempo de ejecucin, muy til para crear nuestros propios componentes View
Para dibujar la interfaz, el sistema necesita que le pasemos el objeto View raiz, para ir descendiendo
por cada uno de sus nodos y presentar al usuario toda la interfaz. El mtodo encargado de esto es
Activity.setContentView().
Android se encarga de dibujar los elementos llamando primero al mtodo draw() de cada vista,
podramos decir que cada vista se dibuja a s misma. El proceso de dibujo se hace en dos veces.
Inicialmente se llama al mtodo measure(int, int), que define el tamao de cada objeto View,
posteriormente se llama al mtodo layout(int, int, int, int), que posiciona el objeto dentro de la
vista.
Para que Android sepa dibujar correctamente los objetos, tenemos que pasarle algunos datos, como
son la altura y anchura. Para eso nos servimos de la clase LayoutParams, que pude tomar los
siguientes valores:
Un nmero
La constante FILL_PARENT, que indica que la vista debe intentar ser tan grande como su
22

MANUAL BSICO DE ANDROID


padre, quitando el padding.
La constante WRAP_CONTENT, para que intente ser lo suficientemente grande para
mostrar su contenido, mas el padding.
Tambin nos podemos servir de la clase View.MeasureSpec, para especificar el tamao y cmo
deben ser posicionadas.
AT_MOST, el padre fija un tamao mnimo para el hijo. El hijo(y los descendientes de ste)
tienen que ocupar por lo menos ese tamao.
EXACTLY, el padre impone un tamao exacto al hijo.
UNSPECIFIED, el padre fija el tamao deseado del hijo.
Un atributo imprescindible es el id(de tipo entero). Que sirve para identificar nicamente a un
objeto View. Cuando lo declaramos mediante xml podemos referenciarlo a travs de la clase de
recursos R, usando una @.
android:id=@+id/nombreID: Crea un nuevo atributo en la clase R llamado nombreID
android:id=@id/nombreID:< Hace referencia a un id ya existente asociado a la etiqueta
'nombreID'/li>
android:id=@android:id/list: Referencia a un a etiqueta definida en la clase R del sistema
llamada list.
Los objetos View pueden tener otros muchos atributos, como padding, colores, imgenes, fondos,
mrgentes etc

Context
Si ya has programado algo en Android, o has visto alguno de los ejemplos, probablemente hayas
visto que muchos mtodos referidos a la vista piden como parmetro un objeto de tipo context.
Context es una interfaz para la informacin global de la aplicacin. A travs de l podemos acceder
a recursos, clases y operaciones, como lanzar actividades, manejar intents etc.
Podemos acceder al contexto de diferentes formas en funcin de donde nos encontremos:
Con el mtodo getContext().
Las actividades implementan esta interfaz, por lo que haciendo referencia a ellas mismas,
con (this) o NombreActivity.this, estaremos referenciando el contexto.
Usando otros mtodos como getApplicationContext() o getApplication()

23

MANUAL BSICO DE ANDROID

4.Programacin Android: Interfaz grfica


Layouts
Los layout nos permiten posicionar cada objeto grfico en el lugar que queramos de la pantalla, es
decir, nos permite disear el aspecto grfico que va a tener nuestra pantalla. Los layouts son de tipo
ViewGroup, una subclase de View
Existen varios tipos de Layouts para Android, vamos a ver los ms comunes:

FrameLayout
Este tipo de Layout es el ms bsico, coloca a sus objetos hijos en la parte superior izquierda de la
pantalla.
< ?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<textview android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"/>
<textview android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"/>
</framelayout>

Como se puede apreciar en en resultado, si hay ms de un hijo, los objetos se amontonan unos
encima de otros.

24

MANUAL BSICO DE ANDROID

LinearLayout
Este tipo de layout coloca sus hijos unos detras de otros, tambin comenzando por la esquina
superior izquierda de la pantalla. Podemos colocarlos alineados horizontalmente o verticalmente
mediante su propiedad android:orientation=horizontal | vertical
< ?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<textview android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:background="#0ff"/>
<textview android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"
android:background="#ff0"/>
</linearlayout>

En este caso, he pueso un fondo de color a cada texto (con la propiedad android:background) para
diferenciarlo bien, y he usado la horientacin horizontal, de haber usado la orientacin vertical, los
textos apareceran uno debajo del otro:
25

MANUAL BSICO DE ANDROID

RelativeLayout
Este Layout permite que coloquemos los elementos en un lugar con respecto a la posicin de otro,
es decir, colocar un botn a la derecha de un texto, o centrarlo en la pantalla, o por ejemplo, colocar
un texto encima de tal elemento y a la derecha de este otro.
Para conseguir esto, RelativeLayout proporciona propiedades como android:layout_toRightOf o
android:layout_alignLeft, que toman como valores los identificadores de los objetos, o valores
booleanos.
< ?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<textview android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:background="#0ff"
android:layout_centerInParent="true"
android:id="@+id/text1"/>
<textview android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"

26

MANUAL BSICO DE ANDROID


android:background="#ff0"
android:layout_below="@id/text1"/>
</relativelayout>

Como vemos, hemos centrado el texto1 en la pantalla con android:layout_centerInParent=true


y hemos puesto debajo del texto1 al texto2 con android:layout_below=@id/text1

Para saber ms acerca de todos los tipos de layouts que hay podis visitar
http://developer.android.com/guide/topics/ui/layout-objects.html

27

MANUAL BSICO DE ANDROID

6. BOTONES Y EVENTOS
Un botn en tu layout es algo simple, os pongo un ejemplo:
1 <Button
android:id="@+id/btnBoton"
2
android:layout_width="wrap_content"
3
android:layout_height="wrap_content"
4
5
android:text="Botn"
6
/>
Como veis es bastante sencillo pero si lo pulsas no hace nada, para hacer que funcione al pulsarlo,
tenemos que trabajar con manejadores de eventos. Para comprobar que un botn se ha pulsado,
existen 5 formas de hacerlo y cada una con sus ventajas e inconvenientes, yo voy a explicar las 3
ms utilizadas:
1 Forma: La clase interna annima.
Declarar el OnClickListener dentro del mtodo setOnClickListener, es algo comn. Este mtodo es
til cuando cada oyente no puede compartir la funcionalidad con otros oyentes. Algunos
desarrolladores novatos encuentran este tipo de cdigo difcil de entender. Tenemos que repetir el
cdigo para cada botn.
Cdigo:
findViewById(R.id.btnBoton).setOnClickListener(new
1
OnClickListener(){
2
public void onClick(View arg0) {
3
Button boton = (Button)arg0;
4
boton.setText("Has pulsado el botn");
5
}
6
});
2 Forma: Implementacin en la actividad
-implementar la interfaz OnClickListener en la actividad con la que vamos a interactuar con el
botn.
- Dentro del mtodo onCreate, relacionar el botn del layout con la actividad a travs del id para
poder trabajar con l desde el cdigo.
- En el mtodo que implementa la interfaz OnclickListener llamado onClick() tenemos que
programar que se va a hacer cuando hagamos clic en el botn.
Aqu tenemos un ejemplo explicado del cdigo:

28

MANUAL BSICO DE ANDROID


//Implementamos la interfaz OnClickListener
public class MainActivity extends Activity implements
OnClickListener{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

1
2
3
4
5
6
//Relacionamos el boton del layout con botn java.
7
Button boton = (Button)findViewById(R.id.btnBoton);
8
//Lo ponemos a escuchar para cuando sea pulsado
9
boton.setOnClickListener(this);
10
11
}
12
13
//Aqu se ir administrando cuando un botn es pulsado
14
@Override
15
16
public void onClick(View v) {
17
/*Comprobamos a que id pertenece el id del botn pulsado,
18 en este caso como solo tenemos 1
19
siempre va a ser el mismo pero se puede dar el caso de
20 que haya ms de un botn, entonces aqu se controlara que botn
21 se ha pulsado.
22
*/
23
switch(v.getId()){
24
case R.id.btnBoton://Si el id del botn pulsado se
25 corresponde con el id que tenemos aqu entrara dentro del case.
26
//Aqu va el cdigo que se va a ejecutar cuando
27 se pulse el botn.
28
}
}
}
3 forma: Se aade un atributo en el diseo del botn llamado onClick disponible a partir de la
versin 1.6 (para m la forma ms fcil).
<Button
1
android:id="@+id/btnBoton"
2
android:layout_width="wrap_content"
3
android:layout_height="wrap_content"
4
android:text="Botn"
5
android:onClick="nombre del mtodo sin parntesis al a que
6
ira al pulsar el botn"
7
/>
Atencin: tenemos que importar todos los paquetes que se nos solicite, de lo contrario no
29

MANUAL BSICO DE ANDROID


funcionar.

30

MANUAL BSICO DE ANDROID

Programacin Android: Interfaz grfica


Componentes grficos y Eventos
Ya hemos visto que todos los componentes visuales descienden del objeto View, que proporciona
una interfaz para que podemos interactuar con ellos.
Para que nuestras aplicaciones sean funcionales, necesitamos responder a los eventos que el usuario
dispare al interactuar con nuestro programa, en Android, esto se consigue mediante los Listeners,
que sern llamados cada vez que se produzca un evento.
Por ejemplo, un listener muy comn ser setOnClickListener(), que responder cada vez que se
pulse sobre la vista a la que se lo aplicamos, como un botn, o una imgen. Hay muchos tipos de
listener, setOnKeyListener() (Para eventos de teclado), setOnItemClicklistener() (Para eventos al
seleccionar un elemento de una lista) etc etc.
En los ejemplos mostrados hasta ahora, solo hemos visto objetos de tipo TexView, vamos a ver
unos cuantos ms (En cada ejemplo pondr la definicin XML del objeto, y su manipulacin
mediante cdigo):

Button
Botones simples, para realizar acciones al pulsar sobre ellos.
<button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Plsame"
android:layout_centerInParent="true"
android:id="@+id/button1"/>

//Recoger el botn en una variable para usarlo


final Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Toast.makeText(
button1.getContext()
, "Me has pulsado " + ++contador + " veces."
, Toast.LENGTH_SHORT)
.show();
}

});

En este caso, hemos declarado una variable como miembro de la clase, (public int contador = 0;),
para que cada vez que pulsemos el botn nos salga un mensaje con el nmero de veces que lo
hemos pulsado:

31

MANUAL BSICO DE ANDROID

EditText
Son campos de texto en los que el usuario puede escribir.
<edittext android:layout_width="200dip"
android:layout_height="wrap_content"
android:layout_above="@id/button1"
android:id="@+id/editText1"
android:layout_centerInParent="true"/>
final EditText editText1 = (EditText) findViewById(R.id.editText1);
editText1.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
if (arg1 == KeyEvent.KEYCODE_ENTER){
Toast.makeText(
editText1.getContext()
, "Escribiste: " + editText1.getText()
, Toast.LENGTH_SHORT)
.show();
return true;
}
return false;
}
});

Lo que hemos hecho con este EditText, es fijarle un onKeyListener, que comprobar (con el if), que
hemos pulsado la tecla enter, y si es cierto, mostrar el texto escrito:

32

MANUAL BSICO DE ANDROID

ImageView
Nos permite mostrar imgenes en la pantalla.
<imageview android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"/>
final ImageView imageView1 = (ImageView) findViewById(R.id.imageView);
imageView1.setImageResource(R.drawable.icon);

El icono es el que viene por defecto al crear un proyecto. Este es el resultado:

CheckBox
Es un tipo de botn con dos estados, activo o inactivo, practicamente tiene el mismo
comportamiento de un botn, una de sus caractersticas es que podemos comprobar si el botn esta
activo o no:
<checkbox android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="CheckBox"

33

MANUAL BSICO DE ANDROID


android:layout_centerInParent="true"
android:layout_below="@id/button1"
android:id="@+id/checkBox1" />
final CheckBox checkbox1 = (CheckBox) findViewById(R.id.checkBox1);
checkbox1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton arg0, boolean checked) {
if (checked) Toast.makeText(checkbox1.getContext(), "Activo", Toast.LENGTH_LONG).sho
else Toast.makeText(checkbox1.getContext(), "Inactivo", Toast.LENGTH_SHORT).show();
}
});

En este caso, hemos usado como listener onCheckedChanged, que se ejecutar cada vez que el
estado del checkbox cambie.

Estos son los componentes grficos bsicos, tambin disponemos de RadioButton, ToggleButton
(Parecidos a los checkBox, pero con una luz que se ilumina al estar activos, y con la caracterstica
de que el texto cambia dependiendo de su estado, aunque esto se puede conseguir con el checkbox
facilmente.)
En general con echar un vistazo a los mtodos y listeners de cada componente, y con la
documentacin que ofrece javadoc en eclipse, lograremos entender como funciona cada uno, y
podremos usarlos fcilmente.

34

MANUAL BSICO DE ANDROID

7. Android: Escuchador y Manejador de


eventos
Escuchador de eventos:
Un escuchador de eventos o Event Listener es una interfaz de la clase view que contiene un mtodo
callback, que ha de ser registrado. Cada event listener tiene solo un mtodo callback, que ser
llamado por Android cuando se produzca la accin correspondiente. Tenemos los siguientes Event
Listener:
onClick()
Mtodo de la interfaz View.OnClickListener. Se llama cuando el usuario selecciona un elemento. Se
puede utilizar cualquier mtodo como la pantalla tctil, las teclas de navegacin o el trackball.
onLongClick()
Mtodo de la interfaz View.OnLongClickListener. Se llama cuando el usuario selecciona un
elemento durante ms de un segundo.
onFocusChange()
Mtodo de la interfaz View.OnFocusChangedListener. Se llama cuando el usuario navega dentro o
fuera de un elemento.
onKey()
Mtodo de la interfaz View.OnKeyListener. Se llama cuando se pulsa o se suelta una tecla del
dispositivo.
onTouch()
Mtodo de la interfaz View.OnTouchListener. Se llama cuando se pulsa o se suelta o se desplaza en
la pantalla tctil.
onCreateContextMenu()
Mtodo de la interfaz View.OnCreateContextMenuListener.Se llama cuando se crea un men de
contexto.

Manejador de eventos:
Si ests creando un descendiente de la clase View, podrs utilizar varios mtodos (callback)
directamente usados como manejadores de eventos por defecto (Event Handlers). En esta lista se
incluye:
onKeyDown(int KeyCode, KeyEvent e) Llamado cuando una tecla es pulsada.
onKeyUp(int keyCode, KeyEvent e) Llamado cuando una tecla deja de ser pulsada.
onTrackballEvent(MotionEvent me) Llamado cuando se mueve el trackball.
onTouchEvent(MotionEvent me) Llamado cuando se utiliza la pantalla tctil.
onFocusChanged(boolean obtengoFoco, int direccion, Rect prevRectanguloFoco) Llamado
cuando cambia el foco.
Es la forma ms sencilla, dado que no hace falta user una interfaz, ni registrar el mtodo callback.

35

MANUAL BSICO DE ANDROID

8. Android: Checkbox y RadioButtons con su


evento de click
Estos elementos probablemente le suenen de otras interfaces de usuario. Permiten que el usuario
pueda elegir entre varias opciones. Los CheckBox se utilizan normalmente cuando se quieren
ofrecer varias opciones con respuesta si/no o verdadero/falso. Los RadioButtons se utilizan slo
cuando se permiten varias opciones a la vez. Los Spinners son similares a los cuadros combinados
o listas desplegables utilizados en otras interfaces de usuario, pero Android los ha adaptado para
que sean ms tiles en un entorno de pantalla tctil.
Diseo:

Cdigo XML del diseo:


1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
4
android:layout_width="fill_parent"
5
android:layout_height="fill_parent"
6
>
7
8
<CheckBox
9
android:id="@+id/cb1"
10
android:layout_width="wrap_content"
11
android:layout_height="wrap_content"
12
android:checked="false"
13
/>
14
<TextView
36

MANUAL BSICO DE ANDROID


android:id="@+id/tvCheckBox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="CheckBox: Desactivado"

15
16
/>
17
<RadioGroup
18
android:id="@+id/rg1"
19
android:layout_width="fill_parent"
20
android:layout_height="wrap_content"
21
android:orientation="vertical">
22
<RadioButton android:id="@+id/rb1" android:text="Radio
23 1" />
24
<RadioButton android:id="@+id/rb2" android:text="Radio
25 2" />
26
<RadioButton android:id="@+id/rb3" android:text="Radio
27
3" />
28
</RadioGroup>
29
<TextView
30
android:id="@+id/tvRadioGroup1"
31
android:layout_width="fill_parent"
32
android:layout_height="wrap_content"
33
android:text="RadioGroup: No hay ningn radio
34
seleccionado"
35
/>
36
<Spinner
37
android:id="@+id/spn1"
38
android:layout_width="250dp"
39
android:layout_height="wrap_content"
40
android:layout_centerHorizontal="true"
41
android:layout_marginTop="2dp"
42
/>
43
<TextView
44
android:id="@+id/tvSpinner"
45
android:layout_width="fill_parent"
46
android:layout_height="wrap_content"
/>
</LinearLayout>
Ahora el cdigo java que corresponde a los click de usuario:
1 public class MainActivity extends Activity {
2
private CheckBox checkBox;
3
private TextView tvCheckBox, tvRadioGroup, tvSpinner;
4
private RadioButton rb1, rb2, rb3;
5
private Spinner spn1;
6
7
@Override
37

MANUAL BSICO DE ANDROID

38

MANUAL BSICO DE ANDROID


public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
checkBox = (CheckBox)findViewById(R.id.cb1);
tvCheckBox = (TextView)findViewById(R.id.tvCheckBox);
tvRadioGroup =
(TextView)findViewById(R.id.tvRadioGroup1);
tvSpinner = (TextView)findViewById(R.id.tvSpinner);
rb1 = (RadioButton)findViewById(R.id.rb1);
rb2 = (RadioButton)findViewById(R.id.rb2);
8
rb3 = (RadioButton)findViewById(R.id.rb3);
9
spn1 =(Spinner)findViewById(R.id.spn1);
10
11
//Reaccionar a eventos del CheckBox
12
checkBox.setOnClickListener(new
13
CheckBox.OnClickListener(){
14
@Override
15
public void onClick(View v) {
16
if(checkBox.isChecked())
17
tvCheckBox.setText("CheckBox: Activado");
18
else
19
tvCheckBox.setText("CheckBox:
20
Desactivado");
21
}
22
});
23
//Fin respecto al checkbox
24
25
//Raccionar a eventos del RadioGroup
26
rb1.setOnClickListener(new RadioButton.OnClickListener(){
27
@Override
28
public void onClick(View v) {
29
tvRadioGroup.setText("RadioGroup: Radio 1
30
seleccionado");
31
}
32
});
33
rb2.setOnClickListener(new RadioButton.OnClickListener(){
34
@Override
35
public void onClick(View v) {
36
tvRadioGroup.setText("RadioGroup: Radio 2
37
38 seleccionado");
}
39
});
40
rb3.setOnClickListener(new RadioButton.OnClickListener(){
41
@Override
42
public void onClick(View v) {
43
tvRadioGroup.setText("RadioGroup: Radio 3
44
seleccionado");
39

MANUAL BSICO DE ANDROID

40

MANUAL BSICO DE ANDROID

9. Programacin Android: Interfaz grfica


Adapters
Un objeto Adaptador acta como puente entre un AdapterView y los datos de una Vista (View). El
adaptador permite el acceso a los elementos de datos, ste tambin es responsable de crear una vista
para cada elemento en la coleccin de datos.
Se puede decir, que los adaptadores son colecciones de datos, que asignamos a una vista para que
sta los muestre, por ejemplo, podemos crear un ArrayAdapter a partir de un array de string ya
creado y con datos, y asignar este adaptador a un ListView, as, el ListView mostrar los datos del
array.
Mediante el uso de Adapters definimos una forma comn de acceder a colecciones de datos.
Para que quede ms claro este concepto, vamos a verlo mediante un ejemplo:
Primero creamos el layout, que va a contener un ListView con un Id ya definido por android, y un
TextView tambin con un id ya definido.
< ?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<listview android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@android:id/list" />
<textview android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@android:id/empty" />
</linearlayout>

Ahora, el cdigo donde creamos el adaptador, y lo asociamos al ListView:


package app.elbauldelprogramador.adapters;
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.widget.ArrayAdapter;
android.widget.ListAdapter;
android.widget.ListView;

public class AdaptadoresActivity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

41

MANUAL BSICO DE ANDROID


//Array que asociaremos al adaptador
String[] array = new String[] {
"Elemento 1"
,"Elemento 2"
,"Elemento 3"
,"Elemento 4"
,"Elemento 5"
,"Elemento 6"
};
//Creacin del adaptador, vamos a escoger el layout
//simple_list_item_1, que los mostr
ListAdapter adaptador = new ArrayAdapter<string>(
this, android.R.layout.simple_list_item_1, array);
//Asociamos el adaptador a la vista.
ListView lv = (ListView) findViewById(android.R.id.list);
lv.setAdapter(adaptador);

}
}
</string>

Como vemos, al crear el arrayAdapter, tenemos que pasar tres parmetros, el contexto, un layout
que se usar para dibujar cada item (en este caso simple_list_item_1, que ya viene definido por
android), ms adelante veremos como crear los nuestros propios, y como tercer parmetro la
coleccin de datos.
Aprovechando que en la anterior entrada hablamos de los eventos, voy a explicar como fijar un
evento onclick para cada elemento de la lista.
//Evento que se disparar al pulsar en un elemento de la lista
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView< ?> arg0, View arg1, int arg2,
long arg3) {
ListAdapter la = (ListAdapter) arg0.getAdapter();
Toast.makeText(
arg1.getContext()
,la.getItem(arg2).toString()
,Toast.LENGTH_LONG)
.show();
};

});

Para realizar este tipo de cosas, android proporciona una clase llamada ListActivity, este tipo de
clase necesita que exista una vista con el id ya definido por Android @android:id/list y otra con el
id @android:id/empty (Tal y como lo definimos en nuestro layout), as, si el adaptador que le
asiganamos a la lista no tiene datos, se mostrar al usuario la vista empty, el cdigo quedara de la
42

MANUAL BSICO DE ANDROID


siguiente manera:
package app.elbauldelprogramador.adapters;
import
import
import
import
import
import
import

android.app.ListActivity;
android.os.Bundle;
android.view.View;
android.widget.ArrayAdapter;
android.widget.ListAdapter;
android.widget.ListView;
android.widget.Toast;

public class AdaptadoresActivity extends ListActivity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//Array que asociaremos al adaptador


String[] array = new String[] {
"Elemento 1"
,"Elemento 2"
,"Elemento 3"
,"Elemento 4"
,"Elemento 5"
,"Elemento 6"
};
//Creacin del adaptador, vamos a escoger el layout
//simple_list_item_1, que los mostr
ListAdapter adaptador = new ArrayAdapter<string>(
this, android.R.layout.simple_list_item_1, array);
//Asociamos el adaptador a la vista.
ListView lv = (ListView) findViewById(android.R.id.list);
lv.setAdapter(adaptador);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Toast.makeText(
AdaptadoresActivity.this
,l.getItemAtPosition(position).toString()
,Toast.LENGTH_LONG)
.show();
}
}
</string>

El resultado de este cdigo es el siguiente, para una adaptador con datos:

43

MANUAL BSICO DE ANDROID

Y para un adaptador sin datos:

44

MANUAL BSICO DE ANDROID


Ahora vamos a ver como crear los nuestros propios.
Para explicar el funcionamiento nos vamos a basar en un ejemplo que listar las distintas versiones
de Ubuntu.
Lo primero que debemos hacer es crearnos una clase que almacenar los datos de cada una de las
versiones:
package app.elbauldelprogramador.adapters2;
public class VersionesUbuntu {
private String nombre;
private String version;
private int logotipo;
public VersionesUbuntu(String nombre, String version, int logotipo) {
this.nombre = nombre;
this.version = version;
this.logotipo = logotipo;
}
public void setNombre(String nombre) { this.nombre = nombre; }
public String getNombre() { return nombre; }
public void setVersion(String version) { this.version = version; }
public String getVersion() { return version; }
public void setLogotipo(int logotipo) { this.logotipo = logotipo; }
public int getLogotipo() { return logotipo; }
}

A continuacin vamos a crear el adaptador desde cero, siendo necesario extender de la clase
BaseAdapter.
package app.elbauldelprogramador.adapters2;
import java.util.ArrayList;
import
import
import
import
import
import
import

android.content.Context;
android.view.LayoutInflater;
android.view.View;
android.view.ViewGroup;
android.widget.BaseAdapter;
android.widget.ImageView;
android.widget.TextView;

public class VersionesUbuntuAdapter extends BaseAdapter{


private ArrayList<versionesubuntu> listadoVersiones;
private LayoutInflater lInflater;

45

MANUAL BSICO DE ANDROID

public VersionesUbuntuAdapter(Context context, ArrayList</versionesubuntu><versionesub


this.lInflater = LayoutInflater.from(context);
this.listadoVersiones = versiones;
}
@Override
public int getCount() { return listadoVersiones.size(); }
@Override
public Object getItem(int arg0) { return listadoVersiones.get(arg0); }
@Override
public long getItemId(int arg0) { return arg0; }
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
ContenedorView contenedor = null;
if (arg1 == null){
arg1 = lInflater.inflate(R.layout.lista_versiones_ubuntu, null);
contenedor = new ContenedorView();
contenedor.nombreVersion = (TextView) arg1.findViewById(R.id.nomVersion);
contenedor.numeroVersion = (TextView) arg1.findViewById(R.id.numVersion);
contenedor.logoVersion = (ImageView) arg1.findViewById(R.id.logo);
arg1.setTag(contenedor);
} else
contenedor = (ContenedorView) arg1.getTag();
VersionesUbuntu versiones = (VersionesUbuntu) getItem(arg0);
contenedor.nombreVersion.setText(versiones.getNombre());
contenedor.numeroVersion.setText(versiones.getVersion());
contenedor.logoVersion.setImageResource(versiones.getLogotipo());
}

return arg1;

class ContenedorView{
TextView nombreVersion;
TextView numeroVersion;
ImageView logoVersion;
}
}
</versionesubuntu>

Lo que hace esta clase es lo siguente, en su constructor, carga un objeto LayoutInflater, que infla los
objetos XML del layout para que podamos usarlos, convirtindolos en un objeto java.
Tambin tenemos tres mtodos sencillos (getCount, getItem, getItemId), que se encargan de
devolver el nmero de elementos de la coleccin, un elemento en concreto y el identificador de un
elemento.

46

MANUAL BSICO DE ANDROID


El mtodo getView() se invoca cada vez que hay que dibujar la lista.
En este caso, para la lista, hemos usado un layout personalizado, que es el siguiente:
< ?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<imageview android:id="@+id/logo"
android:src="@drawable/ocelot"
android:layout_alignParentLeft="true"
android:padding="5px"
android:layout_width="128px"
android:layout_height="128px"/>
<textview android:id="@+id/nomVersion"
android:layout_toRightOf="@id/logo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="15dip"
android:text="VersionNom" />
<textview android:id="@+id/numVersion"
android:layout_below="@id/nomVersion"
android:layout_toRightOf="@id/logo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="VersionNum" />
</relativelayout>

Por ltimo, tan solo queda usar el adaptador que hemos creado en los pasos anteriores en nuesta
Actividad principal, en este caso, una ListActivity:
package app.elbauldelprogramador.adapters2;
import java.util.ArrayList;
import android.app.ListActivity;
import android.os.Bundle;
public class Adaptadores2Activity extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<versionesubuntu> versiones =
new ArrayList</versionesubuntu><versionesubuntu>();
versiones.add(
new VersionesUbuntu("Lucid Lynx", "10.4 LTS", R.drawable.lucid));

47

MANUAL BSICO DE ANDROID


versiones.add(
new VersionesUbuntu("Maverick Meerkat", "10.10", R.drawable.u1010));
versiones.add(
new VersionesUbuntu("Natty Narwhal", "11.04", R.drawable.natty));
versiones.add(
new VersionesUbuntu("Oneiric Ocelot", "11.10", R.drawable.ocelot));
VersionesUbuntuAdapter adaptador = new VersionesUbuntuAdapter(
Adaptadores2Activity.this, versiones);
setListAdapter(adaptador);

}
}
</versionesubuntu>

Ya solo resta ejecutarlo y ver el resultado:

48

MANUAL BSICO DE ANDROID

10. Spinners en Android, de trer formas


distintas.
Los spinners en Android son los combobox de toda la vida. Spinner significa, segn el traductor de
google, hilandero. Porque google ha decidido llamarlo as y no combobox como se ha hecho toda
la vida? Y yo que s. Voy a suponer, de nuevo, que has programado para Android y que sabes cmo
se hacen las activitys y dems. Si no lo sabes busca por internet que manuales para empezar hay a
patadas.
Para rellenar los spinners es un poquillo complejo, al final todo se arregla picando cdigo, pero si
quieres hacer algo especifico (como me pas a m, de hecho hay cosas que an no he sabido
arreglar) pues tiene su miga.
Vamos a lo bsico. Para crear los objetos de los views en android se hace con findViewById.
Spinner prueba = (Spinner) findViewById(R.id.spinner1);

Ya tenemos el objeto de nuestro spinner. Ahora para poblarlo usamos un ArrayAdapter. Voy a
comentar tres formas de hacerlo, dos de ellas bastante populares por internet, poblarla desde un
archivo xml de arrays y desde la base de datos SQLite de Android, y una no tan popular pero
bastante til (y ms compleja). Despus de esto comentar como obtener los datos elegidos por el
usuario y porque me gusta ms el tercer mtodo para segn qu cosas.

Poblando Spinners
Desde arrays.xml
Bien amigos, para esto necesitamos un archivo arrays.xml con los textos que queramos rellenar en
el spinner y un par de lneas de cdigo. El archivo arrays.xml, situado en res/values, tiene el
siguiente formato.
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3
<string-array name="comidas">
4
<item>Salchichas</item>
5
<item>Huevos</item>
6
<item>Tomates</item>
7
</string-array>
8 </resources>

Bien, una vez que tengamos esto vamos a nuestro activity en java y utilizamos el siguiente cdigo
que explicar despus.

1 //Creamos el adaptador
2 ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.comid
3 //Aadimos el layout para el men

49

MANUAL BSICO DE ANDROID


4 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
5 //Le indicamos al spinner el adaptador a usar
6 prueba.setAdapter(adapter);

Analicemos lnea por lnea.


En la primera creamos un ArrayAdapter. Tenemos que indicar entre <> el tipo de objeto que ir
dentro del ArrayAdapter para evitar warnings y mejorar la legibilidad del cdigo, en este caso
CharSequence.
Este ArrayAdapter lo creamos pasndole como parmetros el contexto, que lo pasamos
directamente con this (en otros casos tendrs que hacer un getApplicationContext() ) la referencia a
las cadenas de texto que queremos y el layout genrico que proporciona Android para los Spinners.
Con la siguiente lnea indicamos el layout, de nuevo genrico de Android, para crear el men
desplegable.
Por ltimo, le aadimos al objeto del spinner el adaptador.
Una vez hecho esto ya tenemos nuestro precioso Spinner listo para entrar al campo a jugar. Vamos a
complicarlo un poco ms.

Desde SQLite
Android proporciona para nuestro deleite personas una base de datos SQLite. Aqu es posible que
tengamos los datos que necesitamos para poblar nuestro Spinner. Vamos a ello.
Me ahorro el explicar cmo crear una base de datos SQLite en android, si necesitis informacin
sobre cmo manejarla ya sabis, internet tiene la respuesta, solo dir que est abierta en el objeto
baseDatos, que la tabla donde estn los datos se llama comidas y la columna con lo que lo vamos a
poblar nombres, adems de una id.
Vamos con el cdigo.
1
2
3
4
5
6
7
8

//Creamos el cursor
Cursor c = baseDatos.rawQuery("select id AS _id, nombre from comidas", null);
//Creamos el adaptador
SimpleCursorAdapter adapter2 = new SimpleCursorAdapter(this,android.R.layout.simple_spi
//Aadimos el layout para el men
adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Le indicamos al spinner el adaptador a usar
prueba.setAdapter(adapter2);

Veamos, con el cursor hacemos un Query a la base de datos. Aqu hay un detalle importante, para
que esto funcione necesitamos que la columna del identificador se llame _id, pero, no s por qu, si
la llamas as en la base de datos y luego haces un select normal no funciona, cosas de google (un
bug?). Con AS funciona estupendamente. El segundo parmetro es para parmetros de seleccin,
como no queremos nada pues le ponemos null.
Vayamos con el adaptador, que tiene tela. Creamos el adaptador en base a un cursor. Los parmetros
son el contexto y el layout por defecto, como en el caso anterior, el cursor que hemos creado en la
lnea anterior, un array de String donde le indicamos que columna es la que tiene que tomar para
mostrarlo y de nuevo otro layout por defecto que, sinceramente, no s muy bien que hace.
50

MANUAL BSICO DE ANDROID


Las otras dos lneas son iguales que en el caso del arrays.xml. As de sencillo, ya tenemos un
spinner que nos mostrar los registros de nuestra base de datos. Ahora vamos a complicarlo un
poquito ms.

Desde un objeto
En ocasiones necesitamos poblar el Spinner con elementos que no estn en SQLite o en un array,
como puede ser elementos que nos vengan desde una conexin a una base de datos, creados
dinmicamente, o lo que sea.
Veamos los ingredientes; un spinner, que ya tenemos, una clase que genere los objetos que
queramos, con su toString sobrescrito, unas cuantas lneas similares a las anteriores y sazonar al
gusto.
Vamos con la clase de los objetos, que no tiene mucho misterio, pero bueno.
1 public class ObjetosClase{
2
int id;
3
String nombre;
4
//Constructor
5
public ObjetosClase(int id, String nombre) {
6
super();
7
this.id = id;
8
this.nombre = nombre;
9
}
10
@Override
11
public String toString() {
12
return nombre;
13
}
14
public int getId() {
15
return id;
16
}
17 }

Creo que est claro, no hay que explicarlo. El getId lo usaremos en el siguiente punto, paciencia.
Vale, ahora a crear el spinner.
1
2
3
4
5
6
7
8
9
10
11

//Creamos la lista
LinkedList<ObjetosClase> comidas = new LinkedList<ObjetosClase>();
//La poblamos con los ejemplos
comidas.add(new ObjetosClase(1, "Salchichas"));
comidas.add(new ObjetosClase(2, "Huevos"));
comidas.add(new ObjetosClase(3, "Tomate"));
//Creamos el adaptador
ArrayAdapter<ObjetosClase> spinner_adapter = new ArrayAdapter<ObjetosClase>(this, andr
//Aadimos el layout para el men y se lo damos al spinner
spinner_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
prueba.setAdapter(spinner_adapter);

Si controlas un poco de java ves que he creado un nuevo LinkedList y he metido ah los objetos con
las 3 comidas que estamos utilizando.
Despus he creado el ArrayAdapter como en el primer caso, solo que esta vez lo hemos creado
51

MANUAL BSICO DE ANDROID


pasndole el LinkedList. Fijaos que en este caso creamos el ArrayAdapter como cualquier objeto, y
que en el primer caso utilizbamos el mtodo esttico createFromResource.
El resto ya lo conocemos de sobra. Ya tenemos nuestro spinner con nuestros objetos personalizados.
Recordad que lo que toma como nombre es lo que est indicado en el toString.

Obteniendo el dato seleccionado


Ahora que ya tenemos nuestro spinner lleno de datos necesitamos conocer que dato elije el usuario.
Para ello tenemos que crear un oyente. En este caso vamos a construirlo para el tercer modo de
creacin, para obtener el id, para el resto sera igual pero sustituyendo en la lnea 4 el cdigo,
obteniendo el item y hacindole toString directamente.

1 public class MyOnItemSelectedListener implements OnItemSelectedListener {


2
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id)
3
if (parent.getId() == R.id.spinner1) {
4
alimentoId = ((ObjetosClase) parent.getItemAtPosition(pos)).get
5
}
6
//Podemos hacer varios ifs o un switchs por si tenemos varios spinners.
7
}
8
public void onNothingSelected(AdapterView<?> parent) {
9
// Do nothing.
10
}
11 }

Perfecto, ahora en cuanto un usuario pulse una opcin de nuestro spinner se guardar en la variable
alimentoId el id de nuestra comida escogida.
Como podis ver, utilizando nuestros propios objetos es mucho ms sencillo recuperar los datos.
Podemos crear objetos relativamente grandes, con varios datos, y obtenerlos y tratarlos como
queramos en el oyente. Estoy casi seguro que con el primer mtodo tambin se podra sacar el id (o
lo que queramos) de forma muy similar, pero no lo he conseguido.

52

MANUAL BSICO DE ANDROID

11. Programacin Android: Interfaz grfica


Mens
Los mens en las aplicaciones son algo que encontramos frecuentemente, de hecho, casi todos los
terminales Android tienen un botn especfico para desplegarlos.
Se dispone de distintos tipo de mens:
Options Menu: El men tpico, que se despliega al pulsar la tecla men, que se divide en
dos grupos:
Icon menu:Muestra un men con iconos, 6 elementos como mximo.
Expanded Menu: Se usa cuando hay ms de 6 elementos, mostrando un elemento con la
palabra Ms.
Context Menu: Mens contextuales desplegados al realizar una pulsacin larga en una
View.
Submens: Mens desplegados al pulsar sobre un elemento de otro men.

Options Menu
Lo ms simple y sencillo es definir los mens en XML, colocado en ./res/menu, para este ejemplo
he definido el siguiente menu, que contiene dos elementos, un About y un Quit:
< ?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/about"
android:icon="@drawable/about"
android:title="About App">
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/submenu"
android:title="Submen de &amp;quot;About App&amp;quot;"/>
</menu>
</item>
<item android:id="@+id/quit"
android:title="Quit App"
android:icon="@drawable/quit"/>
</menu>

Bien, voy a explicar un poco la estructura de este men, Empezamos declarando el men con la
etiqueta
, que contendr todos sus elementos bajo la etiqueta , en este caso, tambin tenemos un submenu,
que se declara igual que el men principal.
Los atributos de cada elemento son su identificador, el icono a mostrar y el ttulo.
Para poder usar este men, necesitamos inflarlo (Convertir el fichero XML en un objeto java), para
hacer esto, hay que llamar a MenuInflater.inflate(), el cdigo siguiente infla el fichero xml anterior
en el mtodo callback onCreateOptionsMenu().
53

MANUAL BSICO DE ANDROID


@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ejemplo_menu, menu);
return true;
}

Ahora, tenemos que responder a las acciones del usuario cuando pulse algn elemento de nuestro
men, para ello vamos a sobreescribir el mtodo onOptionsItemSelected()
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about:
Toast.makeText(
MenusActivity.this
,"Ejemplo Mens App"
,Toast.LENGTH_LONG)
.show();
return true;
case R.id.quit:
finish();
return true;

default:
return super.onOptionsItemSelected(item);
}

Context Menu
Los mens contextuales son similares a los mens mostrados al hacer click con el botn derecho de
un ratn en un PC, para crearlos, debemos sobreescribir el mtodo onCreateContextMenu(), donde
inflaremos el archivo xml.
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ejemplo_menu, menu);
}

Al igual que en los options menu, tenemos que responder a las acciones del usuario:
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about:
Toast.makeText(
MenusActivity.this
,"Ejemplo Mens App"

54

MANUAL BSICO DE ANDROID


,Toast.LENGTH_LONG)
.show();
return true;
case R.id.quit:
finish();
return true;

default:
return super.onOptionsItemSelected(item);
}

Pero este men contextual no se va a mostrar, ya que tenemos que asociarlo para que se lanze al
realizar una pulsacin prolongada sobre una view, en este caso un botn:
final Button boton = (Button) findViewById(R.id.button1);
registerForContextMenu(boton);

Aqu dejo algunas capturas de pantalla de la aplicacin:

55

MANUAL BSICO DE ANDROID

56

MANUAL BSICO DE ANDROID

Mas ejemplo de Mens


Android permite asignar mens a las actividades pulsando el botn de men del telfono mvil, y
este se desplegar. Para ello, lo que tenemos que hacer es lo siguiente:
-Crear un directorio nuevo dentro del directorio res, que se llamar menu y dentro de esta, crear un
archivo xml que se llamar menu.xml.
-Cundo ya tenemos el archivo xml creado nos aparecer algo as:
1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
3
4 </menu>
Pues bien, lo que tenemos que hacer a continuacin es aadir los items de los que se compondr el
men con el elemento de tipo <item>. Nosotros hemos creado dos items, uno para salir y otro
llamado acerca de quedando el contenido de menu.xml as:
1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
3
android:title="Salir"
4
android:id="@+id/itemSalir"
5
/>
6
7
<item
8
android:title="Acerca de..."
9
android:id="@+id/itemAcercaDe"
10
/>
11 </menu>
Nota: android:id siempre empieza por @+id/ y ser el encargado de identificar el item al que
corresponde, por tanto ningn id puede llamarse igual.
-Esto es todo en cuanto a diseo, para hacer que funcione correctamente tendramos que ir a la
actividad donde vamos a hacer que aparezca y colocar lo siguiente:

57

MANUAL BSICO DE ANDROID


import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
1 import android.view.MenuInflater;
2 import android.view.MenuItem;
3
4 public class MenuandroidActivity extends Activity {
5
/** Called when the activity is first created. */
6
@Override
7
public void onCreate(Bundle savedInstanceState) {
8
super.onCreate(savedInstanceState);
9
setContentView(R.layout.main);
10
}
11
12
//Crear el men y sus opciones
13
public boolean onCreateOptionsMenu(Menu menu){
14
super.onCreateOptionsMenu(menu);
15
//Se expande el men
16
MenuInflater inflater = getMenuInflater();
17
inflater.inflate(R.menu.menu, menu);
18
return true; //El men est visible
19
}
20
21
//Gestionar los elementos del men
22
public boolean onOptionsIntemSelected(MenuItem item){
23
/*El switch se encargar de gestionar cada elemento del
24
men dependiendo de su id,
25
por eso dijimos antes que ningn id de los elementos del
26
men
podia
ser igual.
27
*/
28
switch(item.getItemId()){
29
case R.id.itemAcercaDe: //Nombre del id del men, para
30
combrobar
que se ha pulsado
31
// Accin a realizar cuando se pulse el Acerca de...
32
en
el
men.
Lo ms normal es lanzar una actividad o un cuadro
33
34 flotante.
break;
35
case R.id.itemSalir:
36
finish();//Sale de la aplicacin
37
}
38
return true;//Consumimos el item, no se propaga
}
}
As quedara el men que hemos programado:

58

MANUAL BSICO DE ANDROID

Tambin se le puede poner un icono al men con el atributo


android:icon=@android:drawable/nombre_del_icono
Tenemos que tener por supuesto el icono metido en el directorio drawable.
Quedara as:

Submen
Pues bien, lo nico que tenemos que tener son dos mtodos en la actividad donde queramos que
aparezca el men.Un mtodo sera para crear el men public boolean
onCreateOptionsMenu(Menu menu) y otro mtodo para realizar la accin que le digamos al
pulsar una opcin del submen public boolean onOptionsItemSelected(MenuItem item).Estos
mtodos ya estn predefinidos, es decir no se les puede cambiar el nombre o no harn su funcin.
El primer mtodo(para disear el men principal y submen) sera as (dentro del cdigo comento
que hace cada trozo de cdigo):

59

MANUAL BSICO DE ANDROID


//Crear el men y sus opciones
@Override
public boolean onCreateOptionsMenu(Menu menu){
1
//MEN 1 Y SUBMEN 1
2
3
//SubMenu sub1 = menu.addSubMenu(id del grupo, id del
4
5 item, orden, ttulo del menu)
SubMenu sub1 = menu.addSubMenu(1,1,1,"Men Salir");
6
7
//Icono del men 1
8
sub1.setIcon(R.drawable.salir);
9
//Icono de las opciones del submen del men 1
10
sub1.setHeaderIcon(R.drawable.salir);
11
12
//sub1.add(id del grupo, id del item, orden, ttulo de la
13
14 opcin)
sub1.add(1, 10, 1, "Menu salir opcin 0");
15
sub1.add(1, 11, 2, "Menu salir opcin 1");
16
17
//MEN 2 Y SUBMEN 2 PARECIDO AL ANTERIOR
18
19
SubMenu sub2 = menu.addSubMenu(2,2,2,"Men Informacin");
20
21
sub2.setHeaderIcon(R.drawable.info);
22
sub2.setIcon(R.drawable.info);
23
24
sub2.add(1, 20, 0, "Men informacin opcin 0");
25
sub2.add(1, 21, 1, "Men informacin opcin 1");
26
/*Como podis comprobar en las opciones del men 1 de id
27 del item le pongo
28
* a la 1 opcin 10 y a la 2 11 debido a que pertenece
29 al men 1 la opcin 0 y la opcin 1
30
* lo mismo hago con las id de las opciones del 2 men 20
31 a la primera y 21 a la segunda.
32
* Esto cada persona lo puede poner como quiera, pero hay
33 que tener cuidado, ya que
34
* no se puede repetir el id de ningun item (opcin)
35
*/
return super.onCreateOptionsMenu(menu);
}
En este diseo de hay 2 mens y 2 submens dentro de esos mens pero se pueden poner todos los
que necesites.
El segundo mtodo(para realizar una accin cuando se pulse un item del men) sera as (dentro del
cdigo comento que hace cada trozo de cdigo):
60

MANUAL BSICO DE ANDROID


//Gestionar los elementos del men
@Override
public boolean onOptionsItemSelected(MenuItem item){
/*El switch se encargar de gestionar cada elemento del
men dependiendo de su id,
por eso dijimos antes que ningn id de los elementos del
men podia ser igual.
*/

1
2
3
4
5
6
switch(item.getItemId()){
7
case 10: //Id del men, para combrobar que se ha
8 pulsado
9
Toast.makeText(this,"Has pulsado la Opcin 0 del
10
men salir",Toast.LENGTH_LONG).show();
11
break;
12
case 11:
13
Toast.makeText(this,"Has pulsado la Opcin 1 del
14
men salir",Toast.LENGTH_LONG).show();
15
break;
16
case 20:
17
Toast.makeText(this,"Has pulsado la Opcin 0 del
18
19 men informacin",Toast.LENGTH_LONG).show();
break;
20
case 21:
21
Toast.makeText(this,"Has pulsado la Opcin 1
22
23 del men informacin",Toast.LENGTH_LONG).show();
break;
}
return true;//Consumimos el item, no se propaga
}
Este sera el resultado en pantalla de este ejemplo despes de pulsar el botn de men del
dispositivo android:

61

MANUAL BSICO DE ANDROID

Este sera el resultado al pulsar el Men salir:

62

MANUAL BSICO DE ANDROID

12. Dilogos y notificaciones


En ocasiones hay que mostrar mensajes al usuario para informarle del estado de la aplicacin, o del
estado de las operaciones que se estn llevando a cabo.
Android dispone de tres tipos de notificaciones:
Notificaciones Toast.
Notificaciones en la barra de estado.
Ventanas de dilogo.

Notificaciones Toast
Una notificacin Toast es un mensaje que se muestra superpuesto en la pantalla. Solo ocupa el
espacio necesario para mostrar la alerta, mientras tanto, la actividad que estaba visible puede seguir
usndose. Este tipo de notificaciones se muestran durante un periodo de tiempo y desaparecen, no
permiten interactuar con ellas. Debido a que un Toast se crea mediante un servicio en segundo
plano, puede aparecer aunque la aplicacin no est visible.
A lo largo de todas las entradas sobre Android, se ha usado mucho este tpo de notificaciones:
Toast.makeText(context, text, duration).show();

Para pasar el contexto, tenemos varias posibilidades, NombreActividad.this, o


getApplicationContext().
Para fijar la duracin del mensaje, usamos una de las dos constantes predefinidas,
Toast.LENGTH_SHORT Toast.LENGTH_LONG
En este caso, vamos a crear un layout personalizado para mostrar el Toast:
< ?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toastLayout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:background="#DAAA"
>
<imageview android:layout_width="48px"
android:layout_height="48px"
android:src="@drawable/ok"
android:padding="5dip"
android:id="@+id/ok"/>
<textview android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="Toast con layout personalizado"
android:textColor="#fff"

63

MANUAL BSICO DE ANDROID


android:gravity="center_vertical|center_horizontal"/>
</linearlayout>

Hay que asignar un id al LinearLayout, que usaremos posteriormente. Tambin hemos creado un
ImageView para mostrar un icono, y un TextView para mostrar el mensaje.
El siguiente paso es inflar este layout desde el cdigo:
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(
R.layout.toast_layout
,(ViewGroup) findViewById(R.id.toastLayout));
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();

Listo, al ejecutar la aplicacin tendremos un Toast como este:

Para saber ms acerca de los mensajes toast puede visitar:


http://developer.android.com/guide/topics/ui/notifiers/toasts.html

64

MANUAL BSICO DE ANDROID

Notificaciones en la barra de estado


Este tipo de notificaciones muestran un icono en la barra de estado, cuando desplegamos esta barra,
veremos el icono acompaado de un texto descriptivo indicando que ha pasado algo (Como que
hemos recibido un nuevo mensaje, o un correo electrnico).
Los pasos necesarios para crear este tipo de notificaciones son, usar el gestor de notificaciones del
sistema (NotificationManager) y posteriormente crear un objeto Notification en el que
configuraremos nuestra notificacin. Vamos a ver como hacerlo.
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

//Agregando el icono, texto y momento para lanzar la notificacin


int icon = R.drawable.ok;
CharSequence tickerText = "Notification Bar";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context = getApplicationContext();
CharSequence contentTitle = "Notificacin en barra";
CharSequence contentText = "Mensaje corto de la notificacin";

//Agregando sonido
notification.defaults |= Notification.DEFAULT_SOUND;
//Agregando vibracin
notification.defaults |= Notification.DEFAULT_VIBRATE;
Intent notificationIntent = new Intent(this, NotificacionesActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(HELLO_ID, notification);

El resultado es el siguiente:

65

MANUAL BSICO DE ANDROID

Al igual que los Toast, se puede crear un layout personalizado, para ms informacin visite:
http://developer.android.com/guide/topics/ui/notifiers/notifications.html

Dilogos
Por ltimo, vamos a ver los dilogos, que son ventanas que se muestran delante de las actividades, y
pueden recibir acciones del usuario, hay varios tipos:

AlertDialog
ProgressDialog
DatePickerDialog
TimePickerDialog

Si necesitamos un Dilogo que no sea uno de los de arriba, podemos extender de la clase Dialog, y
crear el nuestro propio.
La clase Activity implementa mtodos para gestionar los dialogos, son:

onCreateDialog(int): Encargado de crear el dilogo.


onPrepareDialog(int): Llamado justo antes de mostrarlo.
showDialog(int): Para mostrarlo.
dismissDialog(int): cierra el dilogo, guardando su estado.
removeDialog(int): cierra el dialogo elminndolo por completo.

Vamos a ver un ejemplo de AlertDialog, que preguntar si queremos salir de la aplicacin:


AlertDialog.Builder dialog = new AlertDialog.Builder(this);

66

MANUAL BSICO DE ANDROID


dialog.setMessage("Salir?");
dialog.setCancelable(false);
dialog.setPositiveButton("Si", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
NotificacionesActivity.this.finish();
}
});
dialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();

Tambin vamos a ver un ProgressDialog, indefinido (Que nunca termina).


ProgressDialog.show(
NotificacionesActivity.this
,"ProgressDialog"
,"Ejemplo dilogo de progreso"
,true
,true);

67

MANUAL BSICO DE ANDROID


Los dos ltimos parmetros son para que el dilogo sea indeterminado, y para que se pueda cerrar
con la flecha de atrs del terminal.

68

MANUAL BSICO DE ANDROID

13. Android: Una aplicacin con varios


idiomas
Si queremos tener nuestra aplicacin en dos lenguajes diferentes, por ejemplo Espaol e Ingls,
siendo el Espaol el utilizado por defecto, tendramos que crear dos versiones del fichero
strings.xml y lo guardaramos en los siguientes dos directorios:
res/values/strings.xml > para el Espaol.
res/values-en/strings.xml > para el Ingls.
Nota: los dos archivos strings.xml tienen que ser exactamente iguales, cambiando solamente las
cadenas que en uno estaran en Espaol y en el otro en Ingls
Tambin podemos indicar varios sufijos concatenados, por ejemplo:
res/values-en-rUS/strings.xml > para Ingls de Estados Unidos
res/values-en-rUK/strings.xml > para Ingls de Reino Unido

69

MANUAL BSICO DE ANDROID

14. Android: Disear aplicaciones para todas


las dimensiones de pantalla
Posted on by admin
Igual que existen varias carpetas para insertar imgenes dependiendo de la resolucin de la pantalla
del dispositivo, existen carpetas (que no vienen por defecto y las tenemos que crear nosotros) para
disear la aplicacin para todos los tamaos de dispositivos Android que existen. Pongo un
ejemplo:

El directorio Layout, es el que viene por defecto, es decir todos los dispositivos cogern el diseo
de la aplicacin de ese directorio, sin embargo si creamos los directorios layout-large, layout-small
y layot-xlarge, cada dispositivo coger automticamente dependiendo de su tamao y resolucin el
diseo que se encuentre en el directorio que mejor se adapte al dispositivo, es decir si yo tengo una
tablet y el tamao de pantalla es de 10.1 pulgadas automtica mente coger el diseo del directorio
layout-xlarge, pero en cambio si tengo un dispositivo mvil con una pantalla de 2.7 pulgadas,
obtendr el diseo del directorio layout-small.
En resumidas cuentas, tenemos que crear un diseo diferente para cada densidad en sus respectivos
directorios, pero siempre poniendo el mismo nombre a cada una de ellas.

70

MANUAL BSICO DE ANDROID

15. Estilos y Temas


Un estilo es una coleccin de propiedades que especifican que aspecto ha de tener un objeto View o
una ventana. Con los estilos podemos definir propiedades como la altura, relleno, color del texto,
fondo etc. Los estilos en Android comparten la filosofa de las hojas de estlo en cascada (CSS),
permitiendo separar el diseo del contenido.
Como podemos comprobar con este ejemplo, el cdigo queda mucho ms lmpio usando estilos:
Sin estilos:
<textview android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#00FF00"
android:typeface="monospace"
android:text="@string/hello" />

Con estilos:
<textview style="@style/CodeFont"
android:text="@string/hello" />

Definiendo estilos
Los estilos se definen en un fichero de recursos distinto al layout, colocado en el directorio
/res/values. stos ficheros no tienen porqu tener un nombre en concreto, pero por convencin se
suelen llamar styles.xml themes.xml
El nodo raiz de estos archvos debe ser .
Para cada estilo que queramos definir, hay que aadir un elemento
y un atributo name para ese estlo (es obligatorio), despus, aadiremos un elemento para cada
propiedad del estilo, que debe tener obligatoriamente el atributo name que declara la propiedad del
estilo y su valor. Los valores para pueden ser una palabra clave, valor hexadecimal, una referencia a
un recurso u otro valor dependiendo de la propiedad del estilo. Veamos un ejemplo:
<style name="CodeFont" parent="@android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>

En tiempo de compilacin, los elementos se convierten en un recurso que podremos referenciar


posteriormente mediante el atributo name del estilo, como vimos en el primer ejemplo
(@style/CodeFont).
El atributo parent es opcional y especifica el ID de otro estilo del cual queremos heredar sus
propiedades, pudiendo as sobreescribirlas.

71

MANUAL BSICO DE ANDROID

Herencia
Como acabamos de ver, el atributo parent sirve para heredar propiedades de otros estilos, podemos
heredar tanto de estilos del sistema como de los nuestros propios:
Del sistema:
<style name="GreenText" parent="@android:style/TextAppearance">
<item name="android:textColor">#00FF00</item>
</style>

De nuestros propios estilos:


<style name="CodeFont.Red">
<item name="android:textColor">#FF0000</item>
</style>
<style name="CodeFont.Red.Big">
<item name="android:textSize">30sp</item>
</style>

En este caso, no usamos el atributo parent, ya que estamos usando un estilo propio, tambin se
puede apreciar que podemos heredar cuantas veces queramos, como es el caso de
(CodeFont.Red.Big)

Aplicar estilos y temas a la interfaz grfica


Hay dos formas de aplicar estilos a la UI:
A una View individual, aadiendo el atributo style a un elemento del layout.
A una aplicacin o actividad completa, mediante el atributo android:theme del elemento en
el Android manifest.
Como vimos al principio, para aplicar un estilo a una View concreta usamos
style=@style/NombreDelEstilo
Para aplicar un tema a una actividad o aplicacin usaremos:
<application android:theme="@style/CustomTheme">
</application>

Para aplicarlos sobre actividades, usamos:


<activity android:theme="@android:style/Theme.Dialog">
</activity><activity android:theme="@android:style/Theme.Translucent">
</activity>

En este caso, estos temas ya vienen predefinidos, y se ven as, respectivamente:

72

MANUAL BSICO DE ANDROID

A continuacin, dejo una captura del ejemplo que he hecho para esta entrada, que se puede
descargar desde aqu.
73

MANUAL BSICO DE ANDROID

74

MANUAL BSICO DE ANDROID

16. Usando recursos


A todos los recursos que colocamos en las subcarpetas de ./res/ se puede acceder a travs de la clase
R de nuestro proyecto.
Esta clase R la genera el comando aapt en una pasada anterior a la compilacin
(Eclipse, por defecto, la va generando continuamente conforme cambiamos los
recursos). Contiene todos los identificadores de recursos para poder referenciarlos.
Al igual que la carpeta res, la clase R se organiza en subclases, as por ejemplo el icono que
colocamos en ./res/drawable/icon tiene su correspondencia en
R.drawable.icon (que es un identificador esttico de tipo int y sirve para acceder
al recurso).
As pues los ID de recurso estn compuestos de:
Clase R que contienen todos los recursos.
Subclase de recurso, cada grupo tiene la suya (drawable, string, style, layout).
Nombre del recurso que, segn el tipo, ser: el nombre del fichero sin la extensin o el atributo xml
android:name si es un valor sencillo (cadena, estilo, etc.).
Tenemos dos formas de acceder a los recursos definidos en la clase R:
En el cdigo, accediendo a las propiedades de la clase R directamente
(R.string.nombre).
En los ficheros XML, usando una notacin especial: @grupo_recursos/
nombre_recurso, es decir, el recurso anterior se accedera con @string/nombre.
Si lo que queremos es acceder a un recurso definido por el sistema antepondremos el prefijo
android:
Desde el cdigo: android.R.layout.simple_list_item_1.
En los ficheros XML: @android:layout/simple_list_item_1.

Referenciando atributos de estilo


Cuando aplicamos estilos a nuestros layout puede interesarnos acceder a un
atributo concreto de un estilo, para eso tenemos una sintaxis especfica que
podemos usar en nuestros XML:
?[
As por ejemplo si queremos colocar un texto pequeo usaremos:
?android:attr.textAppearanceSmall
Si queremos, tambin podemos utilizar nuestros propios atributos.
Primero lo definimos con un tag attrdentro de ./res/values/attr.xml.
< ?xml version="1.0" encoding="utf-8"?>
<resources>

75

MANUAL BSICO DE ANDROID


<attr name="cabecera" format="reference" />
</resources>

Ahora ya podemos usar esa propiedad en nuestros estilos:


Primero definimos un estilo de texto llamado TituloRojo, y luego lo aplicamos
al atributo que hemos creado llamado Cabecera. Obsrvese que como es un
atributo propio, no usamos el espacio de nombres android:.
Si luego quisiramos acceder a este atributo al definir un layout podramos usar
la sintaxis mencionada:
./res/layout/milayout
< ?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<textview android:layout_width="fill_parent
android:layout_height="fill_parent"
android:text="No hay datos disponibles"
style="?attr/cabecera" />
</framelayout>

./res/values/style.xml
< ?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MiTema" parent=
"@android:style/Theme.Light">
<item name="android:windowBackground">
@drawable/fondo</item>
<item name="cabecera">
@style/TituloRojo</item>
</style>
<style name="TituloRojo"
parent="@android:style/TextAppearance.Large">
<item name="android:textColor">#FF0000</item>
<item name="android:textStyle">bold</item>
</style>
</resources>

76

MANUAL BSICO DE ANDROID

17. Recursos Strings


Como ya hemos visto, los recursos juegan un papel muy importante en la arquitectura Android. Un
recurso en Android es un archivo (como un fichero de msica) o un valor (como el ttulo de un
Dilogo) que est ligado a una aplicacin ejecutable. Estos archivos estn ligados a un ejecutable de
tal manera que podemos cambiarlos sin necesidad de recompilar la aplicacin.
Los ejemplos de recursos ms familiares son cadenas de texto, colores e imgenes. En lugar de
escribir las cadenas de texto en el cdigo fuente, usamos sus IDs. Esta indireccin nos permite
cambiar el valor de la cadena sin tener que cambiar el cdigo fuente.
Existen mucho recursos en Android, que vamos a ver a lo largo de las etradas posteriores.
Empezaremos por un recurso muy comn, los string:

Recursos string
Android permite definir strings en uno o ms archivos XML de recursos. Estos archivos estn bajo
el directorio ./res/values. El nombre del archivo XML para este tipo de recurso puede ser
cualquiera, pero por convencin se suele llamar strings.xml. Veamos un ejemplo de este fichero:
< ?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello</string>
<string name="app_name">Hello app_name</string>
</resources>

Cuando este archivo se crea o modifica, el plugin ADT de eclipse automticamente crear o
actualizar una clase java de nuestra aplicacin llamada R.java alojada en el directorio ./gen, que
contiene los IDs nicos para las dos cadenas que acabamos de crear.
Para el fichero strings.xml que acabamos de crear, tendremos lo siguiente en la clase R:
package nombre.de.nuestro.paquete;
public final class R {
//.. otras entradas dependiendo de tu proyecto y aplicacin

public static final class string {


//.. otras entradas dependiendo de tu proyecto y aplicacin
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
//.. otras entradas dependiendo de tu proyecto y aplicacin
}
//.. otras entradas dependiendo de tu proyecto y aplicacin

Como vemos como primero R.java define una clase principal en el paquete raiz: public final class
R. Depues, define una clase interna llamada public static final class string. R.java crea esta clase
esttica interna como espacio de nombres para guardar los IDs de los recursos string.

77

MANUAL BSICO DE ANDROID


La definicin de los dos public static final int llamados app_name y hello son los IDs de los
recursos que representan nuestras cadenas de texto. Podemos usar estos IDs en cualquier lugar de
nuestro cdigo mediante R.string.hello o R.string.app_name
La estructura del fichero string.xml es muy fcil de seguir. Tenemos un elemento raiz llamado
name que ser la que usar como identificador R.java.
Para comprobar que se permiten varios recursos de string en el directorio values, vamos a crear otro
fichero llamado strings1.xml con lo siguiente:
< ?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello1">Hello</string>
<string name="app_name1">Hello app_name</string>
</resources>

Ahora, el plugin ADT de eclipse se encargar de actualizar el fichero R.java, que contendr lo
siguiente:
package nombre.de.nuestro.paquete;
public final class R {
//.. otras entradas dependiendo de tu proyecto y aplicacin

78

public static final class string {


//.. otras entradas dependiendo de tu proyecto y aplicacin
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
public static final int app_name1=0x7f040006;
public static final int hello1=0x7f040005;
//.. otras entradas dependiendo de tu proyecto y aplicacin
}
//.. otras entradas dependiendo de tu proyecto y aplicacin

MANUAL BSICO DE ANDROID

19. Recursos Layout


En Android, cada pantalla de una aplicacin habitualmente se carga desde un fichero XML que
actua de recurso. Un recurso layout es un recurso clave que se usa en Android para componer la UI
de nuestra aplicacin. Vamos a considerar el segmenteo de cdigo siguiente como ejemplo de una
actividad en Android.
public class PrincipalActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

La lnea setContentView(R.layout.main); seala que hay una clase esttica llamada R.layout y, que
dentro de esa clase hay una constante entera llamada main que apunta a una vista definida por un
fichero de recursos layout xML. El nombre del fichero XML es main.xml, el cual debe estar en el
directorio ./res/layout. El contenido de este fichero es el siguiente:
< ?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<textview android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<button android:id="@+id/b1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"/>
</linearlayout>

Vamos a ver la composicin de este fichero, como elemento raiz tenemos un elemento llamado
TextView seguido de un Button. Un LinearLayout coloca a sus hijos uno detrs de otro vertical u
horizontalmente.
Para cada pantalla que queramos hacer, necesitaremos ficheros layout distintos, mejor dicho, cada
layout debe estar en un fichero, como ./res/layout/screen1.xml y ./res/layout/screen2.xml
Por cada archivo de layout que tengamos en ./res/layout, se generar una entrada en R.java. Por
ejemplo, si tenemos estos dos archivos, file1.xml y file2.xml, en R.java aparecer:
// ...
public static final class layout {
public static final int file1=0x7f030000;

79

MANUAL BSICO DE ANDROID


public static final int file2=0x7f030001;
}
// ..

Las vistas definidas en estos layout, como el TextView son accesibles mediante cdigo java a travs
sus IDs de recursos generadas en R.java.
TextView tv = (TextView) this.findViewById(R.id.text1);
tv.setText("Texto para el TextView")

En este ejemplo, hemos localizado el TextView usando el mtodo findViewById() de la clase


Activity. La constante R.id.text1 corresponde al ID definido para el TextView en el fichero XML,
que creamos de la siguiente manera:
<textview android:id="@+id/text1"
....
/>

El valor del atributo id, indica que la constante llamada text1 ser usada para identificar nicamente
a esa vista. El signo + de +id/text1 significa que el ID text1 ser creado si no existe. En la siguiente
entrada se tratar la sintaxis de los recursos.

80

MANUAL BSICO DE ANDROID

20. Enviar datos entre actividades (Activity)


Posted on by admin
Cuando una actividad ha de lanzar a otra actividad en muchos casos necesita enviarle cierta
informacin. Android nos permite este intercambio de datos utilizando el mecanismo que se
muestra a continuacin:
1 Creamos un nuevo proyecto Android que se va a llamar Pasar Datos

2 Elegimos la versin mnima de Android en la que va a funcionar la aplicacin, en este caso es la


versin 2.2

3 Elegimos el nombre del paquete en el que se encuentra la aplicacin, en este caso se llama:
81

MANUAL BSICO DE ANDROID


es.inforjmr.pasardatos

4 Ahora en el directorio del proyecto res/layout, nos aparece un xml llamado main.
Ese main.xml lo editamos y ponemos este cdigo:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

1
2
3
4
5
6
<TextView
7
android:layout_width="fill_parent"
8
android:layout_height="wrap_content"
9
android:text="Introduce una cadena de carcteres para
10
11 mostrarlo en la siguiente actividad" />
12
<EditText
13
android:layout_width="fill_parent"
14
android:layout_height="wrap_content"
15
android:id="@+id/etCadena"
16
/>
17
<Button
18
android:layout_width="wrap_content"
19
android:layout_height="wrap_content"
20
android:text="Cambiar de actividad"
21
android:onClick="cambiarActividad"
22
/>
</LinearLayout>
Nos quedar algo as:

82

MANUAL BSICO DE ANDROID

5 Creamos otro archivo xml en res/layout llamado resultado.xml, lo editamos y le colocamos el


siguiente cdigo:
<?xml version="1.0" encoding="utf-8"?>
1 <LinearLayout
2 xmlns:android="http://schemas.android.com/apk/res/android"
3
android:layout_width="match_parent"
4
android:layout_height="match_parent"
5
android:orientation="vertical" >
6
<TextView
7
android:layout_width="wrap_content"
8
android:layout_height="wrap_content"
9
android:text="Datos recibidos de la actividad anterior"
10
/>
11
<TextView
12
android:id="@+id/tvDatosRecibidos"
13
android:layout_width="fill_parent"
14
android:layout_height="wrap_content"
15
/>
16
</LinearLayout>
Tiene que quedar as:

83

MANUAL BSICO DE ANDROID

Pues bien, ya tenemos creado el diseo de la aplicacin.


6 En src y dentro del paquete llamado anteriormente es.inforjmr.pasardatos, ya tenemos una
clase llamada PasarDatosActivity (ser la encargada de pasar los datos que le digamos a la
siguiente actividad) y ahora creamos una clase nueva llamada ResultadoActivity (ser la encargada
de recoger los datos que le pasa PasarDatosActivity)
PasarDatosActivity, tiene que contener el siguiente cdigo:

84

MANUAL BSICO DE ANDROID


package es.inforjmr.pasardatos;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
1 import android.view.View;
2 import android.widget.EditText;
3
4 public class PasarDatosActivity extends Activity {
5
/** Called when the activity is first created. */
6
EditText etCadena; //Cuadro de texto donde se inserta la
7 cadna
8
String contenidoCadena;//Aqu guardaremos el contenido del
9 cuadro de texto para pasarselo a la siguiente actividad
10
@Override
11
public void onCreate(Bundle savedInstanceState) {
12
super.onCreate(savedInstanceState);
13
setContentView(R.layout.main);//Muestra el layout
14
main.xml
15
16
etCadena =
17
(EditText)findViewById(R.id.etCadena);//Instanciamos etCadena
18
}
19
public void cambiarActividad(View v){
20
contenidoCadena = etCadena.getText().toString();
21
22 //Obtenemos el contenido del cuadro de texto
23
Intent i = new Intent(this,
24
ResultadoActivity.class);//Creamos
un nuevo intent para llamar a
25
26 la siguiente actividad
i.putExtra("resultado", contenidoCadena);//Guardamos el
27
la cadena en el intent y le ponemos de nombre resultado
startActivity(i);//Ejecutamos la actividad para que
muestre la segunda actividad
}
}
ResultadoActivity, tiene que contener el siguiente cdigo:
1
2
3
4
5
6
7
8
85

package es.inforjmr.pasardatos;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class ResultadoActivity extends Activity {
TextView tvDatosRecibidos; //TextView donde se mostrra la

MANUAL BSICO DE ANDROID


cadena recibida
String cadenaObtenida;//String donde se guardar la cadena
recibida
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
9
super.onCreate(savedInstanceState);
10
setContentView(R.layout.resultado);//Mostramos el layout
11
resultado.xml
12
tvDatosRecibidos =
13
14 (TextView)findViewById(R.id.tvDatosRecibidos);//Instanciamos(Crea
15 mos el objeto) tvDatosRecibidos
16
17
Bundle recogerDatos = getIntent().getExtras();//Creamos
18 un objeto de tipo Bundle que guardar todos los datos recibidos
19
cadenaObtenida =
20 recogerDatos.getString("resultado");//Del Bundle recogerDatos
21 obtenemos la cadena que en la actividad anterior le pusimos de
22 nombre resultado
23
tvDatosRecibidos.setText(cadenaObtenida);//mostramos la
cadena recibida en el TextView
}
}
Y por ltimo, insertamos la actividad en el AndroidManifest.xml
Contenido de AndroidManifest.xml:

86

MANUAL BSICO DE ANDROID


<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="es.inforjmr.pasardatos"
android:versionCode="1"
android:versionName="1.0" >

1
2
3
4
5
6
<uses-sdk android:minSdkVersion="8" />
7
8
<application
9
android:icon="@drawable/ic_launcher"
10
android:label="@string/app_name" >
11
<activity
12
android:name=".PasarDatosActivity"
13
android:label="@string/app_name" >
14
<intent-filter>
15
<action android:name="android.intent.action.MAIN"
16
/>
17
18
<category
19
android:name="android.intent.category.LAUNCHER"
/>
20
</intent-filter>
21
</activity>
22
<activity
23
android:name=".ResultadoActivity"></activity>
24
</application>
25
</manifest>
RESULTADO:

87

MANUAL BSICO DE ANDROID

21. Obtener datos de una subactividad.


Para ello tendremos que utilizar startActivityforResult(), onActivityResult() en la actividad
principal y setResult() en la subactividad.
Bien lo que vamos a hacer para este ejemplo es crear dos actividades, la actividad principal
ActividadPrincipal() y la subactividad SubActividad y vamos a obtener datos de la subactividad
y las utilizaremos en la actividad principal.
Contenido de la actividad principal ActividadPrincipal.java

88

MANUAL BSICO DE ANDROID


1 package es.inforjmr.obtenerDatosSubactividad;
2
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.os.Bundle;
6 import android.widget.TextView;
7
8 public class ActividadPrincipal extends Activity {
9
/** Called when the activity is first created. */
10
11
TextView contenido;//TextView donde se va a mostrar los
12 datos obtenidos de la subactividad
13
//El cdigo recibido se supone que es nico
14
public static final int CODIGO_RESPUESTA = 123;
15
@Override
16
public void onCreate(Bundle savedInstanceState) {
17
super.onCreate(savedInstanceState);
18
setContentView(R.layout.main);
19
contenido = (TextView)findViewById(R.id.tvContenido);
20
llamarSubactividad();
21
}
22
private void llamarSubactividad()
23
{
24
Intent intent = new Intent(this,SubActividad.class
25 );//Creo un intent para lanzar la subactividad
26
startActivityForResult( intent,
27 CODIGO_RESPUESTA );//lanzo la activida con startActivityForResult
28 y le paso el cdigo que tiene que devolver si todo ha ido bien
29
}
30
protected void onActivityResult(int requestCode,int
31 resultCode, Intent pData)
32
{
33
if ( requestCode == CODIGO_RESPUESTA )//Si el cdigo
34
de respuesta es igual al requestCode
35
{
36
if (resultCode == Activity.RESULT_OK )//Si
37
resultCode es igual a ok
38
{
final String dato =
pData.getExtras().getString(SubActividad.DATO_SUBACTIVIDAD );//Ob
tengo el string de la subactividad
//Aqu se hara lo que se desee con el
valor recuperado
contenido.setText(dato);//El valor
recogido en dato es un string que ser mostrado en el TextView de
la actividad principal
89

MANUAL BSICO DE ANDROID


}
}
}
}
Contenido de la subActividad SubActividad.java
package es.inforjmr.obtenerDatosSubactividad;
1 import android.app.Activity;
2 import android.content.Intent;
3 import android.os.Bundle;
4
5 public class SubActividad extends Activity {
6
7
public static final String DATO_SUBACTIVIDAD="";//Variable que
8 pasaremos a la actividad principal
9
@Override
10
public void onCreate(Bundle savedInstanceState)
11
{
12
super.onCreate(savedInstanceState);
13
volverActividadPrincipal();//Llamamos al mtodo
14
}
15
private void volverActividadPrincipal()
16
{
17
Intent dato = new Intent();
18
dato.putExtra(DATO_SUBACTIVIDAD,"valor");//Dato que
19
pasaremos
a la actividad principal
20
setResult(android.app.Activity.RESULT_OK,dato );
21
//Nos devuelve a la actividad principal
22
23 "ActividadPrincipal"
finish();
24
}
25
}
Contenido del layout main.xml

90

MANUAL BSICO DE ANDROID


<?xml version="1.0" encoding="utf-8"?>
1 <LinearLayout
2 xmlns:android="http://schemas.android.com/apk/res/android"
3
android:layout_width="fill_parent"
4
android:layout_height="fill_parent"
5
android:orientation="vertical" >
6
7
<TextView
8
android:id="@+id/tvContenido"
9
android:layout_width="fill_parent"
10
android:layout_height="wrap_content"
11
android:text="Actividad Principal " />
12
13
</LinearLayout>
Al AndroidManifest.xml hay que agregarle la subactividad tal y como aparece en el siguiente
archivo.
Contenido del AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
1 <manifest
2 xmlns:android="http://schemas.android.com/apk/res/android"
3
package="es.inforjmr.obtenerDatosSubactividad"
4
android:versionCode="1"
5
android:versionName="1.0" >
6
7
<uses-sdk android:minSdkVersion="7" />
8
9
<application
10
android:icon="@drawable/ic_launcher"
11
android:label="@string/app_name" >
12
<activity
13
android:name=".ActividadPrincipal"
14
android:label="@string/app_name" >
15
<intent-filter>
16
<action android:name="android.intent.action.MAIN"
17
/>
18
19
<category
20
android:name="android.intent.category.LAUNCHER"
/>
21
</intent-filter>
22
</activity>
23
<activity
24
android:name=".SubActividad"
25
android:label="@string/app_name" >
26
</activity>
27
</application>
91

MANUAL BSICO DE ANDROID


</manifest>
Este seria el resultado:

92

MANUAL BSICO DE ANDROID

21. Manejando la rotacin de pantalla en


Android
Uno de los temas ms importantes que hay que conocer es cmo Android gestiona la rotacin de la
interfaz de usuario dependiendo de la posicin que adquiera el telfono al rotarlo. La mayora de los
telfonos de hoy en da son touch y se encuentran dotados por sensores como el acelermetro que
nos permite saber cuando un telfono cambia entre los estados portrait (vertical) y landscape
(horizontal).
Tambin, resulta una buena prctica asegurarnos de que nuestras interfaces se visualizarn de una
forma decente en cualquiera de estos dos estados. Por ello, el da de hoy vamos a conocer los
conceptos bsicos que debes tomar en cuenta para que tus aplicaciones estn listas para esas
rotaciones que da la vida.
Por default, cuando ocurre un cambio en la configuracin del telfono (como cambio de idioma)
que repercute en la seleccin de los recursos en una aplicacin, Android destruye y reconstruye
todas las actividades que se estn ejecutando o aquellas que se encontraban pausadas con el fin de
prepararlas para el momento en el que el usuario interacte nuevamente con ellas. La rotacin es
uno de estos escenarios ya que provoca que nuevos recursos de layout sean cargados con la
finalidad de ofrecerle una vista ms cmoda al usuario segn la posicin del telfono que est
utilizando en ese momento.
Y si bien podra pensarse que nicamente el cambio se da a nivel visual, no hay que olvidar que el
usuario pudo haber introducido datos en una pantalla o pudo a ver estado enfocando algn tem a la
mitad de un ListView; en estos casos, la rotacin de pantalla no tiene que truncar estas acciones y
por el contrario, debemos hacer todo lo posible para que el usuario visualice esos mismos datos o
ese mismo tem en la nueva vista que ha sido llamada.
En estos casos, resulta til el uso del mtodo onSaveInstanceState() que debemos implementar
dentro de nuestra actividad y llenar el objeto Bundle suministrado como parmetro con la
informacin suficiente para regresar a la nueva actividad al estado actual de la actividad cuya
orientacin acaba de cambiar.
Posteriormente, con el mtodo onRestoreInstanceState() recuperamos toda esta informacin del
objeto Bundle y la utilizamos para que la actividad se muestre con la informacin tal y como estaba
en la actividad anterior.
Para se haga ms claro, vamos a pasar a la parte divertida: el cdigo.
1. Creamos un nuevo proyecto Android llamado RotacionDemo con la versin 2.2.
2. En este ejemplo manejaremos dos archivos de layout; uno para la vista en portrait y la otra para
la vista en landscape. La primera la definiremos dentro de la carpeta res > layout en el archivo
main.xml tal y como te muestro a continuacin:

93

MANUAL BSICO DE ANDROID

3. Para definir la vista en landscape es necesario crear una carpeta llamada layout-land dentro del
directorio res. Dentro de esta carpeta vamos a crear un nuevo archivo XML llamado main.xml en el
que definiremos lo siguiente:

Como puedes ver, el contenido de ambos archivos es casi idntico. Hemos definido un
LinearLayout como elemento raz del archivo, y dentro de l hemos colocado dos botones, el
94

MANUAL BSICO DE ANDROID


primero mostrando un texto Seleccionar y el segundo mostrando el texto Ver, ambos definidos
en el archivo res > values > strings.xml. La diferencia reside en que el atributo android:orientation
del primer layout lo hemos definido en vertical y el segundo, en horizontal. De esta manera, en el
modo portrait, los botones se mostrarn uno sobre otro, mientras que en el modo landscape se
mostrarn uno al lado del otro.
Otro punto importante que quiero aclarar antes de avanzar con el tutorial es la razn de por qu
hemos llamado de la misma forma los archivos en los dos directorios de layout. Android es un
sistema operativo tan inteligente que cuando se trata de elegir recursos segn las caractersticas
que muestre el telfono, seleccionar aquellos que se apeguen a los requerimientos de las
aplicaciones para su buena visualizacin. Cuando platicamos acerca del manejo de idiomas en
Android, vimos cmo con agregar un sufijo con la clave del pas al final de una carpeta values,
Android entiende que nuestra aplicacin soporta varios idiomas, eligiendo de forma automtica cul
debe ser el idioma por default que debe mostrar tomando en cuenta la configuracin del telfono.
Este mismo comportamiento lo vemos con los directorios drawable que nos permiten manejar
recursos de imagen que se acomoden a los diferentes tamaos de pantalla, dejando una vez ms que
Android se encargue de gestionar qu recursos sern llamados.
Con los layouts pasa lo mismo. Para definir los diferentes estados de una interfaz de usuario, es
necesario separar los archivos de layout en las carpetas res > layout y res > layout-land. Si por
ejemplo, tuviramos un layout llamado vista_directorio.xml, este archivo deber colocarse en
ambos directorios con sus modificaciones correspondientes que le permitan desplegarse
cmodamente en la pantalla. De la misma forma que en los casos anteriores, Android se encargar
de llamar el archivo layout correspondiente de acuerdo a la posicin del telfono.
4. En este ejemplo vamos a utilizar el Intent que nos permite trabajar con el directorio de contactos
del telfono. La funcionalidad ir as: Al presionar el botn Seleccionar se lanzar el Intent del
directorio, por lo que podremos elegir a algn contacto y una vez hecho esto, regresaremos a la
pantalla inicial dnde nos encontraremos al botn Ver habilitado (recordar que en la definicin en
XML, definimos que este botn apareciera deshabilitado al arranque de la aplicacin). Al hacer clic
sobre el botn Ver, este lanzar otro Intent que nos permitir ver los detalles completos del contacto
que seleccionamos momentos antes. El plus es que sin importar que rotemos el telfono, la
seleccin previa que haya hecho el usuario deber guardarse.
A continuacin te escribo el cdigo Java que debers tener en la actividad principal de tu proyecto:
import
import
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.provider.ContactsContract.Contacts;
android.widget.Button;
android.net.Uri;
android.view.View;
android.content.Intent;

public class RotacionDemoActivity extends Activity {


static final int PICK_REQUEST=1337;
Button viewButton=null;
Uri contact=null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

95

MANUAL BSICO DE ANDROID


super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn=(Button)findViewById(R.id.seleccionar);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i=new Intent(Intent.ACTION_PICK,
Contacts.CONTENT_URI);
}
});

startActivityForResult(i, PICK_REQUEST);

viewButton=(Button)findViewById(R.id.ver);
viewButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(Intent.ACTION_VIEW, contact));
}
});
restoreMe(savedInstanceState);
viewButton.setEnabled(contact!= null);
}//Fin de onCreate()
@Override
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
if (requestCode==PICK_REQUEST) {
if (resultCode==RESULT_OK) {
contact=data.getData();
viewButton.setEnabled(true);
}
}
}//Fin de onActivityResult()
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (contact!=null) {
outState.putString("contact", contact.toString());
}
}//Fin de onSaveInstanceState()
private void restoreMe(Bundle state){
contact=null;
if (state!=null) {
String contactUri=state.getString("contact");
if (contactUri!=null) {
contact=Uri.parse(contactUri);
}

96

MANUAL BSICO DE ANDROID


}
}//Fin de restoreMe()
}

La magia de la actividad se encuentra centrada en los tres mtodos onActivityResult(),


onSaveInstanceState() y restoreMe(). El mtodo onActivityResult() lo sobreescribimos de la
superclase para que una vez que hayamos elegido el contacto de la lista, guardemos
momentneamente esa Uri en el objeto contacto y habilitemos el botn viewButton que es el botn
Ver de nuestra aplicacin. Este mtodo se manda a llamar como respuesta a la invocacin de
startActivityForResult() dentro del listener del botn Seleccionar.
Tambin sobreescribimos el mtodo onSaveInstanceState() para que pase lo que pase con la
actividad guardemos la referencia del contacto que hemos elegido como el estado actual y que
pueda ser recuperado si algn tipo de interrupcin sucede.
Por ltimo, creamos un mtodo llamado restoreMe() que en el caso de que se detecte un estado
anterior guardado, se recupere dentro del objeto contacto definiendo la Uri de ese recurso que
previamente se seleccion para que al presionar el botn Ver no haya ningn problema en mostrar el
detalle de ese contacto.
5. Para ver realmente el funcionamiento de este demo, es recomendable que lo corras en tu telfono
ya que aqu tendrs tu directorio de contactos que es un pilar fundamental en la funcionalidad.
Nota: Si decides trabajar en el emulador, podrs activar la rotacin de la pantalla presionando la
combinacin de teclas Ctrl + F12.
Al ejecutar la aplicacin este ser el comportamiento que debemos ver:

Layout en Portrait
97

MANUAL BSICO DE ANDROID

Layout en Landscape

Vista de la informacin del contacto


Con este sencillo ejemplo hemos mostrado algunas de las consideraciones ms importantes que
debes tomar en cuenta con la rotacin de la pantalla.
Hay que agregar que dependiendo de la complejidad de nuestras aplicaciones, nos resultar
necesario conocer mejores alternativas para guardar la consistencia de los estados, manejar de
forma manual la rotacin de la pantalla a travs del AndroidManifest.xml o incluso cmo bloquear
esta opcin en una aplicacin.
De ser necesario estaremos platicando acerca de estos casos especficos en futuros posts, de
98

MANUAL BSICO DE ANDROID


mientras ya tienes algo nuevo que poner en prctica en tus aplicaciones.

99

MANUAL BSICO DE ANDROID

EVITAR QUE NUESTRA ACTIVIDAD COMIENCE DE


NUEVO AL ROTAR LA PANTALLA
Pues ya que est mencionado, empecemos precisamente por aqu.
Para que nuestra actividad, o clase para los incondicionales de Java, contine su curso al rotar la
orientacin sin que comience de nuevo el proceso, en el inicio cdigo de la propia actividad
aadiremos esto:
public class nombreActividad extends Activity {
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
Este cdigo por s solo no evitar el reinicio. Para completar la accin deberemos aadir esta lnea
a nuestra actividad en el manifest:
<activity android:name=nombreActividad android:configChanges=keyboard|
keyboardHidden|orientation
Y listo, nuestra actividad continuar ejecutndose sin cambios al rotar la pantalla.
AJUSTE CORRECTO DE ELEMENTOS O VIEWS A LA PANTALLA EN EL CAMBIO DE
ORIENTACION
Sigamos por el mismo camino;
Otra situacin muy comn es que montemos un layout para nuestra actividad donde verticalmente
todos los elementos se colocan o encajan a la perfeccin pero al rotar horizontalmente la pantalla
ste ya no se ajustar como debiera y se pierde toda la armona o configuracin de los elementos.
Realmente existen varias formas de afrontar esto. Desde aqu vamos a detallar una que puede
resultar especialmente til.
Los xml con el interface grfico se guardan en la carpeta layout. Bien, pues vamos a crear una
nueva carpeta llamada layout-land, dentro del directorio res.
Pongamos que dentro de la carpeta original layout tenemos el fichero xml llamado main.xml que
se crea por defecto en cualquier proyecto, pues dentro de la nueva carpeta creada llamado layoutland vamos a crear un fichero que se llame tambin main.xml.

100

MANUAL BSICO DE ANDROID

Para qu sirve esto? Cuando ejecutemos nuestra aplicacin y rotemos horizontalmente la pantalla,
si el programa detecta que existe una carpeta llamada layout-land en vez de rotar el main.xml
original (pudiendo perder la configuracin para que encaje en la pantalla) cargar el main.xml que
est dentro de layout-land.
Esto nos permite crear un xml para cuando estemos corriendo la aplicacin en vertical y otro para
cuando estemos en horizontal, asegurndonos de este modo que siempre tendremos un interface
grfico sin errores.
MOSTRAR UN MENSAJE RPIDO
Algunas veces es necesario informar al usuario o confirmarle una accin de forma
rpida y directa, para eso android contiene los llamados mensajes tipo toast, los cuales
se imprimirn en pantalla con el texto que queramos, evitndonos tener que crear una
nueva alerta, o si nos complicamos la vida, una nueva actividad.
El cdigo de un mensaje toast es tan sencillo como esto:

101

MANUAL BSICO DE ANDROID

Toast.makeText(NOMBREACTIVIDAD.this,Elandroidelibre.com,Toast.LENGTH_SH
ORT).show();
Cmo decamos, se imprimen en pantalla durante unos segundos, no obstante si se quiere prolongar
algo ms el tiempo de prolongado no tenemos mas que modificar el comando SHORT por LONG.
PERO.. Y SI QUEREMOS UN MENSAJE MS DETALLADO?
Una vez vista la utilidad informativa del mensaje toastqu ocurre si lo que necesitamos es un
mensaje informativo que requiera de una interaccin con el usuario?.
Pongamos un ejemplo: grabamos un nombre de usuario y una contrasea y queremos que la
aplicacin nos lance un men donde aparezcan estos datos con un botn de confirmar o cancelar.

El toast simplemente muestra un texto (aunque tambin se puede crear con una
imagen) de modo que para interactuar con el usuario crearemos un alert dialog.
102

MANUAL BSICO DE ANDROID


public void cajaAndroideLibre (){
AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
alt_bld.setMessage(Guardar datos?) // Esto determina la pregunta de la ventana
.setCancelable(false)
.setPositiveButton(Guardar,new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Aqui ponemos el codigo a ejecutar
// al pulsar el boton guardar
}
})
.setNegativeButton(Cancelar, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Aqui ponemos el codigo a ejecutar
// al pulsar el boton Cancelar
}
});
AlertDialog alert = alt_bld.create();
alert.setTitle(Title); // Aqui ponemos el titulo de la ventana
alert.setIcon(R.drawable.icon); // Aqui ponemos el icono de la ventana
alert.show();
}

103

MANUAL BSICO DE ANDROID

22. Tareas en segundo plano (I): Threads


Posted on by admin
Las tareas en segundo plano se utilizan para que cuando tengamos procesos largos o varios procesos
a la vez en nuestra aplicacin esta, no se quede bloqueada mientras los procesos estn corriendo.
Mediante el uso de hilos, se pueden crear aplicaciones que responden cuando se est trabajando con
procesos que requieren mucho tiempo.
Para que la aplicacin responda cuando se estn ejecutando procesos que requieren mucho tiempo,
t tienes varias opciones. Debe saber que en Java se puede crear una clase que extiende de la clase
Thread y anula el mtodo public void run(), despus se llama al mtodo start() para ejecutar el
proceso que consume ms tiempo. Si la clase ya extiende de otra clase, se puede implementar la
interfaz Runnable. Otra forma de hacerlo, sera crear una propia clase que extienda de la clase de
Android AsyncTask, pero de esta opcin ya hablaremos en prximos artculos, en este nos vamos a
centrar en Thread (Hilos).
Primero vamos a mostrar un ejemplo del uso de la clase Thread:
public class MainActivity extends Activity {
1
long contador;
2
TextView tvContador;
3
Handler _handler;
4
@Override
5
public void onCreate(Bundle savedInstanceState) {
6
super.onCreate(savedInstanceState);
7
setContentView(R.layout.main);
8
9
Thread thread = new Thread(new Runnable(){
10
11
@Override
12
public void run() {
13
//Aqu ir el cdigo que se ejecutar en segundo
14
plano.
15
}
16
17
});
18
19
}
20
}
Como podis comprobar, cuando empieza la actividad en el mtodo onCreate() creamos un objeto
de tipo Thread que est construido con un objeto Runnable. El mtodo de la clase Runnable
run() se ejecutar cuando llamemos al mtodo start() de la clase Thread. Desde aqu se pude
llamar a otro mtodo o varios mtodos y operaciones que requieren mucho tiempo y que de otra
forma haran que la aplicacin no respondiese.
Normalmente, cuando nosotros trabajamos con hilos obtenemos unos resultados que queremos
104

MANUAL BSICO DE ANDROID


ensear al usuario. Si intentamos actualizar la interfaz grfica de usuario desde el Thread (no
desde el Thread principal) la aplicacin se bloquear. Es posible cambiar la interfaz de usuario con
la ayuda de una clase de tipo Handler (Que tambin veremos en artculos posteriores).
Los Thereads creados e inicializados seguirn funcionando incluso si el usuario sale de la
aplicacin. Se puede hacer un seguimiento de los Threads y decirles que se detengan, esto
normalmente se hace con un valor booleano. Para estar seguros de que el Thread se detiene cuando
el usuario sale de la aplicacin, antes de llamar al mtodo start() el objeto Thread, lo
estableceremos como un Thread demonio.
1thread.setDaemon(true);
Tambin puede ser til el nombre del thread. Nosotros podemos dar nombre al thread cuando
creamos el objeto. Ejemplo:
Thread thread = new Thread(new Runnable(){
1
@Override
2
public void run() {
3
//Aqu ir el cdigo que se ejecutar en segundo
4
plano.
5
}
6
}, "Nombre del thread(hilo)");
O con el mtodo thread.setName(). Ejemplo:
1thread.setName("Nombre del thread(hilo)");

105

MANUAL BSICO DE ANDROID

23. Tareas en segundo plano (II): AsyncTask


AsyncTastk lo utilizaremos por ejemplo si tenemos que realizar algn procesamiento pesado , o
cargar recursos desde la red y queremos mostrar los avances y resultados en la interfaz de usuario
etc. En nuestro caso vamos a crear algo sencillo, un contador de segundos en la que se ira
rellenando una barra de progreso.
Para ejecutar procesos en segundo plano y actualizar el thread de la interfaz de usuario (Tambin
conocido como thread principal) lo podemos hacer de varias formas, pero para este tipo de
desarrollo AsyncTask es la ms adecuada y todo desarrollador Android debe saber cmo utilizarla.
Esta clase contiene varios mtodos que son los siguientes:
onPreExecute(). Se ejecutar antes de la tarea en segundo plano. Se suele utilizar para preparar la
ejecucin de la tarea, inicializar la interfaz, etc.
doInBackground(). Contendr el cdigo de la tarea que queremos ejecutar en segundo plano.
onProgressUpdate(). Se ejecutar cada vez que llamemos al mtodo publishProgress() desde el
mtodo doInBackground(). Normalmente se utiliza para actualizar la interfaz de usuario.
onPostExecute(). Se ejecutar cuando finalice nuestra tarea en segundo plano, es decir, cuando
termine el mtodo doInBackground().
onCancelled(). Se ejecutar si se cancela la tarea en segundo plano antes de que finalice.
Al crear una clase que extiende de AsyncTask tendremos que implementar un mtodo abstracto (ya
que AsyncTask es una clase abstracta), llamado doInBackground() (este ser el nico que nos dir
que aadamos, los que hemos mencionado anteriormente los tenemos que aadir a mano).
Bueno pues empezamos a programar la actividad que he mencionado al principio. Lo primero es la
interfaz de usuario:

106

MANUAL BSICO DE ANDROID


<?xml version="1.0" encoding="utf-8"?>
1
<LinearLayout
2 xmlns:android="http://schemas.android.com/apk/res/android"
3
android:orientation="vertical"
4
android:layout_width="fill_parent"
5
android:layout_height="fill_parent">
6
7
<TextView
8
android:layout_width="fill_parent"
9
android:layout_height="wrap_content"
10
android:text="Barra de progreso:"
11
/>
12
<ProgressBar
13
android:id="@+id/progressBar"
14
style="?android:attr/progressBarStyleHorizontal"
15
android:layout_width="fill_parent"
16
android:layout_height="wrap_content"
17
/>
18
</LinearLayout>
Como podis comprobar, el diseo es muy simple, pero suficiente para este ejemplo.
Ahora vamos con la programacin del cdigo java. La ir comentando para que se vaya
entendiendo bien lo que hace.

107

MANUAL BSICO DE ANDROID


1 public class MainActivity extends Activity {
2
int progreso;//Guardar un numero entero que ser el numero
3 de segundos que ha pasado desde que hemos inicializado la
4 aplicacin.
5
ProgressBar barraProgreso;//Declaracin de la barra de
6 progreso.
7
@Override
8
public void onCreate(Bundle savedInstanceState) {
9
super.onCreate(savedInstanceState);
10
setContentView(R.layout.main);
11
12
barraProgreso =
13 (ProgressBar)findViewById(R.id.progressBar);//Relacionamos el la
14 barra de progreso del layout con el de java
15
16
new TareaSegundoPlano().execute();//Iniciamos la tarea en
17 segundo plano, en este caso no necesitamos pasarle nada.
18
}
19
20
//Clase interna que extiende de AsyncTask
21
public class TareaSegundoPlano extends AsyncTask<Void, Void,
22 Void>{
23
24
//Mtodo que se ejecutar antes de la tarea en segundo
25 plano, normalmente utilizado para iniciar el entorno grfico
26
protected void onPreExecute(){
27
barraProgreso.setProgress(0);//Ponemos la barra de
28 progreso a 0
29
barraProgreso.setMax(60);//El mximo de la barra de
30 progreso son 60, de los 60 segundo que va a durar la tarea en
31 segundo plano.
32
}
33
34
//Este mtodo se ejecutar despus y ser el que ejecute
35 el cdigo en segundo plano
36
@Override
37
protected Void doInBackground(Void... params) {
38
for(progreso=1;progreso<=60;progreso++){//Creamos un
39
for de 1 a 60 que ir contando los segundos.
40
41
try {
42
Thread.sleep(1000);//Esto lo que hace es
43
ralentizar este proceso un segundo (el tiempo que se pone entre
44
parntesis es en milisegundos) tiene que ir entre try y catch
45
} catch (InterruptedException e) {}
46
108

MANUAL BSICO DE ANDROID


publishProgress();//Actualizamos el progreso, es
decir al llamar a este proceso en realidad estamos llamamos al
mtodo onProgresssUpdate()
}
return null;//Al llegar aqu, no devolvemos nada y
acaba la tarea en segundo plano y se llama al mtodo
onPostExecute().
}
protected void onProgressUpdate(Void... values) {
barraProgreso.setProgress(progreso);//Actualizamos la
barra de progreso con los segundos que vayan.
}
protected void onPostExecute(Void result){//A este mtodo
se le llama cada vez que termine la tarea en segundo plano.
Toast.makeText(MainActivity.this, "Tarea Finalizada",
Toast.LENGTH_LONG).show();//Nos muestra una notificacin
informando de que la tarea en segundo plano ha finalizado
}
}
}
Aqu dejo unas capturas de la aplicacin:

109

MANUAL BSICO DE ANDROID

24. Android: Thread (Hilo) y Handler, proceso


en segundo plano
Primero hay que saber que s cada cosa:
Thread (Hilo):
Es la funcin encargada de crear algn proceso en segundo plano. Su funcionamiento es bastan
te simple aunque como todo siempre se puede complicar. Se pueden crear tantos hilos (Thread)
como se quiera, teniendo en cuenta que el hilo deja de formar parte de la aplicacin y funciona de
manera independiente. A simple visto no hay ningn problema pero el hilo no puede modificar ni
insertar datos en el hilo principal (aplicacin) esto causara error, Entonces?, como podemos
utilizar los hilos para volcar informacin a nuestra aplicacin? La solucin se llama Handler.
Handler:
Para que lo entendamos todos un handler es el puente que hay entre un hilo secundario (thread)
y el hilo principal (aplicacin). No hay mucho ms que explicar, para que se entienda bien:

Para ver el cdigo y el funcionamiento vamos hacer un ejemplo muy prctico que seguro que a
muchos le gusta.
Crear una barra de progreso en Android:
El ejemplo que vamos a utilizar es una barra de progreso (ProgressBar) que mostraremos
inicialmente, a continuacin crearemos un thread y en su interior la funcin que queramos, en este
ejemplo simplemente ser un contador (tendremos que simular algn proceso que tarde algo para
poder ver funcionando el thread y no sea simplemente un parpadeo) y utilizaremos un handlet para
ir actualizando la barra de progreso (situada en el hilo principal) como hemos comentado para
actualizar datos de pantalla desde un hilo secundario (en nuestro caso el contador) hace falta un
puente, es decir, nuestro handler.
Como vamos a ver el Handler hay que declararlo al inicio:
private Handler puente = new Handler() {
@Override

110

MANUAL BSICO DE ANDROID


public void handleMessage(Message msg) {
}
};

Como vemos hay que pasarle un Message, en nuestro caso sera el contador hacia la progressbar.
Ahora mostramos el progressbar:
progressDialog = new ProgressDialog(EjemplotutoActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
progressDialog.setMax(10000);
progressDialog.setProgress(0);
progressDialog.setCancelable(false);
progressDialog.show();

La barra de progreso la hemos puesto a 0 y su mximo ser 10000 as nos dar tiempo a verlo.
Creamos el Thread y lo ponemos en marcha con la funcion start() :
Thread th1 = new Thread(new Runnable() {
@Override
public void run() {
}
});
th1.start();

Ahora crearemos nuestro contrador:


Thread th1 = new Thread(new Runnable() {
@Override
public void run() {
for(int a=1;a<9999;a++){
int contador = a;
}
}
});
th1.start();

Ahora vamos hacer el paso importante pasar nuestro contador por un 'puente' handler hacia el
progressBar, lo haremos atravs de un Message :
Thread th1 = new Thread(new Runnable() {
@Override
public void run() {
for(int a=1;a<9999;a++){
int contador = a;

111

MANUAL BSICO DE ANDROID


Message msg = new Message();
msg.obj = a;
puente.sendMessage(msg);
}
}
});

Como vemos enviamos un Message a nuestro Handler 'puente' y lo har 9998 veces ya que esta
dentro de un tnel, la velocidad como veris va un poco saturada al menos en el emulador. Ya solo
queda recivir el contador en el Handler e insertarlo en el ProgressBar:
private Handler puente = new Handler() {
@Override
public void handleMessage(Message msg) {
progressDialog.setProgress((Integer)msg.obj);
}
};

Como ya vis hay que hacer un casteo '(Integer)msg.obj' para convertir el mensaje en su forma
original, un Integer y aadirlo al progressBar atravs del .setProgress.

112

MANUAL BSICO DE ANDROID

25. Obtener informacin de un archivo


Para obtener informacin de cualquier archivo en Android, vamos a utilizar la clase File.
La clase File tiene una serie de mtodos informativos. Para utilizar cualquiera de estos, debe crear
un objeto File que contenga el nombre del archivo (ruta) con el que se va a trabajar.
Debe tenerse en cuenta que la creacin de un objeto de tipo File no tiene ningn efecto sobre el
sistema permanente de archivos, sino que es solo un objeto en la memoria de Java.
Para cambiar el sistema de archivos del objeto File, existen numerosos mtodos de cambio, como
por ejemplo uno para la creacin de un nuevo archivo (vaco), otro para cambiar el nombre de
archivo, otros que dan informacin acerca del archivo, etc. La siguiente tabla enumera alguno de los
mtodos de informacin de la clase File.
Tipo de
respuesta
boolean
String
String
String
boolean
boolean
long
long
boolean
boolean
Cdigo:

113

Nombre del
mtodo
exists()
getCanonicalPath()
getName()
getParent()
canRead()
canWrite()
lastModified()
length()
isFile()
isDirectory()

Significado
Verdadero si existe ese nombre.
Nombre de archivo completo (ruta).
Nombre de archivo relativo.
Directorio padre.
Devuelve true si el archivo se puede leer.
Devuelve true si en el archivo se puede escribir.
Ultima modificacin.
Tamao del archivo.
Devuelve true si es un archivo.
Devuelve true si es un directorio (puede no ser ni archivo ni
directorio).

MANUAL BSICO DE ANDROID


File archivo = new File("sdcard");
1
StringBuilder datosArchivos = new StringBuilder();
2
3
try {
4
//Ruta completa
5
archivo.getAbsolutePath();
6
//Nombre completo
7
archivo.getCanonicalPath();
8
//Directorio padre
9
archivo.getParent();
10
//Comprobar si se puede escribir devuelve true en el
11
12 caso de que se pueda escribir y false en caso contrario.
13
archivo.canWrite();
14
//Comprobar si se puede leer devuelve truen en el
15 caso de que se pueda leer y false en caso contrario.
16
archivo.canRead();
17
//Comprobar ultima modificacin
18
archivo.lastModified();
19
//Comprobar si es un directorio
20
archivo.isDirectory();
21
22
} catch (IOException e) {
23
e.printStackTrace();
}
No se puede cambiar el nombre de un objeto File almacenado, solo tienes que crear un objeto File
cada vez que tengas que consultar un archivo diferente.

114

MANUAL BSICO DE ANDROID

26. Lectura de un archivo


Queremos leer informacin de un archivo empaquetado con la aplicacin Android. Tendremos que
poner el archivo correspondiente en el directorio res/raw (tambin tendremos que crear el
directorio raw ya que no est presente de forma predeterminada). Dado que es en el directorio res/
la clase R generada tendr un id, que pasaremos a openRawResource(). A continuacin, vamos a
leer el archivo usando InputStreamReader que nos devuelve envuelto en un BufferedReader. Por
ltimo, extraemos la cadena desde el BufferedReader usando el mtodo readLine. Eclipse nos
pide que metamos la funcin readLine dentro del bloque try-catch, ya que existe la posibilidad de
que nos lance un error IOException.
Nota: Tenemos que crear el directorio raw en el directorio res/ y dentro del directorio res/raw/
crearemos un archivo llamado archivo_ejemplo en el cual escribiremos un texto cualquiera (todo
esto de forma grfica en el proyecto).

Cdigo:

115

MANUAL BSICO DE ANDROID


//Creamos un InputStreamReader con la ruta del archivo que se
quiere leer
InputStreamReader is = new
InputStreamReader(this.getResources().openRawResource(R.raw.archi
vo_ejemplo));
//Creamos el BufferedReader para leer el archivo
BufferedReader leer = new BufferedReader(is);
//Variable en la que se guardar todo el texto leido en
el archivo.
StringBuilder textoFinal = new StringBuilder();
//Guarda la linea que lee leer.readLine()
String linea;

1
2
3
4
5
6
7
8
9
10
11
//Se encierra la lectura entre las sentencias try-catch
12
por si hay algn error en el transcurso de la lectura.
13
try {
14
//Mientra la linea sea distinto de null sigue leyendo
15
while((linea = leer.readLine()) != null){
16
//Aade el contenido de la linea al textoFinal
17
textoFinal.append(linea);
18
}
19
} catch (IOException e) {
20
//En caso de error muestra lo sucedido.
e.printStackTrace();
}

116

MANUAL BSICO DE ANDROID

27. Listar contenido de un directorio


La clase java.io.File contiene varios mtodos para trabajar con directorios. Por ejemplo para listar
las entradas del directorio actual, tendramos que escribir:
1String[] lista = new File(".").list();
Para obtener un conjunto de objetos de tipo File ya construidas en lugar de cadenas, utilice:
1File[] lista = new File(".").listFiles();
Por ejemplo, se puede visualizar el resultado en un ListView.
Tambin puede imprimir los nombres en columnas mltiples o en un TextView ya que puede
conocer el nmero de elementos que hay antes de mostrarlos. Puede omitir el nombre de los
archivos con perodos principales, igual que el comando ls de Unix o imprimir los nombres de
directorios en primer lugar como algunos Administradores de archivos, etc.
Una manera mas fcil de mostrar las entradas del sistema de archivos del directorio es con
list(FilenameFilter ff). FilenameFilter es una interfaz pequea, con un solo mtodo: boolean
accept(File directorio, String nombreArchivo). Suponga que desea obtener una lista de slo los
archivos relacionados con imgenes (*.bmp, *.jpg, *.png, *.gif, etc). Slo tiene que escribir el
mtodo accept() y devolver true para estos archivos y false para los dems.
Cdigo principal:
//Creamos un objeto de tipo Listado de archivos que un mtodo de
1 la clase ser la encargada de devolvernos el listado con los
2 archivos/directorios.
ListadoArchivos listadoArchivos = new ListadoArchivos();
3
4
/*
5
* El mtodo devolverListadoArchivosDirectorios de la
6
7 clase ListadoArchivos, ser la encargada de devolvernos todos los
8 archivos/directorios encontrados
* dentro del directorio indicado, nos devolver los
9
10 nombres en un array de String (cadenas).
11
*/
12
String[] listado =
13 listadoArchivos.devolverListadoArchivosDirectorios("sdcard"/*ruta
14 en la que se buscarn los archivos/directorios, en este caso en
15 la tarjeta de memoria.*/);
16
17
/*
18
* Creamos una variable de tipo StringBuilder para ir
19 concatenando todos los directorios/archivos encontrados.
20
*/
21
StringBuilder listadoCompleto = new StringBuilder();

117

MANUAL BSICO DE ANDROID


//Aqu comprobamos si se han encontrados
archivos/directorios en la bsqueda ya que depender del numero
de elementos que contenga el array.
for (int i=0; i<listado.length;i++){ //Recorremos con un
bucle desde 0 hasta el numero de elementos -1 que contenga el
array.
listadoCompleto.append(listado[i].toString());//Conca
tenamos los archivos/directorios encontrados
listadoCompleto.append("-");//Aadimos tambin un para separar el nombre de los archivos/directorios encontrados
}
Clase ListadoArchivos.java
public class ListadoArchivos {
//Al mtodo le pasamos el directorio donde vamos a buscar
todos los archivos/directorios que tenga.
public static String[]
1 devolverListadoArchivosDirectorios(String directorioPrincipal){
2
/*Para hacer una bsqueda selectiva en el list
3
4 instanciamos a la clase SoloImgenes, que ser la encargada de
5 mostrar los archivos
* que tengan en su nombre los filtros de bsqueda
6
7 indicados
* String[] archivos = new
8
9 File(directorioPrincipal).list(new Filtro());
10
*/
11
12
//Para guardar en el array todos los archivos/directorios
13 encontrados de la ruta indicada sin tener en cuenta el filtro.
14
String[] archivos = new File(directorioPrincipal).list();
15
16
//Devuelve el array de String con los
archivos/directorios encontrados en la bsqueda.
return archivos;
}
}
Clase Filtro.java
1 public class Filtro implements FilenameFilter {
@Override
2
public boolean accept(File directorio, String nombreArchivo) {
3
4
/*Devuelve true si el final del archivo coincide con
5 alguna de las extensiones que le indicamos,
6
* en caso contrario devuelve false y no se tiene en
118

MANUAL BSICO DE ANDROID


cuenta el archivo
*/
if(nombreArchivo.endsWith(".bmp") ||
7
8 nombreArchivo.endsWith(".jpg") || nombreArchivo.endsWith(".png")
9 || nombreArchivo.endsWith(".gif"))
10
return true;
11
12
return false;
}
}
El FilenameFilter podra ser ms flexible, en una aplicacin a gran escala, la lista de archivos
devueltos por el FilenameFilter sera elegido de forma dinmica, posiblemente de forma
automtica, en base a lo que est trabajando. Tambin se puede implementar esto en dilogos de
seleccin de archivos (File Chooser) lo que permite al usuario seleccionar interactivamente uno de
los varios grupos de archivos que se enumeran. Esta es una gran ventaja en la bsqueda de archivos,
ya que se reduce la cantidad de archivos que deben ser examinados.
Para el mtodo de listFiles(), hay una sobrecarga adicional que acepta un FileFilter. La nica
diferencia es que el mtodo accept() del FileFilter se llama con un objeto File, mientras que en
FilenameFilter se llama con una cadena de nombre de archivos.

119

MANUAL BSICO DE ANDROID

28. Obtener informacin de la SDCard


Obtener informacin acerca de la sdcard (tamao ocupado, disponible, total, etc.).
Cdigo:
/*Para obtener el espacion total de la SD card uso StatFs,
* y comoconstructor
Environment.getExternalStorageDirectory().getPath()
*/
StatFs informacionSD = new
StatFs(Environment.getExternalStorageDirectory().getPath());
//Multiplico el tamao de cada bloque de memoria de la
tarjeta por el nmero de bloques que hay
double tamanioTotal = (long) informacionSD.getBlockSize()
* (long) informacionSD.getBlockCount();

1
2
3
4
5
6
7
8
9
//Para obtener el espacio libre en la tarjeta SD.
10
double espacioLibre = (long) informacionSD.getBlockSize()
11 * (long) informacionSD.getFreeBlocks();
12
//Para obtener el espacio ocupado en la tarjeta SD le
restamos al tamao total el espacio libre.
double espacioOcupado = tamanioTotal - espacioLibre;
//Para obtener el tamao en megabytes, tenemos que dividir el
1 resultado por 1048576.
2 double megTotal = tamanioTotal / 1048576;
3
4 double megLibres = espacioLibre / 1048576;
5
6 double megOcupados = espacioOcupado / 1048576;
7
8 //Si se desea mostrar el valor con dos cifras decimales, se puede
9 utilizar un objeto DecimalFormat.
DecimalFormat formaDosDecimales = new DecimalFormat("#.##");

120

MANUAL BSICO DE ANDROID

121

MANUAL BSICO DE ANDROID

29. Base de datos (I): Creacin de una base de


datos SQLite
SQLite es una base de datos relacional muy popular basada en el modelo SQL y se puede utilizar
para almacenar datos de una aplicacin. La forma normal de utilizarlo es extenderla de la clase
SQLiteOpenHelper.
Como hemos dicho anteriormente, para utilizar una base de datos SQLite en una aplicacin
Android, es necesario heredar de la clase SQLiteOpenHelper. Este es un estndar de la clase
Android que ayuda a abrir el archivo de base de datos. Primero se comprueba la existencia del
archivo de base de datos y si existe se abre, de lo contrario, se crea uno.
1public class CreacionBDSQlite extends SQLiteOpenHelper {
El constructor de la clase SQLiteOpenHelper contiene los siguientes argumentos: context, nombre
de la base de datos, objeto CursorFactory y la versin.
Esta sera el cdigo de la clase que creara o actualizara la base de datos:
1 import android.content.Context;
2 import android.database.sqlite.SQLiteDatabase;
3 import android.database.sqlite.SQLiteOpenHelper;
4
5 public class CreacionBDSQlite extends SQLiteOpenHelper {
6
7
//Nombre de la base de datos
8
public static final String NOMBREBD = "bdprueba.sqlite";
9
//Versin de la base de datos
10
public static final int VERSION = 1;
11
//Nombre de la tabla (puede haber tantas como necesitemos)
12
public static final String NOMBRE_TABLA = "tablaprueba";
13
//Campo 1
14
public static final String ID = "id";
15
//Campo 2 (tambin puede haber tantos campos como queramos)
16
public static final String NOMBRE = "nombre";
17
18
//Constructor
19
public CreacionBDSQlite(Context context) {
20
//Aqu le pasamos el contexto, el nombre de la base de
21
22 datos, el cursor que no lo necesitamos y la version de la base de
23 datos.
super(context, NOMBREBD, null, VERSION);
24
}
25
26
//Aqu crearemos la base de datos
27
122

MANUAL BSICO DE ANDROID


@Override
public void onCreate(SQLiteDatabase db) {
/*En la siguiente linea lo que estamos haciendo es crear
la base de datos
* con una tabla llamada tablaprueba
* dos campos uno llamado id que almacenar un nmero
entero,
que
ser clave primaria con autoincremento y que no podr
28
29 ser null
* y otro campo llamado nombre que ser de tipo texto
30
*/
31
db.execSQL("create
table " + NOMBRE_TABLA + "(" + ID + "
32
33 integer primary key autoincrement not null, " + NOMBRE +
34 "text);");
35
//dentro de los parntesis tambin podra ir
36 perfectamente "create table tablaprueba(id integer primary key
37 autoincrement not null, nombre text);" esto y lo anterior es lo
38 mismo
39
}
40
//Aqu se actualizar la base de datos
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
}
}
Y en la clase principal para crear la base de datos tendramos que crear un objeto del mismo tipo
que se llame la clase creadora de la base de datos, en este caso se llama CreacionBDSQLite que
hereda de la clase SQLiteOpenHelper.
El cdigo quedara as:
CreacionBDSQLite crearBD = new CreacionBDSQLite(this);
1
SQLiteDatabase bd = crearBD.getWritableDatabase();//Mtodo de la
2
clase heredada SQLiteOpenHelper para crear la bd
Con esto la base de datos ya est disponible para consultar, actualizar e insertar datos en la misma.
Todo esto se ver en los prximos artculos relacionados con base de datos en Android.
Y ahora para comprobar que toda la creacin ha ido bien , tendremos que explorar el sistema de
archivos y ver que se ha creado la base de datos correctamente. En el dispositivo , la ruta donde se
guardan todas las base de datos SQLite es la siguiente:
/data/data/paquete.java.de.la.aplicacion/databases/nombre_base_datos
Para comprobar que se ha creado satisfactoriamente, vamos al explorador de archivos de eclipse y
vamos a la ruta donde se debera haber alojado la base de datos.
Como podemos comprobar, la base de datos se ha creado correctamente.
Nota : Para consultar el contenido de la base de datos, tenemos dos opciones:
123

MANUAL BSICO DE ANDROID


1- Transferir la base de datos a nuestro PC y consultarla con cualquier administrador de
bases de datos SQLite.
2- Acceder directamente a la consola de comandos del emulador de Android y utilizar los
comandos existentes para acceder y consultar la base de datos SQLite.
Nota 2: Si por cualquier motivo no sabis dnde se encuentra el explorador de archivos,
slo tenemos que hacer click abajo a la izquierda de eclipse en un botn como este:
y nos aparecer una lista en la que aparece el explorador de archivos (File
Explorer).

124

MANUAL BSICO DE ANDROID

30. Base de datos(II): Insertar, modificar y


borrar datos de una base de datos SQLite
En este artculo vamos a ver como insertar datos en una base de datos ya creada de SQLite en
Android. Para ello nos vamos a basar en el artculo anterior en el que se explicaba como crear una
base de datos. Pues bien, sobre esa base de datos que hemos creado anteriormente va a ser sobre la
que vamos a trabajar ahora para insertar registros. Pero antes de nada vamos a decir lo que tenemos
que tener en cuenta a la hora de insertar datos en una tabla SQLite.
Para insertar un dato en la base de datos tendremos que utilizar el mtodo exectSQL() para ejecutar
la consulta de insercin que ser tipo insert into nombre_tabla values (valor1, valor2, valor3,).
Por ejemplo, teniendo en cuenta la base de datos ya creada con la tabla tablaprueba y los campos
id y nombre, para insertar un registro nuevo con nombre Pepito , podramos hacerlo de dos
formas diferentes:
1) A travs del mtodo execSQL() y con la consulta de insercin como en el cdigo siguiente:
1bd.execSQL("INSERT INTO tablaprueba VALUES(null,'Pepito');");
Como podis comprobar, al primer campo que pertenece al id le he pasado null porque es un campo
que se autoincrementa a medida que vamos insertando registros.
2) Con el mtodo insert() y pasando un objeto de tipo ContentValues(), como en el cdigo
siguiente:
1 ContentValues valores = new ContentValues();
2 valores.put("nombre", Pepito);
3 bd.insert("tablaprueba", null, valores);
ContentValues ofrece algo similar a un par clave-valor, donde por ejemplo nombre, sera la clave
que identifica al campo de la tabla y Pepito pertenecera al valor de ese campo que queremos
insertar.
Como podis comprobar, en el segundo caso no le he pasado el contenido del campo id, ya que es
nulo, pero en caso de que hubiera ms campos tendramos que seguir asignando valores.put().
Ejemplo:
1 valores.put("nombre", "Pepito");
2 valores.put("apellidos", "Perz");
3 valores.put("Edad", "36");
En el cdigo de ejemplo he creado un layout con un EditText y un Button para insertar los campos
en la tabla con este mtodo. Imagen de la aplicacin:

125

MANUAL BSICO DE ANDROID

Para el caso de las actualizaciones y el borrado de datos tambin existen estas dos formas de
hacerlo.
Para las actualizaciones:
Por ejemplo cambiamos el nombre Pepito por el nombre Pedro Pikapiedras
Con el mtodo exectSQL():
bd.execSQL("UPDATE tablaprueba SET nombre='Pedro Pikapiedras'
WHERE nombre='Pepito' ");
Con el mtodo update():
1

1 ContentValues valores2 = new ContentValues();


2 valores2.put("nombre", "Pedro Pikapiedras");
3 bd.update("tablaprueba", valores2,"nombre='Pepito'",null);
Para el borrado:
Por ejemplo, borramos el registro de la persona que se llame Pepito.
Con el mtodo exectSQL():
1bd.execSQL("DELETE FROM tablaprueba WHERE nombre='Pepito'");
Con el mtodo delete():
1bd.delete("tablaprueba", "nombre='Pepito'", null);

126

MANUAL BSICO DE ANDROID

31. Base de datos (III):Obtener datos de base


de datos SQLite.
En artculos anteriores sobre base de datos SQLite hemos podido crear una base de datos y guardar
modificar y borrar informacin de la misma. Ahora vamos a ver cmo obtener esos datos ya
introducidos anteriormente para poder trabajar con ellos.
Para hacer esto vamos a tener que utilizar el mtodo query() y trabajar con un tipo de dato especial
llamado Cursor (que ser el encargado de almacenar toda la informacin obtenida en la consulta).
Para realizar este proceso vamos a seguir utilizando la base de datos de los ejemplos artculos con
las mismas tablas.
Como hemos dicho anteriormente para interar sobre los datos de una base de datos requerimos un
objeto de la clase Cursor. Para consultar la base de datos tambin podemos hacerlo a travs de dos
mtodos distintos como hemos visto en artculos anteriores.
Por ejemplo: queremos obtener todos los nombres de los registros de la tabla tablaprueba.
1 Con el mtodo rawQuery() y la consulta:
Cursor contenido = bd.rawQuery("Select nombre from tablaprueba",
null);
2 Con el mtodo query():
1

Cursor contenido = bd.query("tablaprueba", new String[]{"nombre"},


null, null, null, null, null);
Todos los datos obtenidos en la consulta se guardan en el objeto Cursor y para consultarlos,
tenemos que tener en cuenta dos cositas:
1) El ndice de la columna en la consulta, es decir si queremos consultar el nombre solamente, el
ndice sera el nmero 0 pero si queremos obtener el id y el nombre el ndice del id sera el 0 y el
del nombre sera el 1. Ejemplo.
1

Con el mtodo rawQuery():


Cursor contenido = bd.rawQuery("Select id,nombre from
tablaprueba", null);
Con el mtodo query():
1

Cursor contenido = bd.query("tablaprueba", new String[]


{"id","nombre",}, null, null, null, null, null);
Dependiendo de la posicin de los campos en la consulta, el ndice de su posicin ser un nmero u
otro. Hay que tener en cuenta que el primer campo siempre tiene como ndice el nmero 0 el
segundo el nmero 1 y as sucesivamente.
1

2) El tipo de dato que contiene cada campo. Esto es importante, ya que si queremos obtener un
nmero de un campo numrico no lo vamos a hacer igual que si queremos obtener un valor de un
campo de texto.

127

MANUAL BSICO DE ANDROID


Despus de tener en cuenta estos dos aspectos, vamos a procede a obtener el/los campos. Para ello
lo primero que tenemos que hacer es poner lo siguiente:
1 //Ir al primer registro
2 contenido.moveToFirst();
Con esto lo que hacemos es situarnos en el primer registro obtenido para obtener los datos.
Siempre es recomendable realizar antes de este paso un contenido.getCount() (que nos devuelve el
nmero de registros obtenidos ) ya que si no existe ningn registro e intentamos ver el contenido de
un registro, nos dar error.
Ahora vamos a obtener los datos del registro, dependiendo del tipo de dato como he dicho antes se
realizar de una u otra forma. Cdigo:
1 //Para obtener una cadena de texto
2 contenido.getString(indice de la columna);
3 //Para obtener un decimal de tipo float
4 contenido.getFloat(columnIndex)
5 //Para obtener un nmero entero.
6 contenido.getInt(columnIndex)
7 //etc
Entre los parntesis, ir un nmero entero que identificar el ndice de cada columna.
Otros mtodos como moveToFirst() seran:
contenido.moveToNext();//Mueve al siguiente registro
1
contenido.moveToPrevious();//Mueve al registro anterior
2
contenido.moveToNext();//Mueve al primer registro
3
contenido.moveToLast();//Mueve al ltimo registro
4
contenido.moveToPosition(poscion);//Mueve a una posicin en
5
concreto

128

MANUAL BSICO DE ANDROID

32. Base de datos(IV): Trabajar con fecha/hora


en base de datos SQLite
Android integra base de datos SQLite compatible con datos de fecha y hora. Sin embargo a la hora
de obtener estos datos de la base de datos podemos tener problemas, ya que no existe un mtodo
para obtener la fecha y la hora de tipo Cursor.getDate().
Para convertir al formato fecha/hora de SQLite a Java tendremos que utilizar una funcin de
SQLite llamado strftime() para pasar la fecha a milisegundos(Esto parece enrevesado, pero no os
preocupis que es fcil).
Este artculo muestra como almacenar datos de tipo fecha/hora en una base de datos SQLite y
recuperarlos cuando lo necesitemos como objetos de tipo Date de java.util.Date.
La forma de hacerlo es la siguiente:
Primero tenemos que crear una tabla con un campo de tipo timestamp.
db.execSQL("create table " + NOMBRE_TABLA + "(" +
"id INTEGER PRIMARY KEY AUTOINCREMENT NOT
NULL," + //id que almacenar un nmero entero, que ser clave
primaria con autoincremento y que no podr ser null
"nombre TEXT," + //otro campo llamado nombre
1
2 que ser de tipo texto
3
"fecha_ingreso TIMESTAMP NOT NULL DEFAULT
4 current_timestamp );"); //otro campo llamado fecha_ingreso que
sera de tipo TIMESTAMP y almacenar una fecha y hora, no podr
ser null y por defecto(DEFAULT) obtendr automticamente la fecha
y la hora actual(current_timestamp) del ingreso del registro en
formato ao-mes-dia hora:minutos:segundos.
Ahora insertamos un registro en la tabla creada por ejemplo:
//Ahora vamos a insertar un dato para que automticamente asigne
la fecha en formato (ao-mes-dia hora:minutos:segundos)
1
bd.execSQL("INSERT INTO tablaprueba(nombre) VALUES('Pepito')");
2
//Si queremos insertar una fecha en concreto podemos hacerlo por
3
ejemplo as:
4
bd.execSQL("INSERT INTO tablaprueba(nombre,fecha_ingreso)
VALUES('Pepito','2012-03-05 16:39:00')");
Ya tenemos nuestro primer registro (dos registros si hemos realizado las dos formas anteriores) pues
bien, ahora si realizamos una consulta(a travs de la consola SQLite) de los registros que hay en la
tabla, nos debe aparecer una algo as:

Como podis comprobar, nos muestra un listado de todos los registros junto a la fecha y hora. Pues
129

MANUAL BSICO DE ANDROID


bien, ahora queremos que nos muestre todos los registros pero solamente con la fecha. Sera algo
as:

O ajustar la fecha al lunes de la semana siguiente:

Como podis comprobar la fecha del segundo registro no cambia, esto es debido a que ese da del
calendario fue lunes.
O ajustar la fecha al lunes anterior:

Aqu si que cambia la fecha de los dos registros.


Bueno esto es un pequeo ejemplo de como trabajar con fechas a travs de la consola de SQLite y
es solo la punta del iceberg, ya que se pueden hacer muchas ms cosas trabajando con fechas.
Ahora vamos a ver como obtener esas fechas a travs de cdigo java y obtener un objeto de tipo
Date. El truco consiste en utilizar otra de las funciones para fechas de SQLite esta vez se llama
strftime().
Java calcula una fecha contando los milisegundos (Unix trabaja con segundos) que han pasado
desde que se cre Unix (1970), entonces lo que tenemos que hacer es obtener los milisegundos que
han pasado desde 1970 a la fecha que hay en la base de datos para poder trabajar en java con el
objeto Date(), que trabaja con milisegundos. Para hacer esto tenemos que hacer una consulta como
la siguiente:
/*strftime('%s',fecha_ingreso) Obtiene los segundos que han
pasado hasta la fecha insertada en la base de datos desde
1970(creacin de Unix),
1 pero como queremos obtener el tiempo en milisegundos que es con
2 el que trabaja java tenemos que multiplicarlo por 1000 y esto nos
3 devolver un dato de tipo Long
4
5 Entonces lo que hacemos es obtener el id, el nombre y los
6 milisegundos que han pasado hasta la fecha de la base de datos
7 desde 1970 (para calcular la fecha en java)
8 */
9 Cursor contenido = bd.rawQuery("Select id, nombre,
10 (strftime('%s',fecha_ingreso)*1000) from tablaprueba",null);
11
12 contenido.moveToFirst();//Movemos al primer resgistro(si es que
13 hay alguno)
14
long milisegundos = contenido.getLong(2);//Pasamos los
milisegundos de la consulta a una variable de tipo Long

130

MANUAL BSICO DE ANDROID


Date fecha = new Date(milisegundos);//Creamos un objeto de tipo
date que ser la fecha pasandole los milisegundos.
fecha.toString() //Obtenemos un formato de fecha larga, para
hacer con ella lo que necesitemos.

131

MANUAL BSICO DE ANDROID

33.Botones grficos y algo de redes.


Estructura de un proyecto Android:
Lo primero que vamos a hacer es crear un nuevo proyecto Android desde Eclipse (File -> New ->
Android Project). Los datos del proyecto sern los siguientes: Project Name: Ejercicio1 Build
Target: Android 2.2 Application Name: Ejercicio1 Package Name: com.fluproject.Ejercicio1
Create Activity: Main . Una vez tengamos nuestro nuevo proyecto creado nos encontraremos con
la siguiente estructura:

Configuracin de proyecto
A continuacin pasamos a explicar para qu sirven cada una de las carpetas y ficheros generados:
src En esta carpeta se alojarn todas las clases de nuestra aplicacin. Como podemos
observar tenemos una nica clase Main generada automticamente al crear el proyecto. Esta
ser la clase que inicie nuestra futura aplicacin. Si abrimos el fichero Main nos
encontramos con lo siguiente:

132

MANUAL BSICO DE ANDROID

Cdigo inicial
Tenemos una clase Main que hereda de la clase Activity. En nuestro proyecto tendremos tantas
clases como vistas (en el futuro las llamaremos actividades) tenga nuestra aplicacin y todas deben
heredar de Activity. Al heredar de la clase Activity debemos sobrescribir algunos mtodos, unos de
forma obligatoria y otros de forma optativa si nuestra aplicacin lo requiere. Uno de los mtodos
que siempre hay que sobrescribir es el mtodo onCreate. Este mtodo siempre recibe un objeto de
la clase Bundle que hace referencia al estado en el que se encuentra nuestra aplicacin, onCreate
siempre se activar nada ms crearse la aplicacin luego siempre tendremos que darle
funcionalidad. Tenemos la opcin de rescribir ms mtodos que hace referencia a estados en los que
puede entrar nuestra aplicacin como por ejemplo onDestroy (mtodo que se activa cuando salimos
de la aplicacin) u Como podemos observar dentro del mtodo, se hace una llamada a la clase
padre Activity mediante la lnea super.onCreate(savedInstanceState), esta sentencia es
recomendable hacerla siempre que estemos sobrescribiendo un mtodo de una clase padre. Por
ltimo, nos encontramos con la llamada a un mtodo de la clase Activity setContentView que es el
encargado de cargar la interfaz que tendr nuestra actividad, este mtodo recibe una direccin de
memoria R.layout.main que apunta a un fichero xml de cuya estructura hablaremos ms adelante.
res: Vamos a dar un pequeo salto a la carpeta res, s, ya s que me he pasado de largo la
carpeta gen, pero creo que es lo mejor para seguir una explicacin lgica. Esta carpeta va a
ser la encargada de guardar todos los recursos que necesitemos usar en nuestra aplicacin
(imgenes, xml de interfaz, xml de strings, sonidos, audios, etc). Android gestiona los
recursos de una forma muy peculiar, a cada recurso le asigna una direccin y lo define como
un atributo de una clase llamada R (esta clase se encuentra en la carpeta gen), recordis
como cargbamos la interfaz a nuestra actividad? R.layout.main, ms tarde volveremos a
ello.
Si nos fijamos, tenemos tres carpetas llamadas drawable: drawable-hdpi, drawable-mdpi,
drawable-ldpi. En estas carpetas irn alojadas las imgenes de nuestra aplicacin y sus
extensiones (higth, medium y low) hacen referencia al tipo de densidad de pantalla de
nuestro dispositivo o emulador. En principio no es relevante donde coloquemos las imgenes
a no ser que queramos optimizar nuestra aplicacin. Tenemos la opcin de crearnos
una carpeta llamada drawable (sin extensin) donde coloquemos todas nuestras imgenes o
tenemos la opcin de poner las imgenes en cualquiera de las tres, yo personalmente
siempre opto por meterlas en drawable-hdpi. Si abrimos cualquiera de las tres carpetas
133

MANUAL BSICO DE ANDROID


veremos que tenemos una imagen icon.png que corresponde al icono que tendr nuestra
aplicacin.
La siguiente carpeta es layout. En esta carpeta se encuentran todos los ficheros xml que
definen la interfaz de las actividades de nuestra aplicacin. Si abrimos la carpeta nos
encontramos con un fichero main.xml. Este es el fichero encargado de dar una interfaz a
nuestra actividad Main. Si lo abrimos nos encontramos con lo siguiente:

Configurando interfaz
Como podemos observar, disponemos de una paleta llena de componentes para crear interfaces de
usuario, podemos aadir botones, listas, etiquetas de texto, imgenes, etc, simplemente
arrastrndolos a nuestro lienzo. Si pulsamos en la etiqueta main.xml (al lado de Graphical
Layout) podemos observar el xml puro y como se definen y programan todos los componentes.

XML de la interfaz
En este xml de interfaz tenemos definido un LinearLayout que no es ms que una especie de
contenedor que albergar componentes de forma consecutiva, en este caso alberga un componente
de tipo TextView que es una etiqueta de texto. Cada componente (o tag xml) tiene atributos, en el
caso del TextView vemos que tiene un atributo android:text cuyo valor corresponde al contenido
textual que tendr dicha etiqueta de texto. Este valor est almacenado en @string/hello, la variable
@string apunta a un fichero xml strings.xml que contiene todos los strings que vayamos a usar en
nuestra aplicacin.
Seguimos con la carpeta values donde nos encontramos con el fichero strings.xml
mencionado anteriormente. La filosofa de Android es intentar separar lo mximo posible la
parte de la interfaz de la aplicacin con respecto a la lgica y a los datos, luego todas las
cadenas de texto que utilicemos, ya sean nombres de botones, etiquetas de texto, etc,
134

MANUAL BSICO DE ANDROID


deberan ir declarados en este fichero.

Android Resources
De momento, slo hay declarados dos strings: Un string hello que hace referencia al valor de
nuestro TextView, cuyo valor textual es Hello World, Main! y cuyo identificador para poder
referenciarlo en los ficheros xml de interfaz (en este caso en el fichero /res/layout/main.xml) es
hello. Y, por ltimo, un string app_name cuyo valor es el nombre de nuestra aplicacin Ejercicio1 y
que ms adelante veremos dnde se referencia.
Vamos ahora con la carpeta gen, esa que nos hemos saltado anteriormente. Si os acordis
mencion que Android referenciaba todos los recursos (imgenes, audios, xml de interfaz,
etc, guardados en la carpera res ) en una clase llamada R. Si abrimos la carpeta gen y la
clase R podemos comprobarlo nosotros mismos.

135

MANUAL BSICO DE ANDROID

Cdigo
Si tenemos un poquito de experiencia en Java podremos observar como cada subcarpeta de
res est declarada como una clase static y como cada recurso de cada carpeta est declarado
como un atributo static de su correspondiente clase. De esta forma, podemos deducir que se
puede acceder a cualquier recurso de la aplicacin y desde cualquier clase de la forma
R.subdirectorio_res.nombre_recurso. Si recordamos, ya lo hicimos anteriormente para
cargar la interfaz de la actividad main en la clase /src/Main.java con la sentencia
setContentView(R.layout.main).
El ltimo fichero que vamos a explicar de la estructura del proyecto es el
AndroidManifest.xml. En este fichero se reflejan todos los permisos de nuestra aplicacin
(permisos para utilizar wifi, bluetooth, gps, etc) y todas las actividades que vayamos
creando. Cuando empecemos con nuestra primera aplicacin veremos cmo se declaran
determinados permisos.
Nuestra primera aplicacin paso a paso:
Esta primera aplicacin va a ser muy simple. Tendremos una nica actividad Main.java con una
interfaz main.xml que contendr una imagen (banner) y dos botones. Vamos a dar funcionalidad a
cada botn, de forma que al pulsar el primero obtengamos la direccin IP de nuestro dispositivo
mvil en una red wifi y al pulsar el segundo obtengamos la direccin MAC de la interfaz de red
wifi. La aplicacin resultante deber ser exactamente igual a la que os mostramos a continuacin:

136

MANUAL BSICO DE ANDROID

Primera aplicacin Flu Project para Android


Como ya tenemos nuestro proyecto creado vamos a ponernos manos a la obra:
1. Definicin de la interfaz de usuario:
Lo primero que vamos a hacer es definir la GUI de nuestra aplicacin y a darle una apariencia un
poco amigable. Para definir los componentes que tiene la interfaz de nuestra actividad Main
debemos dirigirnos al fichero /res/layout/main.xml. Como observamos en las imgenes de la
aplicacin, debemos incluir un componente imagen ImageView (correspondiente al banner de Flu),
dos etiquetas de texto TextView (Dame mi IP, Dame mi MAC) y dos botones Button. Para ello
abrimos el main.xml, borramos el TextView del helloworld e insertamos los componentes de forma
ordenada. Una vez insertados los componentes comprobamos que el xml resultante tenga esta
apariencia:

Cdigo
Cargamos ahora los recursos de la carpeta resources que os dejamos adjunta al final del post.
Descargamos la carpeta y comprobamos que tenemos tres imgenes (flubanner.png, buttonip.png,
137

MANUAL BSICO DE ANDROID


buttonmac.png). Arrastramos las tres imgenes a la carpeta res de recursos del proyecto,
concretamente a la subcarpeta drawable-hdpi. Una vez cargados los recursos debemos utilizarlos
para cada componente, para ello en main.xml localizamos el componente ImageView y en su
atributo android:src le indicamos que apunte a la imagen flubanner de esta forma
android:src=@drawable/flubanner. En el caso de los Button el proceso cambia un poco, como
nuestras botoneras ya contienen texto debemos quitrselo al componente y ponerle a cada uno su
correspondiente imagen de fondo. Para ello quitamos a los Button su texto de forma que el atributo
text quede as android:text=", despus aadimos nosotros mismos otro atributo background que
apunte a cada botonera respectivamente android:background=@drawable/buttonip (En el
primer Button) android:background=@drawable/buttonmac (En el segundo Button). Una vez
hecho, podemos ir comprobando que los cambios surgen efecto poniendo nuestro main.xml en
modo Graphical Layout.

Creando la interfaz grfica


Esto tiene muy buena pinta, slo nos queda poner los TextView en condiciones y acabamos con el
diseo de la GUI. Os acordis de cmo se definen los strings en Android?, pues vamos al fichero
/res/values/strings y aadimos dos nuevos. Para ello pulsamos Add.. -> String, al primero le
pondremos como nombre string_ip y como valor Dame mi IP:. Aadimos otro ms con nombre
string_mac y con valor Dame mi MAC:. Para finalizar indicamos a los TextView que carguen los
strings
creados
como
ya
sabemos
android:text=@string/string_ip
y
android:text=@string/string_mac.
2. Lgica de la aplicacin:
Una vez terminada la GUI vamos a pasar a darle funcionalidad a los componentes que hemos
definido. Para ello nos vamos a nuestra clase /src/Main.java
Lo primero que vamos a hacer es que nuestros botones respondan a eventos, para ello vamos a
cargar dichos botones como atributos privados de la clase y a ponerles a escuchar eventos:

138

MANUAL BSICO DE ANDROID


Definimos dos atributos privados clase Button (button_ip y button_mac).
Cargamos los componentes Button definidos en la interfaz a dichos atributos mediante el
mtodo findViewById. Este mtodo carga los componentes mediante el id que le pasemos de
cada uno, recordemos que cada componente tiene definido un id como atributo en el xml y
este se refleja en la clase R.
Ponemos a escuchar eventos a los atributos Button. Para que nuestra actividad escuche
eventos nuestra clase Main debe implementar de la clase abstracta OnClickListener. Al
hacerlo vemos que el propio Eclipse nos obliga a aadir y a reescribir el mtodo onClick.
Una vez aadido el mtodo onClick ponemos los Button (button_ip y button_mac) a
escuchar llamando a su atributo setOnClickListener.
De momento, nuestra clase debera tener esta pinta:

Cdigo
Debemos indicarle al mtodo onClick qu botn le ha llamado. Como podemos observar el
mtodo recibe un objeto de clase View, como apunte, debemos concretar que View es la
clase padre de todos los componentes incluido de Button, por lo que nos ser fcil filtrar el
id del componente pulsado. Para filtrar el Button pulsado slo tendremos que hacer una
comparacin del id del Button con un switch o un simple if.

Implementando cdigo
139

MANUAL BSICO DE ANDROID


Ahora es momento de llamar a la interfaz wifi de nuestro dispositivo para obtener tanto la ip
como la mac. Para ello vamos a crearnos dos mtodos privados de clase getMyIP y
getMyMAC que devuelvan un String que mostraremos en forma de alarma con el contenido
correspondiente al pulsar un botn u otro. Dichos mtodos tendrn el siguiente aspecto.

Implementando cdigo
Como podemos ver, ambos mtodos crean un objeto de clase WifiManager y obtienen la
informacin correspondiente. En el caso de la direccin IP hay que recurrir a un mtodo de la clase
Formatter para poder obtenerla en un formato legible.
Una vez definidos los mtodos, slo tenemos que llamarlos en el lugar correspondiente y
mostrar por pantalla la informacin obtenida en forma de alerta Toast.

Implementando cdigo
Ya tenemos toda la funcionalidad definida de nuestra primera aplicacin peeero, esto
ahora mismo no va a funcionar, tenemos que dar permiso a nuestra aplicacin para que
pueda utilizar la interfaz wifi. Abrimos el fichero AndroidManifest.xml, pulsamos en la
pestaa Permissions, Add.. -> Uses Permission y buscamos un permiso de nombre
android.permission.ACCESS_WIFI_STATE. Lo dejamos indicado y ya podemos probar
nuestra primera aplicacin.
Antes de dar por finalizada la entrada hay que resaltar que si probamos la aplicacin mediante el
emulador obtendremos que nuestra ip es la 0.0.0.0 y nuestra mac es null. Esto es debido a que el
acceso a red mediante el emulador se hace a travs de un proxy por lo tanto la forma idnea de
probarla es cargando la aplicacin en un dispositivo Android. Para ello no hay ms que conectarlo
va USB y ejecutar la aplicacin al igual que lo hacemos con el emulador, Eclipse nos reconocer el
telfono automticamente y podremos probarla sin problemas.
140

MANUAL BSICO DE ANDROID

Escner de redes WIFI)


Object 1

Despus de haber aprendido la estructura de un proyecto Android y de haber hecho nuestra primera
aplicacin, vamos ahora a ponernos con cosas un poquito ms serias. En esta tercera entrada,
propondremos la realizacin de una aplicacin que haga una bsqueda de las redes Wifi que
tenemos a nuestro alrededor y que nos muestre sus parmetros, como por ejemplo el ssid y qu
seguridad utilizan. La aplicacin resultante debe tener la siguiente apariencia.

Nos ponemos manos a la obra y creamos un proyecto en Android cuyo nombre sea Ejercicio2,
como paquete com.fluproject.Ejercicio2, su target Android 2.2 y no nos olvidamos de indicarle
que queremos una clase principal llamada Main (si alguien no recuerda como se hace todo este
proceso que le eche un vistazo a las dos entradas anteriores).
Diseando la interfaz de la actividad Main:
Una vez tenemos nuestro proyecto creado nos vamos a poner a modelar la interfaz de la aplicacin.
Vamos a empezar por la primera actividad (clase Main) que, tal y como observamos en la imagen
anterior, tendr como elementos una imagen (ImageView) y un botn con funcionalidad (Button).
Lo primero que debemos hacer es meter las imgenes del archivo resources, que os adjuntamos en
la entrada, a la carpeta /res/drawable-hdpi/. Vamos ahora al fichero que define la interfaz de
nuestra actividad Main main.xml y lo dejamos con esta pinta:

141

MANUAL BSICO DE ANDROID

Como podemos ver en el cdigo del main.xml, tenemos un LinearLayout principal que contendr
la imagen del banner de fluproject y otro LinearLayout. El segundo LinearLayout contendr un
TextView con el texto Escanea Wifi y un Button con forma de imagen. El motivo de separar la
interfaz en dos LinearLayout es conseguir darle gravedad slo al segundo LinearLayout
(android:gravity=center) de forma que slo se centren en la pantalla el TextView y el Button.
Una vez definida la interfaz, pasamos ahora a darle lgica.
Definiendo la funcionalidad de la actividad Main:
La funcionalidad de esta actividad es bastante sencilla, exactamente igual que la que utilizamos el
otro da para nuestra primera aplicacin. La nica diferencia es que aqu, adems de mostrar un
mensaje de texto, crearemos una nueva actividad y la mostraremos. A modo de recordatorio, las
actividades (Activity) se corresponden con las pantallas que tendr nuestra aplicacin. En la
navegacin por pantallas, Android trata las actividades mediante una pila de actividades, de
forma que siempre estaremos visualizando la actividad superior de dicha pil, la que se encuentre
en la cima. Cuando arranca una nueva actividad siempre se pone en la cima de la pila, en primer
plano. Cuando pulsamos el botn atrs estaremos realizando una accin equivalente a
desapilar , cerraremos la actividad actual y mostraremos la actividad que est en la cima de la
pila. Si no hay ninguna actividad ms, saldremos de la aplicacin.

142

MANUAL BSICO DE ANDROID

Volviendo a la lgica de la actividad Main, tendremos una clase Main.java con esta apariencia:

Como vemos implementamos de OnClickListener


para escuchar eventos del Button que hemos definido para escanear. En el mtodo onClick vemos
que al pulsar el Button (con id button1 en nuestro main.xml) sacamos una alerta textual por
pantalla con contenido Escaneando redes wifi y que adems creamos una nueva actividad por
medio de la clase Intent:
Intent
wifiList
startActivity(wifiList);

new

Intent(this,

Wifilist.class);

Al constructor de la clase Intent, clase responsable de crear la nueva actividad, le indicamos la


actividad origen y la actividad destino que queremos que se muestre a continuacin, que ser la
actividad Wifilist, la cual todava no hemos definido ni como actividad ni como clase. Para definir
la actividad Wifilist tenemos que crearnos una nueva actividad que se compondr de una clase
Wifilist.java y de un fichero xml wifilist.xml (por convenio de nombres vamos a intentar siempre
llamar a la clase de la actividad y a su fichero xml igual, salvo que la primera letra del nombre de la
clase ser mayscula y la primera letra del nombre del fichero xml ser minscula):
Creamos una nueva clase en nuestro paquete com.fluproject.Ejercicio2 de la siguiente
forma: Botn derecho del ratn sobre el paquete, New > Class, en SuperClass escribimos
143

MANUAL BSICO DE ANDROID


android.app.Activity , le damos un nombre Wifilist y a aceptar. Una vez creada, pinchamos
con el botn derecho del ratn sobre la clase, Source -> Override/Implement Methods y
seleccionamos el mtodo onCreate(Bundle).
Una vez creada la clase creamos su fichero wifilist.xml, para ello nos vamos a la carpeta
/res/layout pulsamos el botn derecho del ratn y seleccionamos New->Android XML
File, le damos como nombre wifilist y finalizamos.
Una vez creada la actividad debemos definirla en el fichero AndroidManifest.xml.
Abrimos dicho fichero, nos vamos al apartado Application y bajamos a la seccin
Application Nodes. Ah podemos observar como tenemos solamente una actividad
declarada, la actividad Main. Para declarar la actividad Wifilist pulsamos Add ->
Activity y rellenamos sus propiedades a la derecha. Slo pondremos el nombre de la
actividad Wifilist y comprobamos que se cambia en el cajetn de Application Nodes.
Diseando la interfaz de la actividad Wifilist:
Como pudimos observar en la imagen del principio, nuestra segunda pantalla tendr una lista con
todas las redes wifi que nuestro mvil haya encontrado. Luego el fichero xml que define la
actividad Wifilist wifilist.xml tendr la siguiente apariencia:

Como podemos observar tiene un LinearLayout con un nico componente ListView.


Cada elemento de la lista tambin debe tener un aspecto, en nuestro caso no van a ser elementos
simples, como podemos observar en la imagen del principio tendremos ms de un elemento en cada
item de la lista (ssid y seguridad), adems estos elementos varan en tamao y en color luego habr
que hacer otro proceso de definicin antes de ponernos con la lgica. Este proceso pasa por
definirnos otro fichero xml, de la misma forma que nos definimos el anterior, que contendr el
aspecto de cada item de la lista, el fichero se llamar elementitems.xml y tendr este aspecto:

144

MANUAL BSICO DE ANDROID

Como podemos ver, disponemos de un LinearLayout que alberga dos TextView, el primero hace
referencia al ssid de la red y el segundo a la seguridad que tiene configurada. Y con esto ya
tendramos diseada la interfaz de nuestra actividad Wifilist.
Definiendo la funcionalidad de la actividad Wifilist:
Lo primero que vamos a hacer para definir la funcionalidad de Wifilist es crearnos una clase bsica
en Java llamada Element. Como hemos dicho anteriormente nuestra lista no va a contener items
simples sino que contendr items compuestos por dos TextView, esto debemos modelarlo en una
clase. La clase Element estar ubicada en el paquete com.fluproject.Ejercicio2 y tendr la
siguiente apariencia:

145

MANUAL BSICO DE ANDROID

En la clase Element tendremos dos atributos uno ser title que har referencia en un futuro al SSID
de la red, y el otro subtitle que har referencia a la seguridad de la red. Adems tendremos dos
mtodos para obtener tanto el atributo title como el subtitle.
A continuacin, vamos a intentar explicar el cdigo que debe tener la clase Wifilist.java en tres
partes para intentar aclarar la funcionalidad.

146

MANUAL BSICO DE ANDROID

Empezaremos nuestro cdigo Wifilist.java definiendo tres atributos de clase: nets -> array de
objetos Element que se encargar de guardar las redes descubiertas y posteriormente pasarle la
informacin a un ArrayAdapter para que la lista pueda ser construida; manWifi -> Objeto de la
clase WifiManager que nos permitir acceder a la interfaz Wifi de nuestro dispositivo mvil y
utilizar su funcionalidad; wifiList -> Objeto de la clase List donde guardaremos los Strings en bruto
resultado de un escner wifi.
Punto 1: En este punto llamamos a la interfaz wifi de nuestro dispositivo mvil y guardamos el
resultado en el atributo manWifi. Posteriormente realizamos el escner de redes mediante el
mtodo startScan() de la clase WifiManager y por ltimo guardamos el resultado en bruto en
nuestro atributo wifiList por medio del mtodo getScanResults().
Punto 2: En este punto vamos a parsear la informacin que nos interesa del resultado del escner
guardado en bruto en el atributo wifiList. Recorreremos la lista wifiList, rescataremos la
informacin que nos interesa de cada red (ssid y security) e iremos creando objetos Element y
guardndolos en nuestro atributo nets. Una vez parseada y guardada toda la informacin resultante
del escner cargaremos a nuestra actividad la interfaz correspondiente wifilist.xml. Despus
crearemos un array adaptador AdapterElements de objetos Elements para nuestra lista que
definiremos en el Punto 3.
Punto 3: Nos definimos una clase llamada AdapterElements que herede de ArrayAdapter. Esta
clase nos va a servir para construir nuestra lista a partir del atributo nets. Esta clase tendr un slo
atributo context que indicar el contexto donde se va a construir la lista, en la actividad presente.
147

MANUAL BSICO DE ANDROID


Como podemos observar AdapterElements tiene un constructor de clase que llama a su clase padre
ArrayAdapter y un mtodo getView. El mtodo getView es el que se encarga de visualizar los
elementos del atributo nets en forma de ListView. getView ser llamado tantas veces como
posiciones tenga nuestro atributo nets, adems getView nos proporciona un parmetro position que
nos servir de ndice para obtener toda la informacin de nets. Dentro de getView formamos nuestro
item cargando el fichero elementitems.xml mediante el mtodo inflate de la clase LayoutInflate,
despus slo manipulamos el contenido textual de los TextView en funcin del valor de nets y
listo!
Ya tenemos nuestra aplicacin completamente diseada, slo nos queda un pequeo detalle, decirle
al AndroidManifest.xml que nos deje utilizar el wifi de nuestro dispositivo mvil. Para ello nos
vamos al fichero y aadimos los siguientes permisos tal y como explicamos en la entrada anterior:
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE

148

MANUAL BSICO DE ANDROID

Escner de redes WIFI


Object 2

Despus de haber aprendido la estructura de un proyecto Android y de haber hecho nuestra primera
aplicacin, vamos ahora a ponernos con cosas un poquito ms serias. En esta tercera entrada,
propondremos la realizacin de una aplicacin que haga una bsqueda de las redes Wifi que
tenemos a nuestro alrededor y que nos muestre sus parmetros, como por ejemplo el ssid y qu
seguridad utilizan. La aplicacin resultante debe tener la siguiente apariencia.

Nos ponemos manos a la obra y creamos un proyecto en Android cuyo nombre sea Ejercicio2,
como paquete com.fluproject.Ejercicio2, su target Android 2.2 y no nos olvidamos de indicarle
que queremos una clase principal llamada Main (si alguien no recuerda como se hace todo este
proceso que le eche un vistazo a las dos entradas anteriores).
Diseando la interfaz de la actividad Main:
Una vez tenemos nuestro proyecto creado nos vamos a poner a modelar la interfaz de la aplicacin.
Vamos a empezar por la primera actividad (clase Main) que, tal y como observamos en la imagen
anterior, tendr como elementos una imagen (ImageView) y un botn con funcionalidad (Button).
Lo primero que debemos hacer es meter las imgenes del archivo resources, que os adjuntamos en
la entrada, a la carpeta /res/drawable-hdpi/. Vamos ahora al fichero que define la interfaz de
nuestra actividad Main main.xml y lo dejamos con esta pinta:

149

MANUAL BSICO DE ANDROID

Como podemos ver en el cdigo del main.xml, tenemos un LinearLayout principal que contendr
la imagen del banner de fluproject y otro LinearLayout. El segundo LinearLayout contendr un
TextView con el texto Escanea Wifi y un Button con forma de imagen. El motivo de separar la
interfaz en dos LinearLayout es conseguir darle gravedad slo al segundo LinearLayout
(android:gravity=center) de forma que slo se centren en la pantalla el TextView y el Button.
Una vez definida la interfaz, pasamos ahora a darle lgica.
Definiendo la funcionalidad de la actividad Main:
La funcionalidad de esta actividad es bastante sencilla, exactamente igual que la que utilizamos el
otro da para nuestra primera aplicacin. La nica diferencia es que aqu, adems de mostrar un
mensaje de texto, crearemos una nueva actividad y la mostraremos. A modo de recordatorio, las
actividades (Activity) se corresponden con las pantallas que tendr nuestra aplicacin. En la
navegacin por pantallas, Android trata las actividades mediante una pila de actividades, de
forma que siempre estaremos visualizando la actividad superior de dicha pil, la que se encuentre
en la cima. Cuando arranca una nueva actividad siempre se pone en la cima de la pila, en primer
plano. Cuando pulsamos el botn atrs estaremos realizando una accin equivalente a
desapilar , cerraremos la actividad actual y mostraremos la actividad que est en la cima de la
pila. Si no hay ninguna actividad ms, saldremos de la aplicacin.

150

MANUAL BSICO DE ANDROID

Volviendo a la lgica de la actividad Main, tendremos una clase Main.java con esta apariencia:

Como vemos implementamos de OnClickListener


para escuchar eventos del Button que hemos definido para escanear. En el mtodo onClick vemos
que al pulsar el Button (con id button1 en nuestro main.xml) sacamos una alerta textual por
pantalla con contenido Escaneando redes wifi y que adems creamos una nueva actividad por
medio de la clase Intent:
Intent
wifiList
startActivity(wifiList);

new

Intent(this,

Wifilist.class);

Al constructor de la clase Intent, clase responsable de crear la nueva actividad, le indicamos la


actividad origen y la actividad destino que queremos que se muestre a continuacin, que ser la
actividad Wifilist, la cual todava no hemos definido ni como actividad ni como clase. Para definir
la actividad Wifilist tenemos que crearnos una nueva actividad que se compondr de una clase
Wifilist.java y de un fichero xml wifilist.xml (por convenio de nombres vamos a intentar siempre
llamar a la clase de la actividad y a su fichero xml igual, salvo que la primera letra del nombre de la
clase ser mayscula y la primera letra del nombre del fichero xml ser minscula):
Creamos una nueva clase en nuestro paquete com.fluproject.Ejercicio2 de la siguiente
forma: Botn derecho del ratn sobre el paquete, New > Class, en SuperClass escribimos
151

MANUAL BSICO DE ANDROID


android.app.Activity , le damos un nombre Wifilist y a aceptar. Una vez creada, pinchamos
con el botn derecho del ratn sobre la clase, Source -> Override/Implement Methods y
seleccionamos el mtodo onCreate(Bundle).
Una vez creada la clase creamos su fichero wifilist.xml, para ello nos vamos a la carpeta
/res/layout pulsamos el botn derecho del ratn y seleccionamos New->Android XML
File, le damos como nombre wifilist y finalizamos.
Una vez creada la actividad debemos definirla en el fichero AndroidManifest.xml.
Abrimos dicho fichero, nos vamos al apartado Application y bajamos a la seccin
Application Nodes. Ah podemos observar como tenemos solamente una actividad
declarada, la actividad Main. Para declarar la actividad Wifilist pulsamos Add ->
Activity y rellenamos sus propiedades a la derecha. Slo pondremos el nombre de la
actividad Wifilist y comprobamos que se cambia en el cajetn de Application Nodes.
Diseando la interfaz de la actividad Wifilist:
Como pudimos observar en la imagen del principio, nuestra segunda pantalla tendr una lista con
todas las redes wifi que nuestro mvil haya encontrado. Luego el fichero xml que define la
actividad Wifilist wifilist.xml tendr la siguiente apariencia:

Como podemos observar tiene un LinearLayout con un nico componente ListView.


Cada elemento de la lista tambin debe tener un aspecto, en nuestro caso no van a ser elementos
simples, como podemos observar en la imagen del principio tendremos ms de un elemento en cada
item de la lista (ssid y seguridad), adems estos elementos varan en tamao y en color luego habr
que hacer otro proceso de definicin antes de ponernos con la lgica. Este proceso pasa por
definirnos otro fichero xml, de la misma forma que nos definimos el anterior, que contendr el
aspecto de cada item de la lista, el fichero se llamar elementitems.xml y tendr este aspecto:

152

MANUAL BSICO DE ANDROID

Como podemos ver, disponemos de un LinearLayout que alberga dos TextView, el primero hace
referencia al ssid de la red y el segundo a la seguridad que tiene configurada. Y con esto ya
tendramos diseada la interfaz de nuestra actividad Wifilist.
Definiendo la funcionalidad de la actividad Wifilist:
Lo primero que vamos a hacer para definir la funcionalidad de Wifilist es crearnos una clase bsica
en Java llamada Element. Como hemos dicho anteriormente nuestra lista no va a contener items
simples sino que contendr items compuestos por dos TextView, esto debemos modelarlo en una
clase. La clase Element estar ubicada en el paquete com.fluproject.Ejercicio2 y tendr la
siguiente apariencia:

153

MANUAL BSICO DE ANDROID

En la clase Element tendremos dos atributos uno ser title que har referencia en un futuro al SSID
de la red, y el otro subtitle que har referencia a la seguridad de la red. Adems tendremos dos
mtodos para obtener tanto el atributo title como el subtitle.
A continuacin, vamos a intentar explicar el cdigo que debe tener la clase Wifilist.java en tres
partes para intentar aclarar la funcionalidad.

154

MANUAL BSICO DE ANDROID

Empezaremos nuestro cdigo Wifilist.java definiendo tres atributos de clase: nets -> array de
objetos Element que se encargar de guardar las redes descubiertas y posteriormente pasarle la
informacin a un ArrayAdapter para que la lista pueda ser construida; manWifi -> Objeto de la
clase WifiManager que nos permitir acceder a la interfaz Wifi de nuestro dispositivo mvil y
utilizar su funcionalidad; wifiList -> Objeto de la clase List donde guardaremos los Strings en bruto
resultado de un escner wifi.
Punto 1: En este punto llamamos a la interfaz wifi de nuestro dispositivo mvil y guardamos el
resultado en el atributo manWifi. Posteriormente realizamos el escner de redes mediante el
mtodo startScan() de la clase WifiManager y por ltimo guardamos el resultado en bruto en
nuestro atributo wifiList por medio del mtodo getScanResults().
Punto 2: En este punto vamos a parsear la informacin que nos interesa del resultado del escner
guardado en bruto en el atributo wifiList. Recorreremos la lista wifiList, rescataremos la
informacin que nos interesa de cada red (ssid y security) e iremos creando objetos Element y
guardndolos en nuestro atributo nets. Una vez parseada y guardada toda la informacin resultante
del escner cargaremos a nuestra actividad la interfaz correspondiente wifilist.xml. Despus
crearemos un array adaptador AdapterElements de objetos Elements para nuestra lista que
definiremos en el Punto 3.
Punto 3: Nos definimos una clase llamada AdapterElements que herede de ArrayAdapter. Esta
clase nos va a servir para construir nuestra lista a partir del atributo nets. Esta clase tendr un slo
atributo context que indicar el contexto donde se va a construir la lista, en la actividad presente.
155

MANUAL BSICO DE ANDROID


Como podemos observar AdapterElements tiene un constructor de clase que llama a su clase padre
ArrayAdapter y un mtodo getView. El mtodo getView es el que se encarga de visualizar los
elementos del atributo nets en forma de ListView. getView ser llamado tantas veces como
posiciones tenga nuestro atributo nets, adems getView nos proporciona un parmetro position que
nos servir de ndice para obtener toda la informacin de nets. Dentro de getView formamos nuestro
item cargando el fichero elementitems.xml mediante el mtodo inflate de la clase LayoutInflate,
despus slo manipulamos el contenido textual de los TextView en funcin del valor de nets y
listo!
Ya tenemos nuestra aplicacin completamente diseada, slo nos queda un pequeo detalle, decirle
al AndroidManifest.xml que nos deje utilizar el wifi de nuestro dispositivo mvil. Para ello nos
vamos al fichero y aadimos los siguientes permisos tal y como explicamos en la entrada anterior:
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE

156

MANUAL BSICO DE ANDROID

Crackeando redes Wifi


Object 3

En esta cuarta entrada del curso de introduccin a Android, veremos como podemos aprovechar el
Ejercicio2, que implementamos en la entrada anterior, para realizar un pequeo crackeador de redes
Wifi del estilo WLAN_XXXX o JAZZTEL_XXXX cuya seguridad sea WPA. La aplicacin
resultante deber tener la siguiente apariencia.

La aplicacin resultante har un escner de las redes Wifi que tengamos a nuestro alrededor y nos
mostrar en una lista las redes encontradas con una pequea descripcin de cada una. Cuando
seleccionemos una red de la lista podremos observar una descripcin ms detallada de ella,
pudiendo obtener tambin su clave si la red es del estilo WLAN_XXXX o JAZZTEL_XXXX.
Vamos entonces a crearnos un nuevo proyecto cuyo nombre sea FluWifiCracker, como paquete
com.fluproject.FluWifiCracker, su target Android 2.2 y como clase principal Main (si alguien no
recuerda como se hace todo este proceso que le eche un vistazo a las dos primeras entradas).
Diseando la interfaz de la actividad Main:
Nuestra primera actividad Main ser idntica a la propuesta en el Ejercicio2 de la entrada anterior.
Recordamos que esta actividad consta de un ImageView que se corresponde con el banner de Flu
Project y de un Button con imagen de fondo. Podemos entonces copiarnos el mismo fichero
main.xml que utilizamos en el Ejercicio2 a nuestra carpeta /res/layout y sustituirlo por el
existente. Tampoco se nos debe olvidar hacer lo propio con los recursos de la imagen del banner y
la imagen del botn.

157

MANUAL BSICO DE ANDROID


Definiendo la funcionalidad de la actividad Main:
La funcionalidad de esta actividad tambin ser exactamente igual a la propuesta en el Ejercicio2.
Simplemente necesitamos capturar el evento del botn de escner implementando la interfaz
OnClickListener y reescribiendo el mtodo OnClick. Cuando entremos en el mtodo activaremos
nuestro mdulo Wifi para realizar el escner de redes y pasaremos a una nueva actividad donde se
muestra una lista con todas las redes encontradas.
Diseando la interfaz de la actividad Wifilist:

El diseo de esta actividad cambia un poco con respecto al anterior ejercicio. En este caso hemos
querido dar ms informacin de cada red y aadirle adems una imagen que nos indique la potencia
de seal recibida de cada una. El fichero elements.xml que define cada item de la lista tendra el
siguiente aspecto:

En vez de utilizar un LinearLayout como contenedor de objetos, hacemos uso ahora del
contenedor TableLayout que alinea vistas en forma de tabla. Nuestro TableLayout estar
compuesto de filas llamadas TableRow. Cada TableRow tendr dos objetos, la primera y la
segunda fila tendrn dos TextView consecutivos y la ltima fila tendr un TextView y un
ImageView.
Definiendo la funcionalidad de la actividad Wifilist:
158

MANUAL BSICO DE ANDROID


La funcionalidad de esta actividad es prcticamente igual que la del Ejercicio2 salvo dos aspectos
nuevos: El manejador de eventos de la lista y la transferencia de informacin entre actividades.

Para manejar eventos de la lista tenemos que implementar la interfaz OnItemClickListener (1) y
poner la instancia de ListView a escuchar mediante el mtodo setOnItemClickListener (2). Al
implementar la interfaz OnItemClickListener tendremos que rescribir el mtodo onItemClick.

Al cargar el aspecto de cada item de la lista, en el mtodo getView, se ha introducido un icono que
indica la potencia de seal recibida por cada red descubierta. Hemos introducido una comparacin
del valor numrico de la seal y hemos asociado un icono de cobertura para distintos rangos (3).
Volviendo a la captura de eventos de la lista, al implementar de OnItemClickListener rescribimos
el mtodo onItemClick (4). Cuando rescribimos el mtodo observamos que disponemos de un
argumento position. Dicho argumento nos servir para indexar en nuestro array de redes y sacar
toda su informacin para posteriormente envirsela a una nueva actividad.
Vamos a definirnos una nueva clase llamada WifiInfo.java. Para pasar elementos a la actividad que
representa dicha clase nos vamos a apoyar en el mtodo putExtra que nos ofrece la clase Intent.
Dicho mtodo enva un objeto representado por un tag textual para que luego pueda ser recogido en
159

MANUAL BSICO DE ANDROID


la clase destino. Haremos tantos putExtra como informacin queramos enviar a la actividad
WifiInfo que se encargar de mostrar toda la informacin detallada de la red elegida (y si puede la
clave

Diseando la interfaz de la actividad WifiInfo:

Esta actividad tendr un diseo muy sencillo donde volveremos a apoyarnos en un TableLayout
como contenedor de objetos con el fin de alinearlos de forma ordenada. A continuacin mostramos
el fichero wifiinfo.xml que define el diseo de la actividad.

160

MANUAL BSICO DE ANDROID

161

MANUAL BSICO DE ANDROID


Definiendo la funcionalidad de la actividad WifiInfo:
Esta actividad tendr como cometido recoger los valores que le enva su actividad padre,
representarlos y, si la red es crackeable, mostrarnos su clave.
A continuacin se muestra el cdigo de la clase WifiInfo.java y se explican las partes ms
importantes del mismo.

Para recoger la informacin procedente de la actividad WifiList se obtienen los extras de la


presente actividad. Para ello hacemos uso del mtodo getExtras. Si hemos obtenido informacin
tenemos que parsearla usando los mismos tags que utilizamos para enviarla (1).
Una vez que tenemos toda la informacin parseada y guardada en objetos en memoria la mostramos
por pantalla indicndosela a los objetos que definimos en la fase de diseo de esta actividad.
Comprobamos despus si la red es crackeable, para ello comprobamos si la red es del tipo
WLAN_XXXX o JAZZTEL_XXXX. Si es as, creamos una instancia a la clase KeyGenerator
(por cortesa de dolphinziyo) y llamamos a su mtodo calcularClave pasndole los cuatro ltimos
dgitos del ESSID y el BSSID en maysculas. Este mtodo sustituye las cuatro ltimas letras del
BSSID por las cuatro ltimas letras del ESSID, posteriormente se le aade a la cadena el BSSID
original. Finalmente, al principio de la cadena aade la palabra bcgbghgg, calcula la suma MD5
de la cadena entera y se queda con los 20 primeros dgitos que corresponden a la clave de la red (ver
entrada http://www.flu-project.com/crackear-wpa-rotura-de-wlan_xxxx.html).

162

Вам также может понравиться