Está en la página 1de 210

1 - Instalacin de Android

El objetivo de este tutorial es iniciarse en la programacin de Android. Se requieren conceptos


previos de programacin en Java. Se busca ir conociendo los rudimentos bsicos de la
programacin en Android presentando los conceptos con ejercicios resueltos e invitando a la
resolucin de otros problemas propuesto.

Descarga de herramientas necesarios para programar para Android.


1 - Primero debemos instalar el compilador de Java y la mquina virtual. Estas herramientas las
podemos descargar de:
Java SE Development Kit (JDK).
2 - El segundo paso es la descarga del editor Eclipse, lo hacemos del sitio:
Eclipse IDE for Java Developers.
3 - El tercer paso es descargar el SDK Android, lo podemos descargar de:
SDK de Android
El archivo que descargaremos es el zip: android-sdk_rxx-windows. (donde xx es el nmero de la
ltima versin)
Descomprimimos el archivo y lo ubicamos en la raiz de la unidad c\:, luego de descomprimir
tenemos una carpeta llamada: c:\android-sdk-windows
4 - El cuarto paso es ejecutar el programa: c:\android-sdk-windows\SDK Manager.exe que se
encuentra en la carpeta que acabamos de descomprimir el SDK de Android.
Aparece esta ventana (presionamos cancelar con el objetivo de seleccionar una AVD (Android
Virtual Device) y no tener que esperar una eternidad descargando todas las versiones de AVD):

Instalaremos en primera instancia la versin del SDK 2.3.3 (la lnea 2 est orientada al desarrollo
de aplicaciones para celulares y la lnea 3 est orientada a tablet). Seleccionamos Available
packages y luego del lado derecho solo dejamos tildado la versin del SDK 2.3.3 (ms adelante

podemos instalar otras versiones de Android) Por ltimo procedemos a presionar el botn "Install
Selected":

Aparece un dilogo donde nos informa el progreso de instalacin:

Ahora ya podemos cerrar la aplicacin del SDK Manager.exe.


5 - Instalacin del plugin de Eclipse para trabajar con Android.
Para instalar el plugin ingresamos al entorno Eclipse. Luego desde el men de opciones: Help->
Install New Software, aparece el siguiente dilogo, presionamos el botn add y disponemos la url
donde se encuentra el plugin:

En Location disponemos la url: https://dl-ssl.google.com/android/eclipse/


Tildamos "Developer Tools", presionamos seguidamente el botn "Next" dos veces hasta que
aparece la ventana donde tenemos que aceptar los "Trminos y Condiciones" y presionamos el
botn "Finish"
Al finalizar la instalacin del plugin se reinicia el Eclipse para que se instale completamente.
6 - El siguiente paso que debemos efectuar para poder empezar a desarrollar aplicaciones para
Android es configurar el SDK:
Para esto nos dirigimos a la opcin Windows -> Preferences donde aparece el siguiente dilogo:

Seleccionamos la carpeta donde descomprimimos SDK de Android y presionamos el botn


"Apply"
7 - Por ltimo debemos crear el AVD (Android Virtual Device) para ello nos dirigimos a la opcin
Window -> Android SDK and AVD Manager.
En este dilogo debemos crear el emulador de Android (presionamos el botn New...):

En este dilogo asignamos un nombre a nuestro AVD, lo enlazamos con la versin de SDK
respectivo, fijamos un tamao al SD Card:

Ya tenemos todo configurado para el desarrollo de aplicaciones Android.

2 - Pasos para crear el primer proyecto


Android
Ya tenemos todo lo necesario instalado para implementar el primer proyecto. Desde el men de
opciones: File -> New -> Android Project

En este dilogo especificamos el nombre del proyecto y el nombre del paquete java donde se
almacenarn los archivos java que creemos.
El plugin de Android nos genera todos los directorios y archivos bsicos para iniciar nuestro
proyecto:

No haremos en este momento un anlisis del significado y objetivo de cada uno de estos
directorios y archivos generados, sino a medida que avancemos con este curso iremos viendo en
forma puntual y profunda.
La interfaz visual de nuestro programa para Android se almacena en un archivo XML en la
carpeta res, subcarpeta layout y el archivo se llama main.xml. En esta carpeta tenemos creada
nuestra primer pantalla.
Al seleccionar este archivo el plugin de Android nos permite visualizar el contenido en "vista de
diseo (Graphical Layout)":

Si seleccionamos la otra pestaa podemos visualizar el archivo main.xml en formato de texto:

El plugin Android ya insert un control de tipo LinealLayout que especifica que todos los controles
visuales que se inserten se dispondrn uno debajo del otro ya que la propiedad orientation est
inicializada con el valor vertical (orientation="vertical")
Ya veremos que podemos modificar todo este archivo para que se adapte a la aplicacin que
queremos desarrollar.
Luego contenido en el control LinealLayout hay otro control de tipo TextView que es bsicamente
una etiqueta o label que mostrar en pantalla el valor almacenado en la propiedad text.

Podemos modificar directamente el archivo xml o en "vista de diseo" modificar los valores de las
propiedades. Elegimos nuevamente la pestaa "Graphical Layout" y seleccionamos el TextView
con el mouse y presionamos el botn derecho del mouse, buscamos la propiedad text y la
cambiamos por la etiqueta: "Mi primer programa para Android":

Con esto ya podemos probar nuestra primer aplicacin para un dispositivo Android. Presionamos
Run desde el men o el cono respectivo. Seleccionamos que se ejecute como aplicacin
"Android Application". Ahora se abrir el AVD(Android Virtual Device) esto tarda bastante tiempo,
es muy importante recordar que luego de ver ejecutndose el programa NO debemos cerrar el
AVD para que la prxima ejecucin se inicie ms rpido (podemos minimizar el AVD)
Ahora podemos ver nuestra primer aplicacin corriendo en el emulador de Android:

Como hemos visto el plugin de Eclipse nos genera en forma automtica todas las carpetas y
archivos bsicos que necesitamos en un principio. En el siguiente concepto podremos empezar a
programar verdaderamente. El nico objetivo de este ejercicio es recordar los pasos para crear
un proyecto.
Final del proyecto001.

3 - Captura del clic de un botn


Problema:

Realizar la carga de dos nmeros en controles de tipo EditText. Mostrar un mensaje que solicite
la carga de los valores. Disponer un Button para sumar los dos valores ingresados. Mostrar el
resultado en un tercer TextView.
La interfaz visual debe quedar algo semejante a esto:

Veamos paso a paso como creamos la interfaz visual de nuestro programa. Primero borramos el
TextView que aparece por defecto cuando se crea un proyecto con el plugin de Android. Ahora
desde la ventana "Palette" seleccionamos de la pestaa "Form Widgets" el control "TextView" y lo
arrastramos a la ventana de diseo de nuestra interfaz:

Ahora lo seleccionamos y presionamos el botn derecho del mouse sobre la componente y


especificamos la propiedad text (como habamos visto anteriormente) disponemos el texto
"Ingrese el primer valor:":

Tambin vamos a especificar la propiedad "Id", la misma parece primera en el men contextual:

Le asignaremos como nombre a este objeto: tv1 (recordemos que se trata de un objeto de la
clase TextView)

Ahora de la paleta de componentes seleccionamos la pestaa "Text Fields" y arrastramos el


primero (el que tiene la etiqueta abc)

Presionando el botn derecho sobre el control EditText configuramos la propiedad Id... con el
nombre et1 (este nombre haremos referencia posteriormente desde Java)

Efectuamos los mismos pasos para crear el segundo TextView y EditText (inicializamos las
propiedades respectivas) Definimos los id con los nombres tv2 y et2, el resultado visual debe ser
algo semejante a esto:

De la pestaa "Form Widgets" arrastramos un control de tipo "Button":

Inicializamos la propiedad text con el texto "Sumar" y la propiedad id la dejamos con el valor ya
creado llamado "button1".

Para terminar con nuestra interfaz visual arrastramos un tercer objeto de tipo TextView y
definimos la propiedad id con el valor "tv3" y la propiedad text con el texto "resultado",
recordemos que la interfaz final debe ser semejante a esta:

Si en este momento ejecutamos la aplicacin aparece la interfaz visual correctamente pero


cuando presionemos el botn no mostrar la suma.
Hasta ahora hemos trabajado solo con el archivo xml (main.xml) donde se definen los controles
visuales de la ventana que estamos creando.

Abrimos seguidamente el archivo Proyecto002Activity.java que lo podemos ubicar en la carpeta


src:

La clase Proyecto002Activity hereda de la clase Activity. La clase Activity representa una ventana
de Android y tiene todos los mtodos necesarios para crear y mostrar los objetos que hemos
dispuesto en el archivo xml.
El cdigo fuente de la clase Proyecto002Activity.java es:
package android.proyecto002;
import android.app.Activity;
import android.os.Bundle;
public class Proyecto002Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Como mnimo se debe sobrescribir el mtodo onCreate heredado de la clase Activity donde
procedemos a llamar la mtodo setContentView pasando como referencia un valor almacenado
en una constante llamada main contenida en una clase llamada layout que a su vez la contiene
una clase llamada R (veremos ms adelante que el plugin de Eclipse para Android se encarga de
crear la clase R en forma automtica y sirve como puente entre el archivo xml y nuestra clase
Proyecto002Activity)
Captura de eventos.

Ahora viene la parte donde definimos variables en java donde almacenamos las referencias a los
objetos definidos en el archivo XML.

Definimos tres variables, dos de tipo EditText y finalmente una de tipo TextView (estas dos clases
se declaran en el paquete android.widget, es necesario importar dichas clases para poder definir
las variables de dichas clases):
package android.proyecto002;
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.widget.EditText;
android.widget.TextView;

public class Proyecto002Activity extends Activity {


private EditText et1,et2;
private TextView tv3;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Los nombres que le d a los objetos en este caso coinciden con la propiedad id (no es
obligatorio):
private EditText et1,et2;
private TextView tv3;

No definimos TextView para los dos mensajes "Ingrese el primer valor" e "Ingrese el segundo
valor" ya que no necesitaremos interactuar con ellos. Tambin veremos que el objeto de la clase
Button no es necesario definir un atributo sino que desde el archivo XML inicializaremos la
propiedad OnClick.
En el mtodo onCreate debemos enlazar estas variables con los objetos definidos en el archivo
XML, esto se hace llamando al mtodo findViewById:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);
et2=(EditText)findViewById(R.id.et2);
tv3=(TextView)findViewById(R.id.tv3);
}
Al mtodo findViewById debemos pasar la constante creada en la clase R (recordemos que se
crea automticamente esta clase) el nombre de la constante si debe ser igual con el nombre de la

propiedad del objeto creado en el archivo XML. Como la clase findViewById retorna una clase de
tipo View luego debemos utilizar el operador cast (es decir le antecedemos entre parntesis el
nombre de la clase)
Ya tenemos almacenados en las variables las referencias a los tres objetos que se crean al
llamar al mtodo:setContentView(R.layout.main); .
Ahora planteamos el mtodo que se ejecutar cuando se presione el botn (el mtodo debe
recibir como parmetro un objeto de la clase View) En nuestro ejemplo lo llam sumar:
package android.proyecto002;
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.EditText;
android.widget.TextView;

public class Proyecto002Activity extends Activity {


private EditText et1,et2;
private TextView tv3;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);
et2=(EditText)findViewById(R.id.et2);
tv3=(TextView)findViewById(R.id.tv3);
}
//Este mtodo se ejecutar cuando se presione el botn
public void sumar(View view) {
}
}
Ahora debemos ir al archivo XML e inicializar la propiedad OnClick del objeto button1 con el
nombre del mtodo que acabamos de crear (este paso es fundamental para que el objeto de la
clase Button pueda llamar al mtodo sumar que acabamos de crear):

Finalmente implementaremos la lgica para sumar los dos valores ingresados en los controles
EditText:
public void sumar(View view) {
String valor1=et1.getText().toString();
String valor2=et2.getText().toString();
int nro1=Integer.parseInt(valor1);
int nro2=Integer.parseInt(valor2);
int suma=nro1+nro2;
String resu=String.valueOf(suma);
tv3.setText(resu);
}
Extraemos el texto de los dos controles de tipo EditText y los almacenamos en dos variables
locales de tipo String. Convertimos los String a tipo entero, los sumamos y el resultado lo
enviamos al TextView donde se muestra la suma (previo a convertir la suma a String)
La clase completa queda entonces como:
package android.proyecto002;
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.EditText;
android.widget.TextView;

public class Proyecto002Activity extends Activity {

private EditText et1,et2;


private TextView tv3;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);
et2=(EditText)findViewById(R.id.et2);
tv3=(TextView)findViewById(R.id.tv3);
}
//Este mtodo se ejecutar cuando se presione el botn
public void sumar(View view) {
String valor1=et1.getText().toString();
String valor2=et2.getText().toString();
int nro1=Integer.parseInt(valor1);
int nro2=Integer.parseInt(valor2);
int suma=nro1+nro2;
String resu=String.valueOf(suma);
tv3.setText(resu);
}
}
Si ejecutamos nuestro programa podemos ver ahora que luego de cargar dos valores al presionar
el botn aparece en el tercer TextView el resultado de la suma de los dos EditText:

Final del proyecto002.

4 - Controles RadioGroup y RadioButton


El objetivo de este concepto es practicar la implementacin de un programa que requiera
controles de tipo RadioButton para seleccionar una actividad. Aprenderemos como agrupar un
conjunto de RadioButton y verificar cual est seleccionado.
Problema:

Realizar la carga de dos nmeros en controles de tipo EditText. Mostrar un mensaje que solicite
la carga de los valores. Disponer dos controles de tipo RadioButton para seleccionar si queremos
sumar o restar dichos valores. Finalmente mediante un control de tipo Button efectuamos la
operacin respectiva. Mostramos el resultado en un TextView.
El problema es similar al anterior. Para disponer los controles de tipo RadioButton debemos en
realidad primero insertar un control de tipo RadioGroup (este control se encuentra en la paleta de
componentes en la pestaa FormWidgets):

Cuando arrastramos el control RadioGroup al formulario se generan automticamente 3 objetos


de la clase RadioButton contenidos dentro del RadioGroup, podemos fcilmente identificar que
los controles RadioButton pertenecen a dicho RadioGroup viendo la ventana de "Outline" del
Eclipse (donde nos muestra todos los controles insertados hasta el momento):

Nuestro problema solo requiere dos controles de tipo RadioButton. Para borrarlo lo podemos
hacer directamente del formulario seleccionndolo y presionando la tecla delete o
seleccionndolo desde la ventana "Outline" y luego presionando la tecla delete
Ahora a los dos controles de tipo RadioButton definimos sus id (los llamaremos r1 y r2
respectivamente).
Cambiamos sus propiedades text por los textos "sumar" y "restar".
No olvidemos tambin cambiar los id de los controles EditText por et1 y et2 (igual que en el
problema anterior)
Por ltimo agreguemos un botn y un TextView
Inicializamos las propiedades del botn con los valores:

para

mostrar

el

resultado

id : button1
text : operar
Y el tercer TextView con los valores:

id : tv3
text : resultado
Podemos controlar en la ventana "Outline" el id definido para cada control (tv1, et1, tv2, et2,
radioGroup1, r1, r2, button1, tv3) Tambin podemos observar de que clase es cada control visual
y el texto de la propiedad text para aquellos controles que tienen sentido su inicializacin.

Si nuestro problema requera ms de 3 RadioButton deberamos arrastrar dentro del RadioGroup


otros controles de tipo RadioButton que se encuentran tambin en la pestaa de "Form Widgets"
Captura del evento clic del button e identifiacin del RadioButton seleccionado.

El cdigo fuente de la clase Proyecto003Activity es:


package android.proyecto003;
import
import
import
import

android.view.View;
android.widget.EditText;
android.widget.RadioButton;
android.widget.TextView;

public class Proyecto003Activity extends Activity {


private EditText et1,et2;
private TextView tv3;
private RadioButton r1,r2;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);
et2=(EditText)findViewById(R.id.et2);
tv3=(TextView)findViewById(R.id.tv3);
r1=(RadioButton)findViewById(R.id.r1);
r2=(RadioButton)findViewById(R.id.r2);
}

//Este mtodo se ejecutar cuando se presione el botn


public void operar(View view) {
String valor1=et1.getText().toString();
String valor2=et2.getText().toString();
int nro1=Integer.parseInt(valor1);
int nro2=Integer.parseInt(valor2);
if (r1.isChecked()==true) {
int suma=nro1+nro2;
String resu=String.valueOf(suma);
tv3.setText(resu);
} else
if (r2.isChecked()==true) {
int resta=nro1-nro2;
String resu=String.valueOf(resta);
tv3.setText(resu);
}
}
}
Primero debemos enlazar el objeto button1 con el mtodo operar. Para esto similar al problema
anterior seleccionamos el control button1 y cambiamos la propiedad OnClick por el valor operar
(si no hacemos esto nunca se ejecutar el mtodo operar de la clase Proyecto003Activity)
Como podemos ver el cdigo fuente es igual al problema anterior. Tenemos dos objetos ms que
debemos inicializar en el mtodo onCreate:
r1=(RadioButton)findViewById(R.id.r1);
r2=(RadioButton)findViewById(R.id.r2);
Las variables r1 y r2 son de la clase RadioButton y son necesarios en el mtodo operar para
verificar cual de los dos RadioButton estn seleccionados. La clase RadioButton tiene un mtodo
llamado isChecked que retorna true si dicho elemento est seleccionado:
public void operar(View view) {
String valor1=et1.getText().toString();
String valor2=et2.getText().toString();
int nro1=Integer.parseInt(valor1);
int nro2=Integer.parseInt(valor2);
if (r1.isChecked()==true) {
int suma=nro1+nro2;
String resu=String.valueOf(suma);
tv3.setText(resu);
} else
if (r2.isChecked()==true) {
int resta=nro1-nro2;
String resu=String.valueOf(resta);
tv3.setText(resu);
}
}
Final del proyecto003.

5 - Control CheckBox
El objetivo de este concepto es practicar lo visto hasta ahora e incorporar el control visual
CheckBox
Problema:

Realizar la carga de dos nmeros en controles de tipo EditText. Mostrar un mensaje que solicite
la carga de los valores. Disponer dos controles de tipo CheckBox para seleccionar si queremos
sumar y/o restar dichos valores. Finalmente mediante un control de tipo Button efectuamos la
operacin respectiva. Mostramos el o los resultados en un TextView.
Lo nuevo en este problema es la insercin de dos objetos de la clase CheckBox que se
encuentra en la pestaa "FormWidgets":

Luego la interfaz grfica final para este problema y los nombres de los controles los podemos ver
en la ventana "Outline":

No olvidemos inicializar la propiedad OnClick del objeto button1 con el valor "operar" (es el
nombre del mtodo a ejecutarse cuando se presione el botn y lo implementa la clase que
hacemos)
Cdigo fuente:

package android.proyecto004;
import
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.CheckBox;
android.widget.EditText;
android.widget.TextView;

public class Proyecto004Activity extends Activity {


private EditText et1,et2;
private TextView tv3;
private CheckBox checkBox1,checkBox2;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);

et2=(EditText)findViewById(R.id.et2);
tv3=(TextView)findViewById(R.id.tv3);
checkBox1=(CheckBox)findViewById(R.id.checkBox1);
checkBox2=(CheckBox)findViewById(R.id.checkBox2);
}
//Este mtodo se ejecutar cuando se presione el botn
public void operar(View view) {
String valor1=et1.getText().toString();
String valor2=et2.getText().toString();
int nro1=Integer.parseInt(valor1);
int nro2=Integer.parseInt(valor2);
String resu="";
if (checkBox1.isChecked()==true) {
int suma=nro1+nro2;
resu="La suma es: "+ suma;
}
if (checkBox2.isChecked()==true) {
int resta=nro1-nro2;
resu=resu + " La resta es: "+ resta;
}
tv3.setText(resu);
}
}
Definimos dos objetos de la clase CheckBox como atributos de la clase:
private CheckBox checkBox1,checkBox2;
En el mtodo onCreate los inicializamos con los objetos definidos en el archivo XML:
checkBox1=(CheckBox)findViewById(R.id.checkBox1);
checkBox2=(CheckBox)findViewById(R.id.checkBox2);
En el mtodo operar debemos definir dos if a la misma altura ya que los dos controles de tipo
CheckBox pueden estar seleccionados simultaneamente. Definimos una variable de tipo String y
la inicializamos con cadena vaca para el caso en que los dos CheckBox no estn seleccionados:
String resu="";
if (checkBox1.isChecked()==true) {
int suma=nro1+nro2;
resu="La suma es: "+ suma;
}
if (checkBox2.isChecked()==true) {
int resta=nro1-nro2;
resu=resu + " La resta es: "+ resta;
}
tv3.setText(resu);
Final del proyecto004.

6 - Control Spinner
El objetivo de este concepto es practicar lo visto hasta ahora e incorporar el control visual Spinner
El control Spinner muestra una lista de String y nos permite seleccionar uno de ellos. Cuando se
lo selecciona se abre y muestra todos sus elementos para permitir seleccionar uno de ellos.
Problema:

Realizar la carga de dos nmeros en controles de tipo EditText. Mostrar un mensaje que solicite
la carga de los valores. Disponer un control de tipo Spinner que permita seleccionar si queremos
sumar, restar, multiplicar o dividir dichos valores. Finalmente mediante un control de tipo Button
efectuamos la operacin respectiva. Mostramos el resultado en un TextView.
Lo nuevo en este problema es la insercin de un control de tipo Spinner que se encuentra en la
pestaa "FormWidgets":

Definimos la propiedad id con el valor spinner1.


En la siguiente imagen en la ventana "Outline" de Eclipse podemos observar los objetos
dispuestos en el formulario, sus Id, sus textos y de que clase son cada uno:

No olvidemos inicializar la propiedad OnClick del objeto button1 con el valor "operar" (dicho
nombre es el mtodo que debemos implementar)
Cdigo fuente:

package android.proyecto005;
import
import
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.ArrayAdapter;
android.widget.EditText;
android.widget.Spinner;
android.widget.TextView;

public class Proyecto005Activity extends Activity {


private Spinner spinner1;
private EditText et1,et2;
private TextView tv3;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);
et2=(EditText)findViewById(R.id.et2);
tv3=(TextView)findViewById(R.id.tv3);

spinner1 = (Spinner) findViewById(R.id.spinner1);


String []opciones={"sumar","restar","multiplicar","dividir"};
ArrayAdapter<String>
adapter
=
new
ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,
opciones);
spinner1.setAdapter(adapter);
}
//Este mtodo se ejecutar cuando se presione el botn
public void operar(View view) {
String valor1=et1.getText().toString();
String valor2=et2.getText().toString();
int nro1=Integer.parseInt(valor1);
int nro2=Integer.parseInt(valor2);
String selec=spinner1.getSelectedItem().toString();
if (selec.equals("sumar")) {
int suma=nro1+nro2;
String resu=String.valueOf(suma);
tv3.setText(resu);
} else
if (selec.equals("restar")) {
int resta=nro1-nro2;
String resu=String.valueOf(resta);
tv3.setText(resu);
}
else
if (selec.equals("multiplicar")) {
int multi=nro1*nro2;
String resu=String.valueOf(multi);
tv3.setText(resu);
}
else
if (selec.equals("dividir")) {
int divi=nro1/nro2;
String resu=String.valueOf(divi);
tv3.setText(resu);
}
}
}
Definimos un objeto de la clase Spinner:
private Spinner spinner1;

En el mtodo onCreate obtenemos la referencia al control visual declarado en el archivo XML:


spinner1=(Spinner)findViewById(R.id.spinner1);

Definimos un vector con la lista de String que mostrar el Spinner:

String []opciones={"sumar","restar","multiplicar","dividir"};

Definimos y creamos un objeto de la clase ArrayAdapter::


ArrayAdapter<String>
adapter
=
ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, opciones);

new

Al constructor le pasamos como primer parmetro la referencia de nuestro Activity (this), el


segundo parmetro indica el tipo de Spinner, pudiendo ser las constantes:
android.R.layout.simple_spinner_item
android.R.layout.simple_spinner_dropdown_item

El tercer parmetro es la referencia del vector que se mostrar:


Luego llamamos al mtodo setAdapter de la clase Spinner pasando la referencia del objeto de la
clase ArrayAdapter que acabamos de crear:
spinner1.setAdapter(adapter);

En el mtodo operar que se ejecuta cuando presionamos el botn procedemos a extraer el


contenido seleccionado del control Spinner:
String selec=spinner1.getSelectedItem().toString();

Luego mediante una serie de if anidados verificamos si debemos sumar, restar, multiplicar o
dividir:
if (selec.equals("sumar")) {
int suma=nro1+nro2;
String resu=String.valueOf(suma);
tv3.setText(resu);
} else
if (selec.equals("restar")) {
int resta=nro1-nro2;
String resu=String.valueOf(resta);
tv3.setText(resu);
}
else
if (selec.equals("multiplicar")) {
int multi=nro1*nro2;
String resu=String.valueOf(multi);
tv3.setText(resu);
}
else
if (selec.equals("dividir")) {
int divi=nro1/nro2;
String resu=String.valueOf(divi);
tv3.setText(resu);
}
Final del proyecto005.

7 - Control ListView
El control ListView a diferencia del Spinner que se cierra luego de seleccionar un elemento
permanecen visibles varios elementos (se lo utiliza cuando hay que mostrar muchos elementos)
Si la lista no entra en el espacio que hemos fijado para el ListView nos permite hacer scroll de los
mismos.
El control ListView se encuentra en la pestaa "compositive".
Problema:

Disponer un ListView con los nombres de paises de sudamrica. Cuando se seleccione un pas
mostrar en un TextView la cantidad de habitantes del pas seleccionado.
La interfaz visual a implementar es la siguiente (primero disponemos un TextView (llamado tv1) y
un ListView (llamado listView1)):

Cdigo fuente:

package android.proyecto006;
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.AdapterView;
android.widget.AdapterView.OnItemClickListener;

import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class Proyecto006Activity extends Activity {
private
paises={"Argentina","Chile","Paraguay","Bolivia","Peru",

String[]

"Ecuador","Brasil","Colombia","Venezuela","Uruguay"};
private
String[]
habitantes={"40000000","17000000","6500000","10000000","30000000",
"14000000","183000000","44000000","29000000","3500000"};
private TextView tv1;
private ListView lv1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv1=(TextView)findViewById(R.id.tv1);
lv1 =(ListView)findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new
ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,
paises);
lv1.setAdapter(adapter);
lv1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int posicion,
long id) {
tv1.setText("Poblacin de "+ lv1.getItemAtPosition(posicion) + "
es "+ habitantes[posicion]);
}
});
}
}
Primero definimos dos vectores paralelos donde almacenamos en uno los nombres de paises y
en el otro almacenamos la cantidad de habitantes de dichos paises:
private
paises={"Argentina","Chile","Paraguay","Bolivia","Peru",

String[]

"Ecuador","Brasil","Colombia","Venezuela","Uruguay"};
private
String[]
habitantes={"40000000","17000000","6500000","10000000","30000000",
"14000000","183000000","44000000","29000000","3500000"};

Definimos un objeto de tipo TextView y otro de tipo ListView donde almacenaremos las
referencias a los objetos que definimos en el archivo XML:
private TextView tv1;
private ListView lv1;
En el mtodo onCreate obtenemos la referencia a los dos objetos:
tv1=(TextView)findViewById(R.id.tv1);
lv1 =(ListView)findViewById(R.id.listView1);
Creamos un objeto de la clase ArrayAdapter de forma similar a como lo hicimos cuando vimos la
clase Spinner:
ArrayAdapter<String> adapter = new
ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, paises);
lv1.setAdapter(adapter);
Llamamos al mtodo setOnItemClicListener de la clase ListView y le pasamos como parmetro
una clase annima que implementa la interfaz OnItemClickListener (dicha interfaz define el
mtodo onItemClick que se dispara cuando seleccionamos un elemento del ListView):
lv1.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int
posicion, long id) {
tv1.setText("Poblacin
de
"+
lv1.getItemAtPosition(posicion) + " es "+ habitantes[posicion]);
}
});
Dentro del mtodo onItemClick modificamos el contenido del TextView con el nombre del pas y
la cantidad de habitantes de dicho pas. Este mtodo recibe en el tercer parmetro la posicin del
item seleccionado del ListView.

Cuando ejecutamos el proyecto podemos ver una interfaz en el emulador similar a esta:

Final del proyecto006.

8 - Control ImageButton
Hemos visto la creacin de objetos de la clase Button, ahora veremos otra clase muy similar a la
anterior llamada ImageButton que tiene la misma filosofa de manejo con la diferencia que puede
mostrar una imagen en su superficie.
Problema:

Disponer un objeto de la clase ImageButton que muestre una imagen de un telfono. Cuando se
presione mostrar en un control TextView el mensaje "Llamando".
Primero crearemos un proyecto llamado proyecto007 y luego debemos buscar una imagen en
formato png que represente un telefono de 50*50 pxeles.
Nombre del archivo: telefono.png Ahora copiamos el archivo a la carpeta de recursos de nuestro
proyecto : res\drawable-mdpi Desde el Eclipse en la ventana "Package Explorer" navegamos
hasta la carpeta res y entramos al directorio drawable-mdpi y vemos que todava no est el
archivo que acabamos de copiar. Para que se actualice el proyecto presionamos el botn
derecho del mouse sobre esta carpeta y seleccionamos la opcin "Refresh":

Vemos que se actualiz el contenido de la carpeta y aparece la imagen que copiamos


previamente.
Ahora insertaremos el objeto de la clase ImageButton en el formulario de nuestra aplicacin. La
clase ImageButton se encuentra en la pestaa "Image & Media":

Aparece un dilogo de donde seleccionamos el archivo telefono. Luego de esto podemos ver que
la superficie del objeto de la clase ImageButton muestra la imagen que almacenamos
previamente en la carpeta de res.
Si queremos cambiar el archivo a mostrar debemos modificar la propiedad src (aparece
nuevamente el dilogo que nos permite seleccionar la imagen) Inicializamos la propiedad ID con
el nombre bi1

Agreguemos un TextView a nuestra aplicacin y configuremos sus propiedades ID (con tv1) y


text. Luego la interfaz visual debe ser similar a:

Cdigo fuente:

package android.proyecto007;
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.TextView;

public class Proyecto007Activity extends Activity {


private TextView tv1;
private ImageButton ib1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv1=(TextView)findViewById(R.id.tv1);
}

//Este mtodo se ejecutar cuando se presione el ImageButton


public void llamar(View view) {
tv1.setText("Llamando");
}
}
Definimos los dos atributos:
TextView tv1;
Enlazamos el control definido en el archivo XML y la variable de java:
tv1=(TextView)findViewById(R.id.tv1);
Implementamos el mtodo que se ejecutar cuando se presione el el objeto de la clase
ImageButton:
public void llamar(View view) {
tv1.setText("Llamando");
}
No olvidemos inicializar la propiedad OnClick del objeto ib1 con el nombre del mtodo "llamar"
(recordemos que esto lo hacemos presionando el botn derecho del mouse sobre la imagen del
objeto de la clase ImageButton y desde la opcin properties accedemos a la propiedad OnClick)
Final del proyecto007.

Comentarios extras de este control.

Cuando copiamos el archivo lo hicimos a la carpeta:


drawable-mdpi
Pero vimos que hay otras dos carpetas con nombres similares:
drawable-ldpi
drawable-hdpi
El objetivo de estas otras dos carpetas es guardar las mismas imgenes pero con una resolucin
mayor si la guardamos en drawable-hdpi y con una resolucin menor al guardarla en drawableldpi.
Esto se hace si queremos que nuestra aplicacin sea ms flexible si se ejecuta en un celular, en
un tablet, en un televisor etc.
Debemos tener en cuenta estos tamaos:
En la carpeta res/drawable-mdpi/

(guardamos la imagen con el tamao original)


En la carpeta res/drawable-ldpi/
(guardamos la imagen con el tamao del 75% con respecto al de la carpeta
drawable-mdpi)
En la carpeta res/drawable-hdpi/
(guardamos la imagen con el tamao del 150% con respecto al de la
carpeta drawable-mdpi)

9 - Lanzar un segundo "Activity"


Hasta ahora todos los programas han tenido una sola ventana (Activity)
Es muy comn que una aplicacin tenga ms de una ventana. Para implementar esto en Android
debemos plantear una segunda clase que tambin herede de la clase Activity (tengamos en
cuenta que cuando utilizamos el plugin de Eclipse para Android automticamente cuando
creamos un proyecto nos crea el archivo XML y java de la primer Activity)
Vamos a ver en este concepto los pasos que debemos dar para crear otro Activity y como
activarlo desde el Activity principal.
Problema:

Confeccionar un programa que muestre en la ventana principal un botn que al ser presionado
muestre otra ventana (Activity) mostrando un TextView con el nombre del programador de la
aplicacin y un botn para cerrar la ventana.
1 - Primero creamos un nuevo proyecto que lo llamaremos proyecto008 y en la ventana principal
creamos la siguiente interfaz:

Es decir que nosotros queremos que cuando se presione el botn "Acerca De" nos abra otra
ventana (Activity) y nos muestre el nombre del programador.

2 - Ahora tenemos que crear el segundo Activity. Crearemos primero el archivo XML.
Presionamos el botn derecho sobre la carpeta layout y seleccionaremos la opcin New ->
Android XML File

Aqu tenemos que definir el nombre del archivo XML (debe estar en minsculas), lo llamaremos
acercade:

Implementamos ahora la interfaz visual de esta segunda ventana (Activity) disponiendo un objeto
de la clase TextView donde mostramos el nombre del autor de este programa y un Button para
cerrar la ventana.

3 - Tenemos ahora que crear el archivo Java donde dispondremos la funcionalidad de la segunda
ventana (Activity)
Creamos una nueva clase al proyecto desde el men contextual(presionamos el botn derecho
del mouse sobre el paquete android.proyecto008):

Al nombre de la clase la llamamos AcercaDe y debemos especificar que hereda de la clase


Activity:

Ahora tenemos que modificar el archivo Java generado con esto:


package android.proyecto008;
import android.app.Activity;
import android.os.Bundle;
public class AcercaDe extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acercade);
}
}
Como podemos ver la clase AcercaDe hereda de la clase Activity e implementa el mtodo
onCreate para enlazar el archivo XML que creamos anteriormente.
4 - Otro paso fundamental es registrar el Activity en el archivo "AndroidManifest.xml" que se
encuentra en la raiz principal del proyecto.

Seleccionamos el archivo y activamos la pestaa : "Application", presionamos el botn "add" y


seleccionamos "Activity":

Por ltimo seleccionamos en "Application Nodes" la actividad creada y definimos la propiedad


Name con el nombre de la clase que la implementa (en nuestro caso se llama AcercaDe):

5 - Ahora implementaremos la funcionalidad en la actividad (Activity) principal para que se active


la segunda ventana.
Inicializamos la propiedad OnClick del objeto de la clase Button con el valor "lanzar", este es el
mtodo que se ejecutar cuando se presione.
El cdigo fuente de la actividad principal queda:
package android.proyecto008;
import
import
import
import

android.app.Activity;
android.content.Intent;
android.os.Bundle;
android.view.View;

public class Proyecto008Activity extends Activity {


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

}
public void lanzar(View view) {
Intent i = new Intent(this, AcercaDe.class );
startActivity(i);
}
}
En el mtodo lanzar creamos un objeto de la clase Intent y le pasamos como parmetros la
referencia del objeto de esta clase (this) y la referencia del otro Activity (Acerca.class).
Llamamos posteriormente al mtodo startActivity pasando el objeto de la clase Intent (con esto ya
tenemos en pantalla la ventana del segundo Activity:
public void lanzar(View view) {
Intent i = new Intent(this, AcercaDe.class );
startActivity(i);
}
Si ejecutamos el programa podemos ver que cuando presionamos el botn "Acerca De" aparece
la segunda ventana donde se muestra el TextView con el valor "Autor de este programa: Diego" y
un botn con el texto "Finalizar" (si presionamos este botn no sucede nada, esto debido a que
no hemos asociado ningn evento a dicho botn).
6 - Debemos codificar el evento OnClick de la segunda actividad. Seleccionemos el botn
"Finalizar" y definamos en la propiedad OnClick el nombre de mtodo que se ejecutar al
presionarse el botn (en nuestro caso lo llamaremos finalizar"):
El cdigo fuente de la actividad AcercaDe queda:
package android.proyecto008;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
public class AcercaDe extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acercade);
}
public void cerrar(View view) {
finish();
}
}
Cuando se presiona el botn finalizar llamando al mtodo finish() que tiene por objetivo liberar el
espacio de memoria de esta actividad y pedir que se active la actividad anterior.

Ahora nuestro programa est funcionando completamente:


Primer Activity:

Segundo Activity:

Ahora ya tenemos el programa funcionando en forma completa.


Final del proyecto008.

Problema propuesto
Realizar un programa que contenga dos Activity. En el primero que solicite el ingreso de una clave (control
Password) Si ingresa la clave "abc123" activar el segundo Activity mostrando en un TextView un mensaje
de bienvenida (mostrar en un TextView si se ingrese la clave incorrecta). Llamar al proyecto: proyecto009.
En tiempo de ejecucin los dos Activity deben mostrarse algo similar a esto:

Final del proyecto009.

10 - Lanzar un segundo "Activity" y pasar


parmetros.
Hemos visto en el concepto anterior que un programa puede tener ms de una ventana
representando cada ventana con una clase que hereda de Activity.
Una situacin muy comn es que la primer ventana necesite enviar datos a la segunda para que
a partir de estos proceda a efectuar una accin.
Problema:

Confeccionar un programa que solicite el ingreso de una direccin de un sitio web y


seguidamente abrir una segunda ventana que muestre dicha pgina.
Para resolver este problema utilizaremos el control visual WebView que nos permite mostrar el
contenido de un sitio web.
Crearemos un nuevo proyecto llamado proyecto010 y lo almacenaremos en el package name:
android.proyecto010.
1 - Nuestro primer Activity tendr la siguiente interfaz visual (ver controles y ID de los controles):

Tenemos un control de tipo TextView (tv1), otro de tipo EditText y finalmente otro de tipo Button
(button1) debemos inicializar las propiedades de cada uno de estos tres objetos.
El cdigo fuente de esta Activity es:
package android.proyecto010;
import android.app.Activity;
import android.content.Intent;

import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class Proyecto010Activity extends Activity {
private EditText et1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);
}
public void ejecutar(View view) {
Intent i = new Intent(this, Actividad2.class );
i.putExtra("direccion", et1.getText().toString());
startActivity(i);
}
}
Como podemos ver la diferencia con el concepto anterior es que llamamos al mtodo putExtra de
la clase Intent. Tiene dos parmetros de tipo String, en el primero indicamos el nombre del dato y
en el segundo el valor del dato:
public void ejecutar(View view) {
Intent i = new Intent(this, Actividad2.class );
i.putExtra("direccion", et1.getText().toString());
startActivity(i);
}

La segunda interfaz visual (recordemos que debemos presionar el botn derecho sobre la
carpeta layout y seleccionar la opcin New -> Android XML File) la llamaremos actividad2.xml:

En esta interfaz disponemos primero un control de tipo Button (button1) y un objeto de la clase
WebView (se encuentra en la pestaa "Composite") y lo dejamos con el ID por defecto llamado
webView1
Tenemos que crear el archivo Java donde dispondremos la funcionalidad de la segunda ventana
(Activity) Creamos una nueva clase al proyecto desde el men contextual(presionamos el botn
derecho del mouse sobre el paquete android.proyecto010) Al nombre de la clase la llamamos
Actividad2 y debemos especificar que hereda de la clase Activity Ahora tenemos que modificar el
archivo Java generado con esto:
package android.proyecto010;
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.View;
android.webkit.WebView;

public class Actividad2 extends Activity {


private WebView webView1;
@Override
public void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.actividad2);
webView1=(WebView)findViewById(R.id.webView1);

Bundle bundle=getIntent().getExtras();
webView1.loadUrl("http://"+bundle.getString("direccion"));
}
public void finalizar(View view) {
finish();
}
}
En esta clase definimos una variable de tipo Bundle y la inicializamos llamando al mtodo
getExtras() de la clase Intent (esto lo hacemos para recuperar el o los parmetros que envi la
otra actividad (Activity)):
Bundle bundle=getIntent().getExtras();
webView1.loadUrl("http://"+bundle.getString("direccion"));
El mtodo loadUrl de la clase WebView permite visualizar el contenido de un sitio web.
Otro paso fundamental es registrar el Activity en el archivo "AndroidManifest.xml" que se
encuentra en la raiz principal del proyecto.
Seleccionamos el archivo y activamos la pestaa : "Application", presionamos el botn "add" y
seleccionamos "Activity".
Por ltimo seleccionamos en "Application Nodes" la actividad creada y definimos la propiedad
Name con el nombre de la clase que la implementa (en nuestro caso se llama Actividad2)
Como nuestra aplicacin debe acceder a internet debemos hacer otra configuracin en el archivo
"AndroidManifest.xml", debemos ir a la pestaa "Permissions" presionar el botn "Add" y
seleccionar "Uses Permissions":

Luego fijar en la propiedad name el valor android.permission.INTERNET

Ahora nuestro programa debera estar funcionando completamente.


La primer ventana debera ser algo similar a esto:

La segunda ventana debera ser algo similar a esto otro:

Final del proyecto010.

11 - Almacenamiento de datos mediante la


clase SharedPreferences
Veremos que la plataforma de Android nos da varias facilidades para el almacenamiento
permanente de datos (es decir que los mismos no se borran cuando se apaga la aplicacin)
Segn el tipo de necesidades utilizaremos alguno de estos mtodos:
1.
2.
3.

Mediante la clase SharedPreferences.


Mediante archivos de Texto.
En una base de datos.

No ser raro que una aplicacin utilice ms de uno de estos mtodos para el almacenamiento de
datos.
Cuando tenemos que almacenar una cantidad limitada de datos es adecuado utilizar la clase
SharedPreferences. Por ejemplo configuraciones de la aplicacin como pueden ser colores de
pantalla, nivel actual en un juego, datos iniciales de controles de entrada de dato etc.
Problema:

Confeccionar un programa que solicite el ingrese del mail de una persona. Guardar el mail
ingresado utilizando la clase SharedPreferences. Cada vez que se inicie la aplicacin almacenar
en el control EditText el ltimo mail ingresado. Disponer un botn para almacenar el mail
ingresado y finalizar el programa.
Crearemos un nuevo proyecto llamado proyecto011 y lo almacenaremos en el package name:
android.proyecto011.
La interfaz visual a implementar y los Id de los controles visuales son los siguientes:

Es decir:
Disponemos un TextView y definimos su ID con el nombre tv1
la propiedad Text con "Ingrese el mail:".
Disponemos un EditText y definimos su ID con el nombre et1.
Disponemos un Button y definimos su propiedad Id con el nombre button1
su
propiedad
Text
con
el
valor
confirmar
su propiedad OnClic con el valor
ejecutar
El cdigo java es:
package android.proyecto011;
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.content.SharedPreferences;
android.content.SharedPreferences.Editor;
android.os.Bundle;
android.view.View;
android.widget.EditText;

public class Proyecto011Activity extends Activity {


private EditText et1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);
SharedPreferences
prefe=getSharedPreferences("datos",Context.MODE_PRIVATE);
et1.setText(prefe.getString("mail",""));
}
public void ejecutar(View v) {
SharedPreferences
preferencias=getSharedPreferences("datos",Context.MODE_PRIVATE);
Editor editor=preferencias.edit();
editor.putString("mail", et1.getText().toString());
editor.commit();
finish();
}
}

Obtenemos la referencia del EditText:


et1=(EditText)findViewById(R.id.et1);
Obtenemos una referencia de un objeto de la clase SharedPreferences a travs del mtodo
getSharedPreferences. El primer parmetro es el nombre del archivo de preferencias y el
segundo la forma de creacin del archivo (MODE_PRIVATE indica que solo esta aplicacin
puede consultar el archivo XML que se crea)
SharedPreferences
prefe=getSharedPreferences("datos",Context.MODE_PRIVATE);
Para extraer los datos del archivo de preferencias debemos indicar el nombre a extraer y un valor
de retorno si dicho nombre no existe en el archivo de preferencias (en nuestro ejemplo la primera
vez que se ejecute nuestro programa como es lgico no existe el archivo de preferencias lo que
hace que Android lo cree, si tratamos de extraer el valor de mail retornar el segundo parmetro
es decir el String con una cadena vaca:
et1.setText(prefe.getString("mail",""));
Cuando se presiona el botn "Confirmar" lo que hacemos es grabar en el archivo de preferencias
el contenido del EditText en una variable llamada "mail":
public void ejecutar(View v) {
SharedPreferences
preferencias=getSharedPreferences("datos",Context.MODE_PRIVATE);
Editor editor=preferencias.edit();
editor.putString("mail", et1.getText().toString());
editor.commit();
finish();
}
Debemos crear un objeto de la clase Editor y obtener la referencia del objeto de la clase
SharedPreferences que acabamos de crear. Mediante el mtodo putString almacenamos en mail
el valor del String cargado en el EditText. Luego debemos llamar al mtodo commit de la clase
editor para que el dato quede almacenado en forma permanente en el archivo de preferencias.
Esto hace que cuando volvamos a arrancar la aplicacin se recupere el ltimo mail ingresado.
Recordemos que el mtodo finish de la clase Activity finaliza la actividad actual (como tenemos
una aplicacin con una sola actividad finalizar completamente nuestro programa.
Final del proyecto011.

Comentarios extras.

El modo de operacin del archivo puede ser:


MODE_PRIVATE
preferencias.

solo

la

aplicacin

puede

acceder

al

archivo

de

MODE_WORLD_READABLE otras aplicaciones pueden consultar el archivo de


preferencias
MODE_WORLD_WRITEABLE otras aplicaciones pueden consultar y modificar el
archivo.
MODE_MULTI_PROCESS varios procesos pueden acceder (Requiere Android 2.3)
Cuando guardamos datos en el archivo de preferencias podemos almacenar distintos tipos de
datos segn el mtodo que llamemos en el momento de grabar:
editor.putInt("edad",3);
editor.putBoolean("activo", true);
editor.putFloat("altura", 2.3f);
Cuando los recuperamos debemos indicar tambin que tipo de datos extraemos:
int e=prefe.getInt("edad", 0);
boolean acti=prefe.getBoolean("activo", false);
float alt=prefe.getFloat("altura", 0f);
Problema propuesto
Realizar un programa que genere un nmero aleatorio entre 1 y 50, pedir que el operador lo
adivine, informar si gan o si el nmero es mayor o menor al ingresado. Cuando el operador lo
adivine incrementar en uno el puntaje de juego. Cada vez que se ingrese a la aplicacin mostrar
el puntaje actual, es decir recordar el puntaje en un archivo de preferencias.
La interfaz visual de la aplicacin a desarrollar es:

Final del proyecto012.

12 - Almacenamiento de datos en un archivo


de texto en la memoria interna.
Otra posibilidad de almacenar datos en nuestro dispositivo Android es el empleo de un archivo de
texto que se almacenar en el almacenamiento interno del equipo (la otro posibilidad es
almacenarlo en una tarjeta SD Card)
Problema:

Confeccionar un programa que permita almacenar notas en un control EditText y cuando se


presione un botn almacenar los datos del EditText en un archivo de texto llamado "notas.txt".
Cada vez que se ingrese al programa verificar si existe el archivo de textos "notas.txt" proceder a
su lectura y almacenamiento de datos en el EditText.
Crear un proyecto en Eclipse de tipo "Android Project" y definir como nombre: proyecto013 y
localizarlo en el paquete android.proyecto013.
La interfaz visual, los controles y sus ID son los siguientes:

El cdigo fuente de la aplicacin:


package android.proyecto013;
import
import
import
import

java.io.BufferedReader;
java.io.IOException;
java.io.InputStreamReader;
java.io.OutputStreamWriter;

import android.app.Activity;
import android.os.Bundle;

import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class Proyecto013Activity extends Activity {


private EditText et1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);
String []archivos=fileList();
if (existe(archivos,"notas.txt"))
try {
InputStreamReader archivo=new
InputStreamReader(openFileInput("notas.txt"));
BufferedReader br=new BufferedReader(archivo);
String linea=br.readLine();
String todo="";
while (linea!=null)
{
todo=todo+linea+"\n";
linea=br.readLine();
}
br.close();
archivo.close();
et1.setText(todo);
} catch (IOException e)
{
}
}
private boolean existe(String[] archivos,String archbusca)
{
for(int f=0;f<archivos.length;f++)
if (archbusca.equals(archivos[f]))
return true;
return false;
}
public void grabar(View v) {
try {
OutputStreamWriter
archivo
=
new
OutputStreamWriter(openFileOutput("notas.txt",Activity.MODE_PRIVATE));
archivo.write(et1.getText().toString());
archivo.flush();
archivo.close();

}catch (IOException e)
{
}
Toast
t=Toast.makeText(this,"Los
Toast.LENGTH_SHORT);
t.show();
finish();
}
}

datos

fueron

grabados",

Veamos primero como grabamos datos en un archivo de texto. Esto se hace en el mtodo grabar
que se ejecuta cuando presionamos el botn "grabar" (recordemos de inicializar la propiedad
"OnClick" del botn):
public void grabar(View v) {
try {
OutputStreamWriter
archivo
=
new
OutputStreamWriter(openFileOutput("notas.txt",Activity.MODE_PRIVATE));
Creamos un objeto de la clase OutputStreamWriter y al constructor de dicha clase le enviamos el
dato que retorna el mtodo openFileOutput propio de la clase Activity que le pasamos como
parmetro el nombre del archivo de texto y el modo de apertura.
Seguidamente si el archivo se cre correctamente procedemos a llamar al mtodo write y le
pasamos el String a grabar, en este caso extraemos los datos del EditText:
archivo.write(et1.getText().toString());
Luego de grabar con el mtodo write llamamos al mtodo flush para que vuelque todos los datos
que pueden haber quedado en el buffer y procedemos al cerrado del archivo:
archivo.flush();
archivo.close();
Todo esto est cerrado en un try/catch para verificar si sucede algn error en la apertura del
archivo.
Finalmente mostramos un mensaje temporal en pantalla utilizando la clase Toast:
Toast
t=Toast.makeText(this,"Los
Toast.LENGTH_SHORT);
t.show();
finish();

datos

fueron

grabados",

Para crear un objeto de la clase Toast llamamos al mtodo makeText de la clase Toast y le
pasamos la referencia del Activity actual, el String a mostrar y el tiempo de duracin del mensaje.
Con el objeto devuelto por el mtodo makeText procedemos a llamar seguidamente al mtodo
show para que se muestre el mensaje.
Es comn llamar al mtodo show de la clase Toast en una sola lnea como esta:

Toast.makeText(this,"Los
Toast.LENGTH_SHORT).show();

datos

fueron

grabados",

El mtodo onCreate tiene por objetivo verificar si existe el archivo de texto, proceder a su lectura
y mostrar su contenido en el EditText.
Primero obtenemos la lista de todos los archivos creados por la Activity. En nuestro ejemplo
puede ser cero o uno:
String []archivos=fileList();
Llamamos a un mtodo que verifica si en el vector de tipo String existe el archivo "notas.txt":
if (existe(archivos,"notas.txt"))
En el caso que me retorne true procedemos a crear un objeto de la clase InputStreamReader y al
constructor de dicha clase le pasamos el dato devuelto por el mtodo openFileInput:
InputStreamReader archivo=new
InputStreamReader(openFileInput("notas.txt"));
Creamos un objeto de la clase BufferedReader y le pasamos al constructor la referencia del
objeto de la clase InputStreamReader:
BufferedReader br=new BufferedReader(archivo);
Leemos la primer lnea del archivo de texto:
String linea=br.readLine();
Inicializamos un String vaco:
String todo="";
Mientras el mtodo readLine de la clase BufferedReader devuelva un String:
while (linea!=null)
{
Lo concatenamos al String junto a un salto de lnea:
todo=todo+linea+"\n";
Leemos la prxima lnea:
linea=br.readLine();
}
Llamamos al mtodo close de la clase BufferedReader y al del InputStreamReader:
br.close();

archivo.close();
Cargamos el EditText con el contenido del String que contiene todos los datos del archivo de
texto:
et1.setText(todo);
El mtodo existe llega un vector de tipo String y otro String a buscar. Dentro de un for verificamos
el String a buscar con cada uno de los String del vector, si lo encontramos retornamos true. Si
recorre todo el for sin encontrarlo fuera del for retornamos false:
private boolean existe(String[] archivos,String archbusca)
{
for(int f=0;f<archivos.length;f++)
if (archbusca.equals(archivos[f]))
return true;
return false;
}
Final del proyecto013.

13 - Almacenamiento de datos en un archivo


de texto localizado en una tarjeta SD
En el concepto anterior vimos como crear y leer un archivo de texto en la memoria interna del
equipo Android. En algunas situaciones podra ser til almacenar los datos en una tarjeta SD,
esto debido a su mayor capacidad o la facilidad de compartir los archivos con otras personas
entregando la tarjeta SD.
Problema:

Confeccionar un programa que permita ingresar el nombre de un archivo y el contenido. Permitir


grabar los datos ingresados al presionar un botn. Disponer un segundo botn que permita
recuperar los datos del archivo de texto.
Hacer que los archivos se graben en una tarjeta SD.
La interfaz visual a implementar es la siguiente:

El primer paso es modificar el archivo AndroidManifest.xml para permitir el acceso a la tarjeta SD


desde nuestra aplicacin esto lo hacemos desde el editor visual del archivo AndroidManifest.xml:

Debemos presionar el botn "Add" seleccionar "Uses Permision" y luego en name seleccionar
"android.permission.WRITE_EXTERNAL_STORAGE".
El cdigo fuente es:
package android.proyecto014;
import
import
import
import
import
import
import

java.io.BufferedReader;
java.io.File;
java.io.FileInputStream;
java.io.FileOutputStream;
java.io.IOException;
java.io.InputStreamReader;
java.io.OutputStreamWriter;

import
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.os.Environment;
android.view.View;
android.widget.EditText;
android.widget.Toast;

public class Proyecto014Activity extends Activity {


EditText et1;
EditText et2;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.editText1);
et2=(EditText)findViewById(R.id.editText2);
}
public void grabar(View v) {
String nomarchivo = et1.getText().toString();
String contenido=et2.getText().toString();
try
{
File tarjeta = Environment.getExternalStorageDirectory();
File file = new File(tarjeta.getAbsolutePath(), nomarchivo);
OutputStreamWriter
osw
=new
OutputStreamWriter(new
FileOutputStream(file));
osw.write(contenido);
osw.flush();
osw.close();
Toast.makeText(this,"Los
datos
fueron
grabados
correctamente",Toast.LENGTH_SHORT).show();
et1.setText("");
et2.setText("");

}
catch (IOException ioe)
{
}
}
public void recuperar(View v) {
String nomarchivo = et1.getText().toString();
File tarjeta = Environment.getExternalStorageDirectory();
File file = new File(tarjeta.getAbsolutePath(), nomarchivo);
try {
FileInputStream fIn = new FileInputStream(file);
InputStreamReader archivo=new InputStreamReader(fIn);
BufferedReader br=new BufferedReader(archivo);
String linea=br.readLine();
String todo="";
while (linea!=null)
{
todo=todo+linea+"\n";
linea=br.readLine();
}
br.close();
archivo.close();
et2.setText(todo);
} catch (IOException e)
{
}
}
}
El mtodo para grabar los datos en un archivo de texto localizado en una tarjeta SD comienza
obteniendo el directorio raiz de la tarjeta a travs del mtodo getExternalStorageDirectory(), el
mismo retorna un objeto de la clase File.
public void grabar(View v) {
String nomarchivo = et1.getText().toString();
String contenido=et2.getText().toString();
try
{
File tarjeta = Environment.getExternalStorageDirectory();
Creamos un nuevo objeto de la clase File indicando el camino de la unidad SD y el nombre del
archivo a crear:
File file = new File(tarjeta.getAbsolutePath(), nomarchivo);
Por ltimo similar al acceso de un archivo interno creamos un objeto de la clase
OutputStreamWriter:

OutputStreamWriter osw =new OutputStreamWriter(new


FileOutputStream(file));
Grabamos el contenido del EditText:
osw.write(contenido);
Cerramos el archivo:
osw.flush();
osw.close();
Toast.makeText(this,"Los datos fueron grabados
correctamente",Toast.LENGTH_SHORT).show();
et1.setText("");
et2.setText("");
}
catch (IOException ioe)
{
}
}
Para la lectura del archivo nuevamente obtenemos la referencia de la tarjeta SD para obtener el
path de la unidad de almacenamiento, el resto del algoritmo es similar al visto con un archivo
interno:
public void recuperar(View v) {
String nomarchivo = et1.getText().toString();
File tarjeta = Environment.getExternalStorageDirectory();
File file = new File(tarjeta.getAbsolutePath(), nomarchivo);
try {
FileInputStream fIn = new FileInputStream(file);
InputStreamReader archivo=new InputStreamReader(fIn);
BufferedReader br=new BufferedReader(archivo);
String linea=br.readLine();
String todo="";
while (linea!=null)
{
todo=todo+linea+"\n";
linea=br.readLine();
}
br.close();
archivo.close();
et2.setText(todo);
} catch (IOException e)
{
}
}
Final del proyecto014.

14 - Almacenamiento en una base de datos


SQLite
Hemos visto hasta ahora dos modos de almacenar datos en forma permanente (archivos de texto
y la clase SharedPreferences), ahora veremos otra herramienta nativa de Android para
almacenar datos en una base de datos llamada SQLite.
SQLite es una base de datos Open Source, es muy popular en muchos dispositivos pequeos,
como Android.
Las ventajas que presenta utilizar SQLite es que no requiere configuracin, no tiene un servidor
de base de datos ejecutndose en un proceso separado y es relativamente simple su empleo.
Problema:

Confeccionar un programa que permita almacenar los datos de votantes de una eleccin. Crear
la tabla votantes y definir los campos dni (documento de identidad), nombre del votante, colegio
donde vota y nmero de mesa donde vota.
El programa debe permitir:
1
2
3
4

Carga de personas.
Consulta por el dni (para saber donde vota)
Borrado de personas
Modificacin de datos.

Primero implementamos una interfaz visual similar a esta:

Lo primero que haremos es crear una clase que herede de SQLiteOpenHelper. Esta clase nos
permite crear la base de datos y actualizar la estructura de tablas y datos iniciales.
Debemos implementar el constructor y sobreescribir los mtodos onCreate y onUpgrade.
El mtodo onCreate se le llama cuando la base de datos se crea por primera vez. Aqu es donde
se define la estructura de las tablas y se cargan eventualmente los datos iniciales
En el mtodo onUpgrade se llama cuando la base de datos debe ser actualizada. Tiene por
objetivo eliminar tablas, aadir tablas, o hacer cualquier otra cosa que necesita para actualizarse.
En nuestro problema implementaremos una nueva clase llamada AdminSQLiteOpenHelper que
herede de la clase SQLiteOpenHelper:
package android.proyecto015;
import
import
import
import

android.content.Context;
android.database.sqlite.SQLiteDatabase;
android.database.sqlite.SQLiteDatabase.CursorFactory;
android.database.sqlite.SQLiteOpenHelper;

public class AdminSQLiteOpenHelper extends SQLiteOpenHelper {

public
AdminSQLiteOpenHelper(Context
context,
CursorFactory factory, int version) {
super(context, nombre, factory, version);
}

String

nombre,

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table votantes(dni integer primary key,
nombre text, colegio text, nromesa integer)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int versionAnte, int
versionNue) {
db.execSQL("drop table if exists votantes");
db.execSQL("create table votantes(dni integer primary key,
nombre text, colegio text, nromesa integer)");
}
}

En el constructor solo llamamos al constructor de la clase padre pasando los datos que llegan en
los parmetros:
public AdminSQLiteOpenHelper(Context context, String nombre,
CursorFactory factory, int version) {
super(context, nombre, factory, version);
}
En el mtodo onCreate procedemos a crear la tabla votantes con los cuatro campos respectivos y
definiendo el campo dni como primary key:
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table votantes(dni integer primary key,
nombre text, colegio text, nromesa integer)");
}
En el mtodo onUpgrade procedemos a borrar la tabla votantes y crear nuevamente la tabla (en
este caso con la misma estructura pero podra ser otra en un caso ms real:
public void onUpgrade(SQLiteDatabase db, int versionAnte, int
versionNue) {
db.execSQL("drop table if exists votantes");
db.execSQL("create table votantes(dni integer primary key,
nombre text, colegio text, nromesa integer)");
}

Ahora veamos la otra clase que implementar las altas, bajas, modificaciones y consultas:
package android.proyecto015;
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.ContentValues;
android.database.Cursor;
android.database.sqlite.SQLiteDatabase;
android.os.Bundle;
android.view.View;
android.widget.EditText;
android.widget.Toast;

public class Proyecto015Activity extends Activity {


private EditText et1,et2,et3,et4;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.editText1);
et2=(EditText)findViewById(R.id.editText2);
et3=(EditText)findViewById(R.id.editText3);
et4=(EditText)findViewById(R.id.editText4);
}
public void alta(View v) {
AdminSQLiteOpenHelper
admin=new
AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String dni=et1.getText().toString();
String nombre=et2.getText().toString();
String colegio=et3.getText().toString();
String nromesa=et4.getText().toString();
ContentValues registro=new ContentValues();
registro.put("dni",dni );
registro.put("nombre",nombre );
registro.put("colegio",colegio );
registro.put("nromesa",nromesa );
bd.insert("votantes", null, registro);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
et4.setText("");
Toast.makeText(this, "Se cargaron los datos de la persona",
Toast.LENGTH_SHORT).show();
}
public void consulta(View v) {

AdminSQLiteOpenHelper
admin=new
AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String dni=et1.getText().toString();
Cursor fila=bd.rawQuery("select nombre,colegio,nromesa
from
votantes where dni="+dni+"",null);
if (fila.moveToFirst())
{
et2.setText(fila.getString(0));
et3.setText(fila.getString(1));
et4.setText(fila.getString(2));
}
else
Toast.makeText(this, "No existe una persona con dicho dni",
Toast.LENGTH_SHORT).show();
bd.close();
}
public void baja(View v) {
AdminSQLiteOpenHelper
admin=new
AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String dni=et1.getText().toString();
int cant=bd.delete("votantes", "dni="+dni+"",null);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
et4.setText("");
if (cant==1)
Toast.makeText(this,
"Se
borr
la
persona
con
dicho
documento", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "No existe una persona con dicho
documento", Toast.LENGTH_SHORT).show();
}
public void modificacion(View v) {
AdminSQLiteOpenHelper
admin=new
AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String dni=et1.getText().toString();
String nombre=et2.getText().toString();
String colegio=et3.getText().toString();
String nromesa=et4.getText().toString();
ContentValues registro=new ContentValues();
registro.put("nombre",nombre);
registro.put("colegio",colegio);
registro.put("nromesa",nromesa);
int cant = bd.update("votantes", registro, "dni="+dni, null);

bd.close();
if (cant==1)
Toast.makeText(this,
"se
modificaron
los
datos",
Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "no existe una persona con dicho
documento", Toast.LENGTH_SHORT).show();
}
}
Como en problemas anteriores definimos los cuatro EditText como atributos y en el mtodo
onCreate obtenemos la referencia de los mismos:
public class Proyecto015Activity extends Activity {
private EditText et1,et2,et3,et4;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.editText1);
et2=(EditText)findViewById(R.id.editText2);
et3=(EditText)findViewById(R.id.editText3);
et4=(EditText)findViewById(R.id.editText4);
}
1 - Alta de datos.
Cuando se presiona el botn alta se ejecuta el mtodo "alta" recordemos inicializar la propiedad
"OnClick" del botn desde la ventana de visualizacin del archivo XML.
Lo primero que hacemos en este mtodo es crear un objeto de la clase que planteamos
anteriormente y le pasamos al constructor this (referencia del Activity actual), "administracion" (es
el nombre de la base de datos que crearemos en el caso que no exista) luego pasamos null y un
uno indicando que es la primer versin de la base de datos (en caso que cambiemos la estructura
o agreguemos tablas por ejemplo podemos pasar un dos en lugar de un uno para que se ejecute
el mtodo onUpgrade donde indicamos la nuestra estructura de la base de datos)
Luego de crear un objeto de la clase AdminSqLiteOpenHelper procedemos a crear un objeto de
la clase SQLiteDataBase llamando al mtodo getWritableDatabase (la base de datos se abre en
modo lectura y escritura).
Creamos un objeto de la clase ContentValues y mediante el mtodo put inicializamos todos tos
campos a cargar.
Seguidamente llamamos al mtodo insert de la clase SQLiteDatabase pasando en el primer
parmetro el nombre de la tabla, como segundo parmetro un null y por ltimo el objeto de la
clase ContentValues ya inicializado (este mtodo es el que provoca que se inserte una nueva fila
en la tabla votantes en la base de datos llamada administracion)

Borramos seguidamente los EditText y mostramos un mensaje para que conozca el operador que
el alta de datos se efectu en forma correcta:
public void alta(View v) {
AdminSQLiteOpenHelper admin=new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String dni=et1.getText().toString();
String nombre=et2.getText().toString();
String colegio=et3.getText().toString();
String nromesa=et4.getText().toString();
ContentValues registro=new ContentValues();
registro.put("dni",dni );
registro.put("nombre",nombre );
registro.put("colegio",colegio );
registro.put("nromesa",nromesa );
bd.insert("votantes", null, registro);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
et4.setText("");
Toast.makeText(this, "Se cargaron los datos de la persona",
Toast.LENGTH_SHORT).show();
}
2 - Consulta de datos.
Cuando se presiona el botn "Consulta por DNI" se ejecuta el mtodo consulta:
public void consulta(View v) {
AdminSQLiteOpenHelper
admin=new
AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String dni=et1.getText().toString();
Cursor fila=bd.rawQuery("select nombre,colegio,nromesa
from
votantes where dni="+dni+"",null);
if (fila.moveToFirst())
{
et2.setText(fila.getString(0));
et3.setText(fila.getString(1));
et4.setText(fila.getString(2));
}
else
Toast.makeText(this, "No existe una persona con dicho dni",
Toast.LENGTH_SHORT).show();
bd.close();
}
En el mtodo consulta lo primero que hacemos es crear un objeto de la clase
AdminSQLiteOpenHelper y obtener una referencia de la base de datos llamando al mtodo
getWritableDatabase.

Seguidamente definimos una variable de la clase Cursor y la inicializamos con el valor devuelto
por el mtodo llamado rawQuery.
La clase Cursos almacena en este caso una fila o cero filas (una en caso que hayamos ingresado
un dni existente en la tabla votantes), llamamos al mtodo moveToFirst() de la clase Cursos y
retorna true en caso de existir una persona con el dni ingresado, en caso contrario retorna cero.
Para recuperar los datos propiamente dichos que queremos consultar llamamos al mtodo
getString y le pasamos la posicin del campo a recuperar (comienza a numerarse en cero, en
este ejemplo la columna cero representa el campo nombre, la columna 1 representa el campo
colegio y la columna 2 representa el campo nromesa)
3 - Baja o borrado de datos.
Para borrar uno o ms registros la clase SQLiteDatabase tiene un mtodo que le pasamos en el
primer parmetro el nombre de la tabla y en el segundo la condicin que debe cumplirse para que
se borre la fila de la tabla. El mtodo delete retorna un entero que indica la cantidad de registros
borrados:
public void baja(View v) {
AdminSQLiteOpenHelper admin=new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String dni=et1.getText().toString();
int cant=bd.delete("votantes", "dni="+dni+"",null);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
et4.setText("");
if (cant==1)
Toast.makeText(this, "Se borr la persona con dicho
documento", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "No existe una persona con dicho
documento", Toast.LENGTH_SHORT).show();
}
4 - Modificacin de datos.
En la modificacin de datos debemos crear un objeto de la clase ContentValues y mediante el
mtodo put almacenar los valores para cada campo que ser modificado. Luego se llama al
mtodo update de la clase SQLiteDatabase pasando el nombre de la tabla, el objeto de la clase
ContentValues y la condicin del where (el cuanto parmetro en este ejemplo no se lo emplea)
public void modificacion(View v) {
AdminSQLiteOpenHelper admin=new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String dni=et1.getText().toString();
String nombre=et2.getText().toString();
String colegio=et3.getText().toString();

String nromesa=et4.getText().toString();
ContentValues registro=new ContentValues();
registro.put("nombre",nombre);
registro.put("colegio",colegio);
registro.put("nromesa",nromesa);
int cant = bd.update("votantes", registro, "dni="+dni, null);
bd.close();
if (cant==1)
Toast.makeText(this, "se modificaron los datos",
Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "no existe una persona con dicho
documento", Toast.LENGTH_SHORT).show();
}
Final del proyecto015.

15 - Ventana de propiedades (Properties)


Hasta ahora siempre que queremos modificar propiedades de un objeto debemos presionar el
botn derecho del mouse y mediante el men contextual proceder a accederla y modificarla:

Otra forma de acceder a estas propiedades es la apertura de la ventana de properties, para esto
desde el men de Eclipse procedemos a seleccionar la opcin: Window -> Show View -> Other...:

Ahora seleccionamos en el dilogo siguiente en el cuadro General el cono de Properties:

Ahora cuando disponemos objetos sobre el formulario o lienzo de nuestra aplicacin podemos
ver todas las propiedades del objetos seleccionado y modificarlas desde esta ventana:

Por ejemplo si queremos definir la propiedad On Click de un objeto Button debemos seleccionarlo
y en la ventana de propiedades cargamos el valor para dicha propiedad:

16 - Layout (LinearLayout)
Android organiza las componentes visuales (Button, EditText, TextView etc.) en pantalla
mediante contenedores llamados Layout.
Hasta ahora no nos a preocupado como organizar una pantalla, sino nos hemos centrado en la
funcionalidad de cada programa que implementamos.
Ahora comenzaremos a preocuparnos como organizar y disponer las componentes dentro de la
pantalla.
- LinearLayout.
LinearLayout es uno de los diseos ms simples y ms empleado. Simplemente establece los
componentes visuales uno junto al otro, ya sea horizontal o verticalmente (nosotros hemos
empleado hasta ahora el LinearLayout disponiendo los componentes verticalmente)
Una de las propiedades ms importantes del contenedor LinearLayout es Orientation.
Si fijamos la propiedad Orientation con el valor Vertical luego las componentes contenidas en el
Layout se disponen una debajo de otra (Cuando disponemos un contenedor LinearLayout por
defecto se inicializa la propiedad Orientation en Vertical):

En cambio si fijamos la propiedad Orientation con el valor Horizontal el resultado es la disposicin


de las componentes en forma horizontal:

Otra propiedad pero en este caso perteneciente a los controles visuales (Button, EditText,
TextView etc.) y que tiene sentido emplearla cuando utilizamos un LinearLayout es la propiedad
Layout_weight (Define la cantidad de espacio extra en el diseo que debe ser asignado al
control) Por ejemplo si queremos disponer un control de tipo EditText y un Button en un
LinearLayout y que el EditText se apropie el 70% del espacio restante y el botn el 30% restante
debemos fijar los valores de las propiedades Layout_weight con los nmeros 0.7 y 0.3
respectivamente:

Podemos disponer ms de una componente de tipo LinearLayout para implementar nuestra


interfaz visual. Veamos los objetos y propiedades a configurar si queremos la siguiente interfaz:

Para implementar este interfaz hemos agregado de la pestaa "Layouts" dos controles de tipo
uno de tipo "LinearLayout (Vertical)" en la parte superior y uno de tipo "LinearLayout (Horizontal)"
en la parte inferior:

Disponemos un TextView y un EditText en el LinearLayout superior:

Ahora en el otro LinearLayout agregamos un Button y un TextView:

Para que el segundo LinearLayout quede en la parte inferior de la pantalla inicializamos las
propiedades "Layout_weight" con 1 para el superior y con 0 para el inferior:

Seleccionamos el EditText del primer LinearLayout y actualizamos las propiedades "Background"


(con el color blanco #ffffff) y Layout Width con el valor Match Parent (para que ocupe todo el
espacio del contenedor), tambin actualizamos el valor de la propiedad Text color con el valor
#000000:

Finalmente actualizamos el segundo EditText con lo que tenemos como resultado la interfaz:

Propiedad Gravity.
Otra propiedad muy utilizada es Gravity. Esta propiedad nos permite alinear a la izquierda, a la
derecha, a la parte superior, a la parte superior derecha etc.
Para implementar la siguiente interfaz:

Para el LinearLayout superior definimos la propiedad Layout_weight con valor 0 y el segundo


LinearLayout la misma propiedad Layout_weight con valor 1. Los dos botones que ubicamos en
el segundo LinearLayout aparecen en la parte inferior derecha ya que inicializamos la propiedad
Gravity del segundo LinearLayout con los valores:

17 - Layout (TableLayout)
El Layout de tipo TableLayout agrupa componentes en filas y columnas. Un TableLayout contiene
un conjunto de componentes de tipo TableRow que es el que agrupa componentes visuales por
cada fila (cada fila puede tener distinta cantidad de componentes visuales)
Cuando disponemos un control de Layouts de tipo TableLayout automticamente crea cuatro
componentes de tipo TableRow que los podemos ver en la ventana "Outline". Podemos borrar o
agregar componentes de tipo TableRow segn las necesidades de nuestro TableLayout:

Luego de borrar un control de tipo TableRow y agregar componentes de tipo Button la interfaz
visual queda como sigue:

Otra propiedad que nos puede ser til inicializar en los controles que se disponen dentro de un
TableLayout es layout_span. Esta propiedad permite que un control se expanda ms de una
celda.
En el siguiente ejemplo el objeto de la clase Button de la segunda fila hemos dispuesto la
propiedad layout_span con el valor 2:

Si la propiedad no aparece en la ventana "Properties" cuando seleccionamos el objeto debemos


entrar al archivo XML y agregar manualmente dicha propiedad:

18 - Layout (RelativeLayout)
Hay varias posibilidades cuando empleamos el RelativeLayout. Primero podemos alinear un
control con respecto al Layout que lo contiene. Para probar esto dispondremos un control de tipo
RelativeLayout y fijaremos la propiedad Layout_weight con el valor 1 (esto hace que el
RelativeLayout ocupe completamente la pantalla) Luego dispondremos un botn en cada vrtice
y veremos que propiedades son afectadas e inicializadas:

Como podemos ver cada control que agregamos se inicializan alguna de las propiedades:
alignParentLeft
alignParentRight
alignParentTop
alignParentBottom
centerHorizontal
centerVertical
centerInParent
Con este tipo de layout podemos disponer un control en forma relativa a otro control que haya
dentro del RelativeLayout. Veamos un ejemplo:

En este ejemplo hemos dispuesto el segundo botn debajo (below) del botn 1 y alineado a la
izquierda (luego si desplazamos el botn 1 se desplazar el botn 2)
La posicin relativa con respecto a otro control puede ser:
above (por encima)
below (debajo)
toLeftOf (a la izquierda de)
toRightOf (a la derecha)

19 - Layout (FrameLayout)
El control de tipo FrameLayout dispone dentro del contenedor todos los controles visuales
alineados al vrtice superior izquierdo. Es decir si disponemos dos o ms controles los mismos
se apilan.
Por ejemplo si disponemos dentro de un FrameLayout un ImageView y un Button luego el botn
se superpone a la imagen:

Otra aplicacin del control FrameLayout es disponer una serie de controles visuales no visibles e
ir alternando cual se hace visible.
Problema:

Disponer un ImageView y un Button dentro de un layout FrameLayout. Cuando se inicia la


aplicacin mostrar solo el botn y al ser presionado ocultar el botn y hacer visible la imagen que
muestra el ImageView.

Creamos una interfaz visual similar a la siguiente:

Seleccionamos el control ImageView y fijarmos la propiedad Visibility con el valor invisible (esto
hace que la imagen no se muestre en pantalla)
Luego inicializamos la propiedad On click del control Button indicando el nombre del mtodo que
se ejecutar al ser presionado:

El cdigo fuente de la clase es:

package android.proyecto016;
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.Button;
android.widget.ImageView;

public class Proyecto016Activity extends Activity {


Button b1;
ImageView iv1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1=(Button)findViewById(R.id.button1);
iv1=(ImageView)findViewById(R.id.imageView1);
}
public void ocultarBoton(View v) {
b1.setVisibility(View.INVISIBLE);
iv1.setVisibility(View.VISIBLE);
}
}
Cuando se presiona el botn procedemos a ocultar el botn y hacer visible la imagen:
public void ocultarBoton(View v) {
b1.setVisibility(View.INVISIBLE);
iv1.setVisibility(View.VISIBLE);
}
Final del proyecto016.

20 - Layout (ScrollView y LinearLayout)


El ScrollView junto con un LinearLayout nos permite disponer una cantidad de componentes
visuales que superan la cantidad de espacio del visor del celular o tablet. Luego el usuario puede
desplazar con el dedo la interfaz creada.
Problema:

Disponer un control de tipo ScrollView (que se encuentra en la pestaa Composite). Como


veremos automticamente se crea una componente de tipo LinearLayout e fijemos la propiedad
Orientation del LinearLayout con el valor vertical:

Luego dispongamos numerosos botones que superen la cantidad de espacio del dispositivo.
Numerar los botones con los nmeros del 1 en adelante:

Luego si ejecutamos el programa veremos que podemos desplazar (scroll) todo el contenido del
visor con el dedo:

Final del proyecto017.

Otra posibilidad para la implementacin de una interfaz en Android es disponer un LinearLayout


en la parte superior y un ScrollView en la parte inferior:

Esto hace que en tiempo de ejecucin quede fijo el LinearLayout y podamos desplazar con el
dedo el ScrollView que aparece en la parte inferior:

21 - Icono de la aplicacin
Cuando creamos un proyecto para implementar una aplicacin con el plugin de Android nos crea
un cono por defecto:

Los conos e imgenes se almacenan en la carpeta res (resources) y en esta hay tres carpetas
llamadas:
drawable-mdpi
drawable-ldpi
drawable-hdpi
Y en cada una de estas hay un archivo llamado icon.png:

Como las resoluciones de los dispositivos Android pueden ser muy distintos (un celular, una
tablet, un televisor etc.) se recomienda proporcionar mltiples copias de cada imagen de recursos
a diferentes resoluciones y almacenarlos en las carpetas nombradas respetando las siguientes
reglas:
res/drawable-mdpi/
El cono debe ser de 48*48 pxeles.
res/drawable-ldpi/
75% del tamao de las imgenes almacenadas en la carpeta drawablemdpi
El cono debe ser de 36*36 pxeles.
res/drawable-hdpi/
150% del tamao de las imgenes almacenadas en la carpeta drawablemdpi
El cono debe ser de 72*72 pxeles.
En las versiones ms actuales de Android se propone crear una cuarta carpeta llamada:

res/drawable-xhdpi/
200% del tamao de las imgenes almacenadas en la carpeta drawablemdpi
Problema:

Crear una aplicacin, dibujar y almacenar tres archivos llamados icon.png. Tener en cuenta que
el archivo que se almacena en la carpeta drawable-mdpi debe ser de 48 pxeles, el de la carpeta
drawable-mdpi de 36 pxeles y el de la carpeta drawable-hdpi debe ser de 72 pxeles de ancho y
alto. Ejecutar la aplicacin y ver el cono nuevo.

Final del proyecto018.

22 - Reproduccin de audio (archivo


contenido en la aplicacin)
Veremos los pasos para reproducir un archivo mp3 (otros formatos soportados por Android son:
Ogg, Wav)
Problema:

Disponer dos botones con las etiquetas: Gato y Len, luego cuando se presione reproducir el
archivo de audio respectivo. Los archivos de sonidos almacenarlos en la misma aplicacin.
Luego de crear el proyecto procedemos a crear una carpeta llamada raw que dependa de la
carpeta res, almacenamos los dos archivos mp3 en dicha carpeta:

Luego de copiar los archivos a la carpeta debemos refrescar los archivos contenidos en el
proyecto presionando el botn derecho del mouse y seleccionando la opcin "Refresh":

Podemos comprobar que los dos archivos estn referenciados en el proyecto.


Creamos una interfaz con dos botones e inicializamos las propiedades Text y On Click de cada
botn:

El cdigo fuente de la clase Proyecto019Activity.java es:


package android.proyecto019;
import
import
import
import

android.app.Activity;
android.media.MediaPlayer;
android.os.Bundle;
android.view.View;

public class Proyecto019Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void presionGato(View v) {
MediaPlayer mp=MediaPlayer.create(this,R.raw.gato);
mp.start();
}
public void presionLeon(View v) {
MediaPlayer mp=MediaPlayer.create(this, R.raw.leon);
mp.start();
}

}
Cuando copiamos los archivos mp3 se genera luego en la clase R la referencia a los dos archivos
y posteriormente los podemos rescatar cuando creamos un objeto de la clase MediaPlayer:
MediaPlayer mp=MediaPlayer.create(this,R.raw.gato);
Seguidamente llamamos al mtodo start:
mp.start();
Final del proyecto019.

23 - Reproduccin, pausa, continuacin y


detencin de un archivo de audio.
Problema:

Confeccionar una aplicacin que permita Iniciar un archivo mp3, detener, continuar, detener en
forma definitiva y activacin o no de la reproduccin en forma circular.
Crear un archivo mp3 con el programa Audacity contando del 1 al 30.
Primero creamos un proyecto y definimos los 5 botones y mtodos a ejecutar cuando se
presionen los botones respectivos:

Creamos la carpeta raw y almacenamos en la misma el archivo mp3 creado previamente.


Refrescamos la carpeta raw para actualizar el archivo mp3:

El cdigo fuente es:


package android.proyecto020;
import
import
import
import
import

android.app.Activity;
android.media.MediaPlayer;
android.os.Bundle;
android.view.View;
android.widget.Button;

public class Proyecto020Activity extends Activity {


MediaPlayer mp;
Button b1;
int posicion=0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1=(Button)findViewById(R.id.button5);
}
public void destruir() {
if(mp!=null)
mp.release();
}
public void iniciar(View v) {
destruir();
mp = MediaPlayer.create(this,R.raw.numeros);
mp.start();
String op=b1.getText().toString();
if (op.equals("No reproducir en forma circular"))
mp.setLooping(false);
else
mp.setLooping(true);
}
public void pausar(View v) {
if(mp != null && mp.isPlaying()) {
posicion = mp.getCurrentPosition();
mp.pause();
}
}
public void continuar(View v) {
if(mp != null && mp.isPlaying()==false) {
mp.seekTo(posicion);
mp.start();
}
}

public void detener(View v) {


if(mp != null) {
mp.stop();
posicion = 0;
}
}
public void circular(View v) {
detener(null);
String op=b1.getText().toString();
if (op.equals("No reproducir en forma circular"))
b1.setText("reproducir en forma circular");
else
b1.setText("No reproducir en forma circular");
}
}
Primero definimos tres atributos uno de la clase MediaPlayer para administrar el archivo mp3, un
entero donde se almacena la posicin actual de reproduccin en milisegundos (para poder
continuarla en el futuro) y la referencia de un objeto de la clase Button:
MediaPlayer mp;
Button b1;
int posicion=0;
El mtodo destruir verifica con un if si el objeto de la clase MediaPlayer est creado procede a
liberar recursos del mismo llamando al mtodo release:
public void destruir() {
if(mp!=null)
mp.release();
}
El mtodo iniciar que se ejecuta al presionar el botn "Iniciar" primero llama al mtodo destruir
(para el caso que el mp3 este en ejecucin actualmente) seguidamente creamos un objeto de la
clase MediaPlayer llamando al mtodo create (en este hacemos referencia al archivo que
copiamos a la carpeta raw) Llamamos al mtodo start. Por ltimo extraemos el texto del quinto
botn y verificamos si la reproduccin debe ejecutarse en forma circular (en forma indefinida una
y otra vez):
public void iniciar(View v) {
destruir();
mp = MediaPlayer.create(this,R.raw.numeros);
mp.start();
String op=b1.getText().toString();
if (op.equals("No reproducir en forma circular"))
mp.setLooping(false);
else
mp.setLooping(true);

}
El mtodo pausar verifica que el objeto de la clase MediaPlayer este creado y en ejecucin, en
caso afirmativo recuperamos la posicin actual de reproduccin y llamamos seguidamente al
mtodo pause:
public void pausar(View v) {
if(mp != null && mp.isPlaying()) {
posicion = mp.getCurrentPosition();
mp.pause();
}
}
El mtodo continuar verifica que el objeto de la clase MediaPlayer este creado y la propiedad
isPlaying retorne false para proceder a posicionar en que milisegundo continuar la reproduccin:
public void continuar(View v) {
if(mp != null && mp.isPlaying()==false) {
mp.seekTo(posicion);
mp.start();
}
}
El mtodo detener interrumpe la ejecucin del mp3 e inicializa el atributo posicion con cero:
public void detener(View v) {
if(mp != null) {
mp.stop();
posicion = 0;
}
}
Cuando se presiona el botn que cambia si la reproduccin se efecta en forma circular o no
procedemos a extraer su texto y segn dicho valor almacenamos el valor opuesto:
public void circular(View v) {
detener(null);
String op=b1.getText().toString();
if (op.equals("No reproducir en forma circular"))
b1.setText("reproducir en forma circular");
else
b1.setText("No reproducir en forma circular");
}
Final del proyecto020.

24 - Reproduccin de audio (archivo


contenido en una tarjeta SD)
El objetivo de este concepto es acceder a un archivo mp3 almacenado en la tarjeta SD de
nuestro equipo.
Problema:

Disponer un botn con la etiqueta: "Gato", luego cuando se presione reproducir el archivo de
audio respectivo. El archivo de sonido almacenarlo en la tarjeta SD.
Luego de crear el proyecto debemos ejecutar la aplicacin en modo depuracin para poder
acceder a la tarjeta SD que crea el emulador Android. Para ejecutar la aplicacin en modo
"Debug" presionamos el botn derecha del mouse sobre el proyecto y seleccionamos la opcin
"Debug A" "Android Aplication":

Una vez que se este ejecutando la aplicacin (no importa que todava no hemos implementado
su funcionalidad) procedemos a abrir la ventana "File Explorer" de Android. Seleccionamos del
men de opciones de Eclipse: Window -> Show View -> Other :

Y en esta ventana seleccionamos Android -> FileExplorer:

Ahora podemos ver la ventana donde administramos los archivos contenidos en la tarjeta SD que
emula el "Android Virtual Device":

En la carpeta sdcard debemos subir el archivo mp3 (debemos seleccionar esta carpeta con el
mouse)
Esto lo hacemos mediante un botn que aparece en la parte derecha de esta ventana "Push a file
onto device", luego de esto tenemos el archivo montado en la tarjeta SD:

Ahora implementemos la interfaz de nuestra aplicacin (un solo botn) que cuando se presione
llame al mtodo ejecutar:

El cdigo fuente es:


package android.proyecto021;
import
import
import
import
import
import

android.app.Activity;
android.media.MediaPlayer;
android.net.Uri;
android.os.Bundle;
android.os.Environment;
android.view.View;

public class Proyecto021Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void ejecutar(View v) {
Uri
datos
Uri.parse(Environment.getExternalStorageDirectory().getPath()
+"/gato.mp3");
MediaPlayer mp=MediaPlayer.create(this, datos);
mp.start();
}
}

Creamos un objeto de la clase Uri llamando al mtodo parse donde indicamos el path y nombre
del archivo a recuperar:

Uri datos =
Uri.parse(Environment.getExternalStorageDirectory().getPath()
+"/gato.mp3");
Creamos el objeto de la clase MediaPlayer pasando ahora la referencia del objeto de la clase Uri:
MediaPlayer mp=MediaPlayer.create(this, datos);
Iniciamos la reproduccin del mp3:
mp.start();
Final del proyecto021.
Recordar que para ejecutar este proyecto se debe subir un archivo mp3 llamado "gato.mp3" a la
tarjeta SD.

25 - Reproduccin de audio (archivo


localizado en internet)
Ahora vamos a ver los pasos para reproducir un archivo almacenado en un servidor de internet.
Problema:

Disponer un botn con la etiqueta: "Gato", luego cuando se presione reproducir el archivo de
audio
respectivo.
El
archivo
de
sonido
se
encuentra
almacenado
en
http://www.codigofuenteya.com.ar/recursos/gato.mp3
El primer paso es modificar el archivo AndroidManifest.xml donde autorizamos a la aplicacin a
acceder a recursos localizados en internet:

Creamos la interfaz de la aplicacin e inicializamos el evento On click del Button con el mtodo
que implementaremos:

El cdigo fuente es:


package android.proyecto022;
import java.io.IOException;
import
import
import
import

android.app.Activity;
android.media.MediaPlayer;
android.os.Bundle;
android.view.View;

public class Proyecto022Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void ejecutar(View v) {
MediaPlayer mp=new MediaPlayer();
try {
mp.setDataSource("http://www.codigofuenteya.com.ar/recursos/gato.mp3");
mp.prepare();
mp.start();
}catch(IOException e) {
}
}
}
Para recuperar un archivo mp3 de internet procedemos de la siguiente manera, primero creamos
un objeto de la clase MediaPlayer:
MediaPlayer mp=new MediaPlayer();
Luego llamamos al mtodo setDataSource indicando la direccin de internet donde se almacena
el archivo mp3:
mp.setDataSource("http://www.codigofuenteya.com.ar/recursos/gato.mp3");
Llamamos al mtodo prepare y seguidamente llamamos a start:
mp.prepare();
mp.start();
Todo esto lo hacemos en un bloque try/catch para capturar excepciones de tipo IOException.
Esta primera aproximacin para ejecutar un mp3 localizado en internet bloquea la aplicacin
hasta que se carga por completo el archivo, es decir queda ejecutndose el mtodo mp.prepare()
hasta que finaliza la recuperacin en forma completa.

Final del proyecto022.


Problema:

Confeccionar otra aplicacin similar a la anterior pero que no se congele la interfaz de la


aplicacin mientras se carga el mp3. Mostrar un mensaje que el archivo se est cargando.
Desarrollamos un nuevo proyecto, asignamos el permiso de acceder a internet en el archivo
AndroidManifest.xmp y creamos una interfaz similar al problema anterior.
El cdigo fuente es:
package android.proyecto023;
import java.io.IOException;
import
import
import
import
import
import

android.app.Activity;
android.media.MediaPlayer;
android.media.MediaPlayer.OnPreparedListener;
android.os.Bundle;
android.view.View;
android.widget.Toast;

public
class
Proyecto023Activity
extends
Activity
OnPreparedListener {
MediaPlayer mp;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

implements

public void ejecutar(View v) {


mp=new MediaPlayer();
mp.setOnPreparedListener(this);
try {
mp.setDataSource("http://www.codigofuenteya.com.ar/recursos/gato.mp3");
mp.prepareAsync();
}catch(IOException e) {
}
Toast t=Toast.makeText(this,"Espere un momento mientras se
carga el mp3", Toast.LENGTH_SHORT);
t.show();
}
public void onPrepared(MediaPlayer mp) {
mp.start();
}
}

Para poder capturar el evento que el archivo se termin de recuperar debemos implementar la
interface OnPreparedListener:
public class Proyecto023Activity extends Activity implements
OnPreparedListener {
Con esto decimos que nuestra clase implementar el mtodo onPrepared donde iniciamos la
ejecucin del mp3:
public void onPrepared(MediaPlayer mp) {
mp.start();
}
En el evento click del botn creamos el objeto de la clase MediaPlayer, le pasamos al mtodo
setOnPreparedListener la direccin del objeto que capturar el evento de que el recurso est
completo. Luego llamamos a los mtodos setDataSource y prepareAsync para inicializar la carga
del mp3. Finalmente mostramos un mensaje para informar al usuario que el archivo se est
descargando:
public void ejecutar(View v) {
mp=new MediaPlayer();
mp.setOnPreparedListener(this);
try {
mp.setDataSource("http://www.codigofuenteya.com.ar/recursos/gato.mp3");
mp.prepareAsync();
}catch(IOException e) {
}
Toast t=Toast.makeText(this,"Espere un momento mientras se
carga el mp3", Toast.LENGTH_SHORT);
t.show();
}
Final del proyecto023.

26 - Reproduccin de audio utilizando el


reproductor propio de Android (va Intent)
Otra forma de ejecutar un archivo mp3 es mediante el reproductor interno de Android. Esta
aplicacin reproduce todos los formatos soportados por Android y tiene una interfaz que le ser
familiar al usuario de nuestra aplicacin.
Problema:

Disponer un botn con la etiqueta: "Ejecutar mp3 con el reproductor propio de Android", luego
cuando se presione reproducir el archivo de audio respectivo con el reproductor de Android via
Intent. El archivo de sonido almacenarlo en la tarjeta SD.
Luego de crear el proyecto debemos ejecutar la aplicacin en modo depuracin para poder
acceder a la tarjeta SD que crea el emulador Android. Para ejecutar la aplicacin en modo
"Debug" presionamos el botn derecha del mouse sobre el proyecto y seleccionamos la opcin
"Debug A" "Android Aplication":

Una vez que se este ejecutando la aplicacin (no importa que todava no hemos implementado
su funcionalidad) procedemos a abrir la ventana "File Explorer" de Android. Seleccionamos del
men de opciones de Eclipse: Window -> Show View -> Other :

Y en esta ventana seleccionamos Android -> FileExplorer:

Ahora podemos ver la ventana donde administramos los archivos contenidos en la tarjeta SD que
emula el "Android Virtual Device":

En la carpeta sdcard debemos subir el archivo mp3 (debemos seleccionar esta carpeta con el
mouse)
Esto lo hacemos mediante un botn que aparece en la parte derecha de esta ventana "Push a file
onto device", luego de esto tenemos el archivo montado en la tarjeta SD:

Creamos la interfaz con el Button y especificamos el evento On click:

El cdigo fuente es:


package android.proyecto024;
import
import
import
import
import

android.app.Activity;
android.content.Intent;
android.net.Uri;
android.os.Bundle;
android.view.View;

public class Proyecto024Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void ejecutar(View v) {
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
Uri data = Uri.parse("file:///sdcard"+"/gato.mp3");
intent.setDataAndType(data, "audio/mp3");
startActivity(intent);
}
}
Creamos un objeto de la clase Intent y un objeto de la clase Uri referenciando al archivo mp3
almacenado en la tarjeta SD. Indicamos mediante el mtodo setDataAndType el Uri y el tipo de
archivo a reproducir. Activamos la aplicacin mediante startActivity.
Final del proyecto024.

27 - Grabacin de audio mediante el


grabador provisto por Android (via Intent)
La forma ms sencilla de capturar audio en Android es mediante el grabador que provee el
sistema operativo Android. Invocamos la aplicacin de grabacin (tiene como ventana que la
interfaz le es familiar al usuario, ya que muchas aplicaciones utilizan esta caracterstica) y luego
recuperamos el audio grabado.
Problema:

Disponer dos objetos de la clase Button con las etiquetas "Grabar" y "Reproducir". Cuando se
presione el primer botn proceder a activar la grabadora provista por Android. Cuando se
presione el segundo botn reproducir el audio grabado.
Crear la interfaz e inicializar los eventos On click de cada botn:

El cdigo fuente es:


package android.proyecto25;
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Intent;
android.media.MediaPlayer;
android.media.MediaPlayer.OnCompletionListener;
android.net.Uri;
android.os.Bundle;
android.provider.MediaStore;
android.view.View;

public class Proyecto025Activity extends Activity {


int peticion=1;
Uri url1;

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void grabar(View v) {
Intent
intent
=
Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(intent, peticion);
}

new

public void reproducir(View v) {


MediaPlayer mediaPlayer = MediaPlayer.create(this, url1);
mediaPlayer.start();
}
protected void onActivityResult (int requestCode, int resultCode,
Intent data) {
if (resultCode == RESULT_OK && requestCode == peticion) {
url1 = data.getData();
}
}
}
Cuando se presiona el botn de grabar el audio mediante un Intent activamos la aplicacin de
grabacin propia de Android.
Seguidamente llamamos al mtodo startActivityForResult para poder recuperar la grabacin
luego de finalizada a travs del mtodo onActivityResult:
public void grabar(View v) {
Intent
intent
=
Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(intent, peticion);
}

new

Debemos pasar al mtodo startActivityForResult adems de la referencia del Intent una variable
con un valor 0 o positivo (luego este valor retornar al mtodo onActivityResult)
Cuando finalizamos la grabacin se ejecuta el mtodo onActivityResult, donde almacenamos en
la variable url1 la referencia al archivo de audio creado:
protected void onActivityResult (int requestCode, int resultCode,
Intent data) {
if (resultCode == RESULT_OK && requestCode == peticion) {
url1 = data.getData();
}

Por ltimo para ejecutar el contenido de la grabacin utilizamos la clase ya vista MediaPlayer:
public void reproducir(View v) {
MediaPlayer mediaPlayer = MediaPlayer.create(this, url1);
mediaPlayer.start();
}
Final del proyecto025.

28 - Captura de audio mediante la clase


MediaRecorder
Otra forma de grabar audio en Android es el empleo de la clase MediaRecorder. Esta clase nos
da ms libertades a la hora de construir una aplicacin que requiere grabar audio.
Problema:

Disponer tres objetos de la clase Button con las etiquetas "Grabar", "Detener Grabacin" y
"Reproducir Grabacin". Disponer adems un TextView para informar del estado actual.
Cuando se presione el botn "Grabar" permitir registrar todos los sonidos hasta que se presione
el botn "Detener Grabacin". Cuando se presione el botn "Reproducir Grabacin" emitir el
archivo de audio previamente generado.
La interfaz visual a implementar es la siguiente:

Tener en cuenta de no olvidar definir los tres mtodos para los tres botones: grabar, detener y
reproducir.
Tambin debemos modificar el archivo AndroidManifest.xml donde debemos indicar que nuestra
aplicacin acceder a la grabadora de sonido y a la tarjeta SD donde se almacenar el archivo de
sonido.

Esto lo hacemos seleccionando el archivo AndroidManifest.xml y en la pestaa Permissions


registramos los dos permisos:

El cdigo fuente es:


package android.proyecto026;
import
import
import
import
import
import
import
import
import
import
import

java.io.File;
java.io.IOException;
android.app.Activity;
android.media.MediaPlayer;
android.media.MediaRecorder;
android.media.MediaPlayer.OnCompletionListener;
android.os.Bundle;
android.os.Environment;
android.view.View;
android.widget.Button;
android.widget.TextView;

public
class
Proyecto026Activity
OnCompletionListener {
TextView tv1;
MediaRecorder recorder;
MediaPlayer player;
File archivo;
Button b1,b2,b3;

extends

Activity

implements

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv1 = (TextView) this.findViewById(R.id.tv1);
b1=(Button)findViewById(R.id.button1);
b2=(Button)findViewById(R.id.button2);
b3=(Button)findViewById(R.id.button3);
}
public void grabar(View v) {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
File
path
=
new
File(Environment.getExternalStorageDirectory().getPath());
try {
archivo = File.createTempFile("temporal", ".3gp", path);
} catch (IOException e) {
}
recorder.setOutputFile(archivo.getAbsolutePath());
try {
recorder.prepare();
} catch (IOException e) {
}
recorder.start();
tv1.setText("Grabando");
b1.setEnabled(false);
b2.setEnabled(true);
}

public void detener(View v) {


recorder.stop();
recorder.release();
player = new MediaPlayer();
player.setOnCompletionListener(this);
try {
player.setDataSource(archivo.getAbsolutePath());
} catch (IOException e) {
}
try {
player.prepare();
} catch (IOException e) {
}
b1.setEnabled(true);
b2.setEnabled(false);
b3.setEnabled(true);
tv1.setText("Listo para reproducir");
}
public void reproducir(View v) {
player.start();
b1.setEnabled(false);
b2.setEnabled(false);
b3.setEnabled(false);
tv1.setText("Reproduciendo");
}

public void onCompletion(MediaPlayer mp) {


b1.setEnabled(true);
b2.setEnabled(true);
b3.setEnabled(true);

tv1.setText("Listo");
}
}
Declaramos un objeto de la clase MediaRecorder para grabar audio:
MediaRecorder recorder;
Declaramos un objeto de la clase MediaPlayer para reproducir el archivo de sonido generado:
MediaPlayer player;
Declaramos un objeto de la clase File que hace referencia al archivo que se crear:
File archivo;
Declaramos las variables que harn referencia a los tres botones y al TextView:
TextView tv1;
Button b1,b2,b3;
En el mtodo onCreate obtenemos la referencia de los cuatro objetos creados en el archivo XML:
tv1 = (TextView) this.findViewById(R.id.tv1);
b1=(Button)findViewById(R.id.button1);
b2=(Button)findViewById(R.id.button2);
b3=(Button)findViewById(R.id.button3);
El mtodo ms importante de este concepto es el grabar:
public void grabar(View v) {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
File path = new
File(Environment.getExternalStorageDirectory().getPath());
try {
archivo = File.createTempFile("temporal", ".3gp", path);
} catch (IOException e) {
}
recorder.setOutputFile(archivo.getAbsolutePath());
try {
recorder.prepare();
} catch (IOException e) {
}
recorder.start();
tv1.setText("Grabando");
b1.setEnabled(false);
b2.setEnabled(true);

}
Creamos un objeto de la clase MediaRecorder:
recorder = new MediaRecorder();
Seguidamente definimos el micrfono como fuente de audio:
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
Luego llamamos al mtodo setOutputFormat especificando que el archivo ser almacenado con
la especificacin 3GPP y con extensin .3gp
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
Especificamos el codec a emplear llamando al mtodo setAudioEncoder:
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
Obtenemos el path de la tarjeta SD y creamos un archivo temporal con extensin 3gp:
File path = new
File(Environment.getExternalStorageDirectory().getPath());
try {
archivo = File.createTempFile("temporal", ".3gp", path);
} catch (IOException e) {
}
Con el mtodo setOutputFile de la clase MediaRecorder le indicamos el archivo donde debe
almacenarse la grabacin:
recorder.setOutputFile(archivo.getAbsolutePath());
Llamamos al mtodo prepare y finalmente al mtodo start para comenzar la grabacin:
try {
recorder.prepare();
} catch (IOException e) {
}
recorder.start();
El mtodo detener:
public void detener(View v) {
recorder.stop();
recorder.release();
player = new MediaPlayer();
player.setOnCompletionListener(this);
try {
player.setDataSource(archivo.getAbsolutePath());
} catch (IOException e) {

}
try {
player.prepare();
} catch (IOException e) {
}
b1.setEnabled(true);
b2.setEnabled(false);
b3.setEnabled(true);
tv1.setText("Listo para reproducir");
}
Llamamos primero al mtodo stop de la clase MediaRecorder y liberamos los recursos
consumidos llamando a release:
recorder.stop();
recorder.release();
Creamos un objeto de la clase MediaPlayer para poder reproducir el archivo de audio que
acabamos de grabar. Indicamos mediante el mtodo setOnCompletionListener la referencia de la
clase que ser informada cuando el audio finalice:
player = new MediaPlayer();
player.setOnCompletionListener(this);
Referenciamos el archivo a que debe reproducir:
try {
player.setDataSource(archivo.getAbsolutePath());
} catch (IOException e) {
}
Finalmente llamamos al mtodo prepare de la clase MediaPlayer:
try {
player.prepare();
} catch (IOException e) {
}
El mtodo reproducir simplemente llama al mtodo start de la clase MediaPlayer para iniciar la
reproduccin del archivo previamente grabado:
public void reproducir(View v) {
player.start();
b1.setEnabled(false);
b2.setEnabled(false);
b3.setEnabled(false);
tv1.setText("Reproduciendo");
}
El mtodo onCompletion se ejecuta cuando termina de reproducirse el archivo de audio:

public void onCompletion(MediaPlayer mp) {


b1.setEnabled(true);
b2.setEnabled(true);
b3.setEnabled(true);
tv1.setText("Listo");
}
Final del proyecto026.

29 - Men de opciones
En Android la implementacin de un men de opciones permite mostrar opciones de una forma
estandarizada entre aplicaciones (esto hace que todos los programas tengan una vista de un
men muy parecidos)
Los mens aparecen en la parte inferior de la pantalla cuando el usuario presiona el botn Men
del celular.
La implementacin del men se puede hacer de forma similar a la interfaz visual de la aplicacin
mediante la creacin de un archivo XML y la construccin del mismo empleando las herramientas
que provee el plugin de Eclipse para Android.
Problema:

Confeccionar una aplicacin que muestre un men con dos opciones: una que visualice el
"Acerca de..." (nombre de la aplicacin, programador etc.) del programa y otra que finalice el
programa.
Lo primero que hacemos es crear el archivo XML que contendr el men de opciones
(presionamos el botn derecho del mouse sobre la carpeta res de nuestro proyecto y
seleccionamos New -> Android XML File):

Aparece un dilogo donde debemos indicar el nombre del archivo de recursos a crear (lo
llamamos menu1, este es el nombre del archivo XML que se crear en una carpeta llamada
menu que depende de la carpeta res) y seleccionamos el RadioButton de menu:

Ya tenemos una nueva carpeta llamada menu y un archivo llamado menu1:

La intefaz del editor de menu que nos provee el plugin de Android para Eclipse es:

Procedemos a insertar la primera opcin presionando el botn "Add", seguidamente


seleccionamos "Item":

Luego nos queda inicializar como mnimo el ttulo de que mostrar dicha opcin:

Ahora nuevamente presionamos el botn "Add" para aadir la segunda opcin. En el dilogo que
aparece seleccionamos "Create a new element at the top level, in Menu", seguidamente
seleccionamos "Item" y confirmamos:

Configuramos la propiedad Title de la segunda opcin:

Paso
seguido
debemos
sobreescribir
los
onOptionsItemSelected heredados de la clase Activity.

mtodos

onCreateOptionsMenu

El cdigo fuente de la clase Proyecto027Activity.java es:


package android.proyecto027;
import
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;
android.widget.Toast;

public class Proyecto027Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu1, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case
R.id.item1:
Toast.makeText(this,"Programador:
(23/08/2011)",Toast.LENGTH_SHORT).show(); break;
case R.id.item2: finish();
}
return true;
}
}

Diego

En el mtodo onCreateOptionsMenu creamos un objeto de la clase MenuInflater y mediante el


mtodo inflate vinculamos el identificador del archivo de recursos: R.menu.menu1 y el objeto de
la clase menu que llega como parmetro. Debemos retornar true:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu1, menu);
return true;
}

En el mtodo onOptionsItemSelected debemos disponer un switch para identificar cual de las


opciones del men fue seleccionado. El parmetro item de la clase MenuItem tiene la referencia
del objeto que fue pulsado. Luego obtenemos su Id llamando al mtodo getItemId y a travs del
switch verificamos con el recurso que coincide y procedemos a efectuar la actividad respectiva (si
se selecciona la primer opcin mostramos un mensaje mediante la clase Toast, si se seleccion
la segunda opcin llamamos al mtodo finish para finalizar el programa:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1: Toast.makeText(this,"Programador: Diego
(23/08/2011)",Toast.LENGTH_SHORT).show(); break;
case R.id.item2: finish();
}
return true;
}
Desde el emulador para activar el men debemos presionar el siguiente botn:

Final del proyecto027.

30 - Men de opciones con submen


Ahora veremos que podemos desplegar un submen cuando se selecciona una opcin del men
principal.
Problema:

Confeccionar una aplicacin que muestre un men con dos opciones: una que visualice el texto
"Sitios interesantes..." y al ser seleccionado muestre otro submen con una serie de buscadores.
y otra opcin en el men principal para que finalice el programa.
Creamos el archivo "Android XML File" siguiendo los mismos pasos indicados en el concepto
anterior, procedemos a crear el primer Item y luego creamos el submen para dicho menuitem
como lo indica la siguiente imagen:

Luego aadimos varios Menu Item al Sub-Menu (uno por cada sitio web a enlazar):

La estructura final del men de opciones debe ser la siguiente:

El cdigo fuente de la clase Proyecto028Activity.java es:


package android.proyecto028;
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Intent;
android.net.Uri;
android.os.Bundle;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;
android.widget.Toast;

public class Proyecto028Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu1, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent i;
switch (item.getItemId()) {
case R.id.item2: i = new Intent("android.intent.action.VIEW",
Uri.parse("http://www.google.com"));
startActivity(i);
break;
case R.id.item3: i = new Intent("android.intent.action.VIEW",
Uri.parse("http://www.yahoo.com"));
startActivity(i);
break;
case R.id.item4: i = new Intent("android.intent.action.VIEW",
Uri.parse("http://www.bing.com"));
startActivity(i);
break;
case R.id.item5: finish();
}
return true;
}
}

El mtodo onCreateOptionsMenu es idntico al concepto anterior. En el mtodo


onOptionsItemSelected verificamos cual de los MenuItem es seleccionado y procedemos a
invocar mediante un Intent al navegador configurado por defecto para el dispositivo.
La visualizacin del submen en tiempo de ejecucin es similar a:

Final del proyecto028.

31 - Men de opciones con conos en los


MenuItem
Otra posibilidad es disponer grficos dentro de los MenuItem de nuestro programa.
Problema:

Confeccionar una aplicacin que muestre un men con dos opciones: una que active el
navegador con YouTube y otra que active Facebook. Disponer un cono para cada MenuItem.
Luego de crear el proyecto procedemos a buscar dos conos representativos de Youtube y
Facebook (dos archivos png de 48 pxeles de ancho y alto) y los almacenamos en la carpeta
drawable-mdpi.
Luego de refrescar la carpeta debemos tener en nuestro proyecto en dicha carpeta tres archivos:

Procedemos seguidamente a crear el archivo Android XML File (recordemos que lo hacemos
presionando el botn derecho del mouse sobre la carpeta res y seleccionando New -> Android
XML File)
Creamos un menu llamado menu1 y seleccionamos el RadioButton Menu.
Ahora tenemos que crear los dos Item y especificar las propiedades Title (con el texto que
queremos que se muestre) y la propiedad Icon.
Para configurar cada icon procedemos a asignar los valores @drawable/youtube y
@drawable/facebook (los nombres coinciden con los nombres de archivos que copiamos a la
carpeta drawable)
Nos queda agregar solo la funcionalidad de cada MenuItem:
package android.proyecto029;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;

import
import
import
import

android.os.Bundle;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;

public class Proyecto029Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu1, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent i;
switch (item.getItemId()) {
case
R.id.item1:
i
=
Intent("android.intent.action.VIEW",
Uri.parse("http://www.youtube.com"));
startActivity(i);
break;
case
R.id.item2:
i
=
Intent("android.intent.action.VIEW",
Uri.parse("http://www.facebook.com"));
startActivity(i);
}
return true;
}
}

new

new

Luego cuando lo ejecutamos podemos observar el cono que se muestra en cada MenuItem:

Final del proyecto029.

32 - Men contextuales
Otra variante de men de opciones son los men contextuales que se pueden asociar a distintos
componentes visuales del formulario (TextView, EditText, ListView etc.)
Un men contectual aparece cuando el usuario presiona por un tiempo ms o menos prolongado
el control visual.
Problema:

Confeccionar una aplicacin que muestre un EditText y asociarle un men contextual que permita
cambiar el color de fondo del mismo. El men debe permitir seleccionar entre el rojo, verde y
azul.
Primero creamos un proyecto y creamos una interfaz con un control de tipo EditText:

Luego creamos el archivo XML que contendr el men de opciones (presionamos el botn
derecho del mouse sobre la carpeta res de nuestro proyecto y seleccionamos New -> Android
XML File):

Aparece un dilogo donde debemos indicar el nombre del archivo de recursos a crear (lo
llamamos menu1, este es el nombre del archivo XML que se crear en una carpeta llamada
menu que depende de la carpeta res) y seleccionamos el RadioButton de men
Ya tenemos una nueva carpeta llamada menu y un archivo llamado menu1.

Creamos las tres opciones del men:

Ahora veamos como asociar el archivo XML donde definimos el men con el cdigo Java:
package android.proyecto030;
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.graphics.Color;
android.os.Bundle;
android.view.ContextMenu;
android.view.ContextMenu.ContextMenuInfo;
android.view.MenuInflater;
android.view.MenuItem;
android.view.View;
android.widget.EditText;

public class Proyecto030Activity extends Activity {


EditText et1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.editText1);
registerForContextMenu(et1);
}
@Override

public
void
onCreateContextMenu(ContextMenu
v,ContextMenuInfo menuInfo)
{
menu.setHeaderTitle("Elija el color de fondo:");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu1, menu);
}

menu,

View

@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:et1.setBackgroundColor(Color.rgb(255, 0, 0)) ;
break;
case R.id.item2:et1.setBackgroundColor(Color.rgb(0, 255, 0)) ;
break;
case R.id.item3:et1.setBackgroundColor(Color.rgb(0, 0, 255)) ;
break;
}
return true;
}
}
En el mtodo onCreateContextMenu asociamos el archivo XML llamando al mtodo inflate de la
clase MenuInflate.
Podemos tambin llamar al mtodo setHeaderTitle para mostrar un ttulo en el men emergente.
@Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo
menuInfo)
{
menu.setHeaderTitle("Elija el color de fondo:");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu1, menu);
}

Para la captura de eventos de los MenuItem debemos implementar el mtodo


onContextItemSelected donde mediante un switch verificamos cual de los MenuItem fue
seleccionado y cambiamos el color de fondo del control EditText:
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:et1.setBackgroundColor(Color.rgb(255, 0, 0)) ;
break;
case R.id.item2:et1.setBackgroundColor(Color.rgb(0, 255, 0)) ;
break;
case R.id.item3:et1.setBackgroundColor(Color.rgb(0, 0, 255)) ;
break;
}
return true;
}

Final del proyecto030.

33 - AlertDialog simple
El dilogo ms simple que podemos crear con Android en una ventana con un ttulo, un mensaje
y un botn para cerrarlo.
Muy til si tenemos que informar al usuario y no queremos que la ventana desaparezca hasta
que el usuario presione un botn para ocultar el dilogo.
Problema:

Confeccionar una aplicacin que muestre un dilogo cada vez que se inicie la aplicacin
informando que el programa que est ejecutando es un programa de prueba y no el completo.
Primero creamos un proyecto llamado: proyecto031
Lo almacenamos en el paquete: android.proyecto031
El cdigo fuente de la aplicacin queda como sigue:
package android.proyecto021;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
public class Proyecto031Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Importante");
builder.setMessage("Este es un programa solo de prueba y no la
versin completa");
builder.setPositiveButton("OK",null);
builder.create();
builder.show();
}
}
Como queremos que el dilogo aparezca inmediatamente se arranque la aplicacin procedemos
a incorporar el cdigo en el mtodo onCreate.
Primero debemos importar la clase AlertDialog:
import android.app.AlertDialog;

La clase AlertDialog contiene otra clase llamada Builder que es la que encapsula la creacin de
objetos de la clase AlertDialog. Procedemos a definir y crear un objeto de la clase Builder
contenida en la clase AlertDialog:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
Una vez creado el objeto procedemos a llamar al mtodo que define el ttulo a mostrar en el
dilogo:
builder.setTitle("Importante");
El mensaje propiamente dicho lo configuramos llamando al mtodo setMessage:
builder.setMessage("Este es un programa solo de prueba y no la
versin completa");
Mostramos un botn para poder cerrar el dilogo:
builder.setPositiveButton("OK",null);
Finalmente llamamos al mtodo que crea el dilogo y el que lo visualiza:
builder.create();
builder.show();

La interfaz visual del dilogo en tiempo de ejecucin es:

Final del proyecto031.

34 - AlertDialog con botones de confirmar y


cancelar
Problema:

Confeccionar una aplicacin que muestre un dilogo cada vez que se inicie la aplicacin
informando: "Acepta la ejecucin de este programa en modo prueba?" y dos botones para
confirmar o rechazar. En caso que se rechace finalizar la ejecucin del programa.
Primero creamos un proyecto llamado: proyecto032
Lo almacenamos en el paquete: android.proyecto032
El cdigo fuente de la aplicacin queda como sigue:
package android.proyecto032;
import
import
import
import
import

android.app.Activity;
android.app.AlertDialog;
android.content.DialogInterface;
android.os.Bundle;
android.widget.Toast;

public class Proyecto032Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AlertDialog.Builder dialogo1 = new AlertDialog.Builder(this);
dialogo1.setTitle("Importante");
dialogo1.setMessage(" Acepta la ejecucin de este programa en
modo prueba ?");
dialogo1.setCancelable(false);
dialogo1.setPositiveButton("Confirmar",
new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogo1, int id) {
aceptar();
}
});
dialogo1.setNegativeButton("Cancelar",
new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogo1, int id) {
cancelar();
}
});
dialogo1.show();
}
public void aceptar() {

Toast t=Toast.makeText(this,"Bienvenido a probar el programa.",


Toast.LENGTH_SHORT);
t.show();
}
public void cancelar() {
finish();
}
}
Creamos un objeto de la clase AlertDialog a travs de la clase Builder:
AlertDialog.Builder dialogo1 = new AlertDialog.Builder(this);
Configuramos el ttulo del dilogo:
dialogo1.setTitle("Importante");
Configuramos el mensaje del dilogo:
dialogo1.setMessage(" Acepta la ejecucin de este programa en
modo prueba ?");
Evitamos que el dilogo sea salteado por cualquier medio distinto a presionar alguno de los dos
botones:
dialogo1.setCancelable(false);
Llamamos al mtodo setPositiveButton indicando el texto a mostrar en el botn y la clase
annima que capturar el evento clic del botn:
dialogo1.setPositiveButton("Confirmar",
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogo1, int id) {
aceptar();
}
});

new

De forma similar procedemos con el botn de cancelar:


dialogo1.setNegativeButton("Cancelar",
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogo1, int id) {
cancelar();
}
});
Mostramos el dilogo:
dialogo1.show();

new

Definimos los mtodos del Activity que se llamaran desde las clases annimas:
public void aceptar() {
Toast t=Toast.makeText(this,"Bienvenido a probar el programa.",
Toast.LENGTH_SHORT);
t.show();
}
public void cancelar() {
finish();
}
La interfaz del dilogo es similar a esta:

Final del proyecto032.

35 - Notificaciones o mensajes mediante la


clase Toast
La clase Toast nos permite mostrar un mensaje superpuesto a la ventana por un perodo de
tiempo pero sin congelar la aplicacin. Este mensaje no permite interactuar con el usuario (no se
pueden ingresar datos, seleccionar botones ni obligar a que se cierre)
Eventualmente se lo puede localizar en distintas partes del dispositivo.
Problema:

Confeccionar una aplicacin que muestre una serie de botones y active mensajes de
notificaciones con la clase Toast.
Primero creamos un proyecto llamado: proyecto033.
Lo almacenamos en el paquete: android.proyecto033
La interfaz visual a implementar son tres botones:

No olvidemos inicializar la propiedad On Click de cada botn con los mtodos: prueba1, prueba2
y prueba3.

El cdigo fuente de la aplicacin queda como sigue:


package android.proyecto033;
import
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.Gravity;
android.view.LayoutInflater;
android.view.View;
android.widget.Toast;

public class Proyecto033Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void prueba1(View v) {
Toast
toast
=
Toast.makeText(this,
Toast.LENGTH_SHORT);
toast.show();
}

"Mensaje

public void prueba2(View v) {


Toast
toast
=
Toast.makeText(this,
"Mensaje
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
public void prueba3(View v) {
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.toast1,
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
}

1",

2",

null);

}
Para el evento click del primer botn mostramos el mensaje con las estructura ms simple que
nos provee la clase Toast. Definimos un objeto de la clase Toast y llamamos al mtodo makeText
pasando como parmetro la referencia del Activity, el mensaje a mostrar y una constante
indicando si queremos que el mensaje aparezca por un perodo corto o largo de tiempo en la
pantalla. Por ltimo llamamos al mtodo show para que se muestre el mensaje:

public void prueba1(View v) {


Toast toast = Toast.makeText(this, "Mensaje 1",
Toast.LENGTH_SHORT);
toast.show();
}

Si queremos ubicar en otra parte de la pantalla debemos llamar al mtodo setGravity e indicar en
el primer parmetro una constante (en este ejemplo lo centramos verticalmente)
En el segundo y tercer parmetro de setGravity podemos desplazarlo una cantidad de pxeles
hacia derecha o izquierda, arriba o abajo segn indiquemos valores positivos o negativos.
Luego el mtodo completo para este segundo Toast es:

public void prueba2(View v) {


Toast
toast
=
Toast.makeText(this,
"Mensaje
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}

2",

Para generar un Toast customizado debemos crear un archivo XML donde creamos visualmente
los controles a mostrar, en este ejemplo creamos el siguiente archivo (crear un archivo llamado
toast1.xml):

Este recurso luego lo incorporamos en el Toast mediante el siguiente cdigo:


public void prueba3(View v) {
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.toast1,null);
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
}
Mediante la clase LayoutInflate procedemos a leer el contenido del archivo XML creado
anteriormente y lo enlazamos con el toast mediante el mtodo:
toast.setView(layout);

En pantalla luego el Toast customizado aparece de la siguiente forma:

Final del proyecto033.

36 - Dibujar: graficar un pxel


Problema:

Graficar un pxel de color blanco en medio de la pantalla del dispositivo.


Para poder hacer esta simple tarea debemos seguir una serie de pasos:
Creamos un proyecto llamado: proyecto034
Lo almacenamos en el paquete: android.proyecto034
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Ahora codificamos la clase donde se encuentra toda la lgica para encender el pxel:
package android.proyecto034;
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Canvas;
android.graphics.Paint;
android.os.Bundle;
android.view.View;
android.widget.LinearLayout;

public class Proyecto034Activity extends Activity {


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

LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);
linearLayout.addView(fondo);
}

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
int ancho=canvas.getWidth();
int alto=canvas.getHeight();
Paint pincel1=new Paint();
pincel1.setARGB(255,255,255,255);
canvas.drawPoint(ancho/2, alto/2, pincel1);
}
}
}
Debemos crear una clase que herede de la clase View (todos los controles visuales en Android
heredan de esta clase) y sobreescribir el mtodo onDraw. El mtodo onDraw se ejecuta cuando
tiene que graficarse. Para acceder a las primitivas grficas hay una clase llamada Canvas que
encapsula todo lo relacionado a pintar pxeles, lneas, rectngules etc.:
protected void onDraw(Canvas canvas) {
int ancho=canvas.getWidth();
int alto=canvas.getHeight();
Paint pincel1=new Paint();
pincel1.setARGB(255,255,255,255);
canvas.drawPoint(ancho/2, alto/2, pincel1);
}
Lo primero que hacemos en el mtodo onDraw es obtener el ancho y alto en pxeles del
dispositivo mediante los mtodos getWidth() y getHeight() que nos provee la clase Canvas.
Seguidamente creamos un objeto de la clase Paint. Llamamos al mtodo setARGB para definir el
color del pincel (el primer parmetro indica el valor de transparencia con 255 indicamos que no
hay transparencia, luego indicamos la cantidad de rojo, verde y azul.
Por ltimo debemos llamar al mtodo drawPoint que dibuja el pxel en la columna, fila y pincel
que le pasamos como parmetros.
Como podemos observar la clase Lienzo hereda de View e implementa el constructor donde
llegar la referencia del Activity donde se inserta:

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
int ancho=canvas.getWidth();
int alto=canvas.getHeight();
Paint pincel1=new Paint();
pincel1.setARGB(255,255,255,255);
canvas.drawPoint(ancho/2, alto/2, pincel1);
}
}
Por ltimo en el mtodo onCreate del Activity obtenemos la referencia del LinearLayout que
insertamos en el formulario previamente. Creamos un objeto de la clase Lienzo (llamado fondo) y
agregamos el objeto fondo al linealLayout llamando al mtodo addView:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);
linearLayout.addView(fondo);
}

Cuando ejecutemos el programa veremos un pxel en medio de la pantalla de color blanco:

Final del proyecto034.

37 - Dibujar: pintar fondo y dibujar lneas


Problema:

Pintar el fondo de color amarillo y dibujar una serie de lneas con distintos estilos.
Creamos un proyecto llamado: proyecto035
Lo almacenamos en el paquete: android.proyecto035
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Ahora codificamos la clase donde se encuentra toda la lgica para pintar el fondo y dibujar las
lneas:
package android.proyecto035;

import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Canvas;
android.graphics.Paint;
android.os.Bundle;
android.view.View;
android.widget.LinearLayout;

public class Proyecto035Activity extends Activity {


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

LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);
linearLayout.addView(fondo);
}

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,0);
int ancho=canvas.getWidth();
Paint pincel1=new Paint();
pincel1.setARGB(255,255,0,0);
canvas.drawLine(0, 30, ancho, 30, pincel1);
pincel1.setStrokeWidth(4);
canvas.drawLine(0, 60, ancho, 60, pincel1);
}
}
}
Veamos el mtodo onDraw donde pintamos el fondo de la componente llamando al mtodo
drawRGB donde indicamos la cantidad de rojo, verde a azul:
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,0);
Creamos un objeto de la clase paint y definimos el color rojo (recordemos que el primer
parmetro indica el valor de la transparencia, si vale 255 es totalmente opaco, con un valor
menor el trazo de la lnea tendr transparencia.
El mtodo para graficar una lnea se llama drawLine y tiene como parmetros la columna y fila
del punto inicial y el tercer y cuarto parmetro indica la columna y fila del punto final de la lnea
(en este ejemplo se dibujar una lnea horizontal en la fila 30 y tendr un ancho que coincide con
el ancho del dispositivo), el ltimo parmetro es el objeto de la clase Paint que indica el color de
la lnea:
Paint pincel1=new Paint();
pincel1.setARGB(255,255,0,0);
canvas.drawLine(0, 30, ancho, 30, pincel1);

La siguiente lnea la dibujamos en la fila 60 pero previamente cambiamos el grosor del pincel
llamando al mtodo setTrokeWidth indicando que sern 4 pxeles el grosor:
pincel1.setStrokeWidth(4);
canvas.drawLine(0, 60, ancho, 60, pincel1);

La vista previa en el dispositivo ser:

Final del proyecto035.

Problema propuesto
Confeccionar una aplicacin que muestre una hoja en la pantalla similar a esta:

Final del proyecto036.

38 - Dibujar: rectngulos
Problema:

Pintar el fondo de color blanco y dibujar una serie de rectngulos con distintos estilos.
1 - Creamos un proyecto llamado: proyecto037
Lo almacenamos en el paquete: android.proyecto037
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Ahora codificamos la clase donde se encuentra toda la lgica:


package android.proyecto037;
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Canvas;
android.graphics.Paint;
android.graphics.Paint.Style;
android.os.Bundle;
android.view.View;
android.widget.LinearLayout;

public class Proyecto037Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);

linearLayout.addView(fondo);
}

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,255);
int ancho=canvas.getWidth();
Paint pincel1=new Paint();
pincel1.setARGB(255,255,0,0);
canvas.drawRect(10,10,ancho-10,40,pincel1);
pincel1.setStyle(Style.STROKE);
canvas.drawRect(10,60,ancho-10,90,pincel1);
pincel1.setStrokeWidth(3);
canvas.drawRect(10,110,ancho-10,140,pincel1);
}
}
}
En el mtodo onDraw de la clase Lienzo procedemos a pintar el fondo de color blanco:
canvas.drawRGB(255,255,255);
Obtenemos el ancho del dispositivo:
int ancho=canvas.getWidth();
Creamos un objeto de la clase Paint:
Paint pincel1=new Paint();
Activamos el color rojo:
pincel1.setARGB(255,255,0,0);
Dibujamos un rectngulo desde la coordenada columna:10 y fila 10 hasta la columna que
coincide con el ancho de la pantalla menos 10 pxeles y la fila 40. Adems le pasamos el pincel a
utilizar:
canvas.drawRect(10,10,ancho-10,40,pincel1);

Para el siguiente rectngulo configuramos el pincel para que solo pinte el permetro llamando al
mtodo setStyle y pasando la constante STROKE:
pincel1.setStyle(Style.STROKE);
canvas.drawRect(10,60,ancho-10,90,pincel1);
Por ltimo dibujamos otro rectngulo que solo se pinta el permetro pero cambiamos el grosor del
lapiz llamando al mtodo setStrokeWidth:
pincel1.setStrokeWidth(3);
canvas.drawRect(10,110,ancho-10,140,pincel1);
La vista previa de la aplicacin es:

Final del proyecto037.

39 - Dibujar: crculos
Problema:

Pintar el fondo de color blanco y dibujar 10 crculos crecientes desde el medio de la pantalla.
Creamos un proyecto llamado: proyecto038
Lo almacenamos en el paquete: android.proyecto038
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Ahora codificamos la clase donde se encuentra toda la lgica:


package android.proyecto038;
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Canvas;
android.graphics.Paint;
android.graphics.Paint.Style;
android.os.Bundle;
android.view.View;
android.widget.LinearLayout;

public class Proyecto038Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);

linearLayout.addView(fondo);
}

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,255);
int ancho=canvas.getWidth();
int alto=canvas.getHeight();
Paint pincel1=new Paint();
pincel1.setARGB(255, 255, 0, 0);
pincel1.setStyle(Style.STROKE);
for(int f=0;f<10;f++) {
canvas.drawCircle(ancho/2, alto/2, f*15, pincel1);
}
}
}
}
Pintamos el fondo de blanco y obtenemos el ancho y alto del control:
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,255);
int ancho=canvas.getWidth();
int alto=canvas.getHeight();
Creamos un objeto de la clase Paint, fijamos el color rojo y mediante setStyle indicamos que solo
se debe pintar el permetro:
Paint pincel1=new Paint();
pincel1.setARGB(255, 255, 0, 0);
pincel1.setStyle(Style.STROKE);
Disponemos un for para dibujar los 10 crculos concntricos (indicamos en los dos primeros
parmetros el punto central del crculo y en el tercer parmetro el radio del crculo:
for(int f=0;f<10;f++) {
canvas.drawCircle(ancho/2, alto/2, f*15, pincel1);
}
}

La vista previa de la aplicacin es:

Final del proyecto038.

40 - Dibujar: valos
Problema:

Dibujar un valo que ocupe toda la pantalla y un crculo en su interior.


Creamos un proyecto llamado: proyecto039
Lo almacenamos en el paquete: android.proyecto039
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Ahora codificamos la clase donde se encuentra toda la lgica:


package android.proyecto039;
import
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Canvas;
android.graphics.Paint;
android.graphics.Paint.Style;
android.graphics.RectF;
android.os.Bundle;
android.view.View;
android.view.Window;
android.view.WindowManager;
android.widget.LinearLayout;

public class Proyecto039Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);
linearLayout.addView(fondo);
}

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,255);
int ancho=canvas.getWidth();
int alto=canvas.getHeight();
Paint pincel1=new Paint();
pincel1.setARGB(255,0,0,0);
pincel1.setStrokeWidth(5);
pincel1.setStyle(Style.STROKE);
RectF rectangulo1=new RectF(0,0,ancho,alto);
canvas.drawOval(rectangulo1, pincel1);
int menor;
if (ancho<alto)
menor=ancho;
else
menor=alto;
pincel1.setStyle(Style.FILL);
pincel1.setARGB(255, 255, 255, 0);
canvas.drawCircle(ancho/2, alto/2, menor/2, pincel1);
}
}
}
Para ocultar la barra del ttulo y la barra superior debemos hacer lo siguiente en el mtodo
onCreate:
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);
linearLayout.addView(fondo);
}

En el mtodo onDraw pintamos el fondo de blanco y obtenemos el ancho y alto de la pantalla:


protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,255);
int ancho=canvas.getWidth();
int alto=canvas.getHeight();

Seguidamente creamos el objeto de la clase Paint y configuramos el color, grosor de lnea y


estilo:
Paint pincel1=new Paint();
pincel1.setARGB(255,0,0,0);
pincel1.setStrokeWidth(5);
pincel1.setStyle(Style.STROKE);
Creamos un objeto de la clase RectT pasando como dato la coordenada superior izquierda del
valo y la coordenada inferior derecha del mismo (teniendo en cuenta que el valo se dibujar en
ese rectngulo imaginario que indicamos con dichas coordenadas):
RectF rectangulo1=new RectF(0,0,ancho,alto);
canvas.drawOval(rectangulo1, pincel1);
Obtenemos el valor menor del ancho y alto del dispositivo:

int menor;
if (ancho<alto)
menor=ancho;
else
menor=alto;
Configuramos ahora el pincel para dibujar el crculo y lo dibujamos:

pincel1.setStyle(Style.FILL);
pincel1.setARGB(255, 255, 255, 0);
canvas.drawCircle(ancho/2, alto/2, menor/2, pincel1);
}

La vista previa de la aplicacin es:

Final del proyecto039.

41 - Dibujar: texto
Otra recurso que nos permite la clase Canvas es el de graficar texto.
Creamos un proyecto llamado: proyecto040
Lo almacenamos en el paquete: android.proyecto040
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Ahora codificamos la clase donde se encuentra toda la lgica:


package android.proyecto040;
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Canvas;
android.graphics.Paint;
android.graphics.Typeface;
android.os.Bundle;
android.view.View;
android.view.Window;
android.view.WindowManager;
android.widget.LinearLayout;

public class Proyecto040Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);
linearLayout.addView(fondo);
}

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(0,0,255);
Paint pincel1=new Paint();
pincel1.setARGB(255,255,0,0);
pincel1.setTextSize(30);
pincel1.setTypeface(Typeface.SERIF);
canvas.drawText("Hola Mundo (SERIF)", 0, 70, pincel1);
pincel1.setTypeface(Typeface.SANS_SERIF);
canvas.drawText("Hola Mundo (SANS SERIF)", 0, 100, pincel1);
pincel1.setTypeface(Typeface.MONOSPACE);
canvas.drawText("Hola Mundo (MONOSPACE)", 0, 140, pincel1);
Typeface
tf=Typeface.create(Typeface.SERIF,
Typeface.ITALIC);
pincel1.setTypeface(tf);
canvas.drawText("Hola
Mundo
(SERIF
ITALIC)",
0,
180,
pincel1);
tf=Typeface.create(Typeface.SERIF,
Typeface.ITALIC
|
Typeface.BOLD);
pincel1.setTypeface(tf);
canvas.drawText("Hola Mundo (SERIF ITALIC BOLD)", 0, 220,
pincel1);
}
}
}
Para graficar texto disponemos del mtodo drawText que nos permite imprimir un String en una
determinada columna, fila con un determinado pincel que podemos definir su color:
Paint pincel1=new Paint();
pincel1.setARGB(255,255,0,0);
El tamao de la letra:

pincel1.setTextSize(30);
El estilo de la letra:
pincel1.setTypeface(Typeface.SERIF);
La interfaz del programa es:

Final del proyecto040.

42 - Dibujar: texto con fuentes externas


Podemos confeccionar aplicaciones e incorporar fuentes True Type externas. Para ello
implementaremos una aplicacin que muestre un texto con una fuente externa.
Creamos un proyecto llamado: proyecto041
Lo almacenamos en el paquete: android.proyecto041
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Procedemos ahora a descargar una fuente del sitio Creamundo y copiamos el archivo de la
fuente a la carpeta assets como se muestra:

Ahora codificamos la clase donde se encuentra toda la lgica:


package android.proyecto041;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;

import
import
import
import
import
import
import

android.graphics.Paint;
android.graphics.Typeface;
android.os.Bundle;
android.view.View;
android.view.Window;
android.view.WindowManager;
android.widget.LinearLayout;

public class Proyecto041Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);
linearLayout.addView(fondo);
}

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,255);
Paint pincel1=new Paint();
pincel1.setARGB(255,0,0,0);
pincel1.setTextSize(30);
Typeface
face
=
Typeface.createFromAsset(getAssets(),
"Action Man Shaded.ttf");
pincel1.setTypeface(face);
canvas.drawText("Hola Mundo", 0, 120, pincel1);
}
}
}
En el mtodo onDraw procedemos a crear una fuente llamando al mtodo createFromAsset e
indicando el nombre del archivo que descargamos de internet (disponga en el segundo parmetro
el nombre del archivo que eligi y descarg de internet):

Typeface
face
=
Typeface.createFromAsset(getAssets(),
"Action Man Shaded.ttf");
pincel1.setTypeface(face);
La interfaz del programa es:

Final del proyecto041.

43 - Dibujar: texto sobre un camino


Si queremos disponer texto no no est horizontal debemos crear un camino indicando los puntos
donde pasar el texto.
Creamos un proyecto llamado: proyecto042
Lo almacenamos en el paquete: android.proyecto042
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Ahora codificamos la clase donde se encuentra toda la lgica:


package android.proyecto042;
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Canvas;
android.graphics.Paint;
android.graphics.Path;
android.os.Bundle;
android.view.View;
android.view.Window;
android.view.WindowManager;
android.widget.LinearLayout;

public class Proyecto042Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);
linearLayout.addView(fondo);
}

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(0,0,255);
int alto=canvas.getHeight();
Path camino = new Path();
camino.moveTo(0, alto/2);
camino.lineTo(40, alto/2-30);
camino.lineTo(80, alto/2-60);
camino.lineTo(120, alto/2-90);
camino.lineTo(160, alto/2-120);
camino.lineTo(220, alto/2-150);
camino.lineTo(280, alto/2-180);
camino.lineTo(340, alto/2-210);
Paint pincel1=new Paint();
pincel1.setARGB(255,255,0,0);
pincel1.setTextSize(30);
canvas.drawTextOnPath("Hola Mundo Hola Mundo",camino, 0, 0,
pincel1);
}
}
}
Creamos un objeto de la clase Path e indicamos el primer punto del camino llamando al mtodo
moveTo:
Path camino = new Path();
camino.moveTo(0, alto/2);
Luego indicamos todos los otros puntos en forma consecutiva llamando al mtodo lineTo:
camino.lineTo(40, alto/2-30);
camino.lineTo(80, alto/2-60);
camino.lineTo(120, alto/2-90);

camino.lineTo(160,
camino.lineTo(220,
camino.lineTo(280,
camino.lineTo(340,

alto/2-120);
alto/2-150);
alto/2-180);
alto/2-210);

Luego para graficar el texto llamamos al mtodo drawTextOnPath y le pasamos en el segundo


parmetro la referencia del objeto de tipo Path:
canvas.drawTextOnPath("Hola Mundo Hola Mundo",camino, 0, 0,
pincel1);
La salida del programa es:

Final del proyecto042.

La vista previa de la aplicacin es:

Final del proyecto044.

44 - Dibujar: una imagen


Para mostrar un archivo jpg, png etc. disponemos el la clase Canvas de un mtodo llamado
drawBitmap.
Problema:

Mostrar el contenido de un archivo jpg centrado en la pantalla sabiendo que tiene un tamao de
250 pxeles de ancho por 200 de alto.
Creamos un proyecto llamado: proyecto043
Lo almacenamos en el paquete: android.proyecto043
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Descargar de internet una imagen y redimensionarla a 250*200 pxeles. Copiar dicho archivo a la
carpeta res/drawable-hdpi de nuestro proyecto (actualizar desde el Eclipse dicha carpeta):

Ahora codificamos la clase donde se encuentra toda la lgica:


package android.proyecto043;
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Bitmap;
android.graphics.BitmapFactory;
android.graphics.Canvas;
android.os.Bundle;
android.view.View;
android.view.Window;
android.view.WindowManager;
android.widget.LinearLayout;

public class Proyecto043Activity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
Lienzo fondo=new Lienzo(this);
linearLayout.addView(fondo);
}

class Lienzo extends View {


public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(0,0,255);
int ancho=canvas.getWidth();
int alto=canvas.getHeight();
Bitmap
bmp=BitmapFactory.decodeResource(getResources(),
R.drawable.imagen1);
canvas.drawBitmap(bmp, (ancho-250)/2,(alto-200)/2, null);
}
}
}

Para recuperar la imagen del archivo de la carpeta res/drawable-hdpi debemos utilizar el mtodo
decodeResource:
Bitmap bmp=BitmapFactory.decodeResource(getResources(),
R.drawable.imagen1);
Una vez que tenemos creado el objeto de la clase Bitmap procedemos a posicionar la imagen en
forma centrada en la pantalla del dispositivo:
canvas.drawBitmap(bmp, (ancho-250)/2,(alto-200)/2, null);
La vista previa de la aplicacin es:

Final del proyecto043.

45 - Evento touch: dibujar un crculo


Una actividad fundamental es poder detectar cuando el usuario selecciona o toca la pantalla
tctil.
Problema:

Desarrollar un programa que dibuje un crculo en la coordenada 100,100. Cuando se presione


otra parte de la pantalla tctil proceder a trasladar el crculo a dicha coordenada.
1 - Creamos un proyecto llamado: proyecto044
Lo almacenamos en el paquete: android.proyecto044
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a insertar
un objeto de la clase LinearLayout (vertical):

Ahora codificamos la clase donde se encuentra toda la lgica para capturar el evento onTouch:
package android.proyecto044;
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Canvas;
android.graphics.Paint;
android.os.Bundle;
android.view.MotionEvent;
android.view.View;
android.view.View.OnTouchListener;
android.widget.LinearLayout;

public
class
Proyecto044Activity
extends
Activity
OnTouchListener{
private int corx,cory;
private Lienzo fondo;
/** Called when the activity is first created. */

implements

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
linearLayout
(LinearLayout)findViewById(R.id.linearLayout1);
corx=100;
cory=100;
fondo=new Lienzo(this);
fondo.setOnTouchListener(this);
linearLayout.addView(fondo);
}

public boolean onTouch(View v, MotionEvent event) {


corx=(int)event.getX();
cory=(int)event.getY();
fondo.invalidate();
return true;
}
class Lienzo extends View {
public Lienzo(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,0);
Paint pincel1=new Paint();
pincel1.setARGB(255,255,0,0);
pincel1.setStrokeWidth(4);
pincel1.setStyle(Paint.Style.STROKE);
canvas.drawCircle(corx, cory, 20, pincel1);
}
}
}
La clase que captura el evento onTouch debe implementar la interface OnTouchListener (con
esto indicamos que la clase debe implementar el mtodo onTouch:
public class Proyecto044Activity extends Activity implements
OnTouchListener{
Definimos como atributos la coordenada donde se debe dibujar el crculo y la referencia al objeto
de la clase Lienzo:

private int corx,cory;


private Lienzo fondo;
En el mtodo onCreate del Activity inicializamos los tres atributos de la clase y mediante el
mtodo setOnTouchListener indicamos que la propia clase capturar el evento onTouch del
objeto fondo:
corx=100;
cory=100;
fondo=new Lienzo(this);
fondo.setOnTouchListener(this);
linearLayout.addView(fondo);
El mtodo onTouch es el que implementamos de la clase OnTouchListener. En este mtodo
mediante el objeto event obtenemos la coordenada x e y donde el usuario seleccion con el dedo
y procedemos a llamar al mtodo invalidate para que vuelva a pintarse el control fondo (el
mtodo invalidate borra el contendio del objeto de la clase Lienzo y vuelve a ejecutarse el mtodo
onDraw):
public boolean onTouch(View v, MotionEvent event) {
corx=(int)event.getX();
cory=(int)event.getY();
fondo.invalidate();
return true;
}
El mtodo onDraw pinta el fondo de amarillo, crea un objeto de la clase Paint y procede a dibujar
un crculo en las coordenadas indicadas por los atributos corx y cory:
protected void onDraw(Canvas canvas) {
canvas.drawRGB(255,255,0);
Paint pincel1=new Paint();
pincel1.setARGB(255,255,0,0);
pincel1.setStrokeWidth(4);
pincel1.setStyle(Paint.Style.STROKE);
canvas.drawCircle(corx, cory, 20, pincel1);
}

La vista previa de la aplicacin es:

Final del proyecto044.

46 - Evento touch: juego del buscaminas


Problema:

Implementar el juego del Buscaminas. Crear una grilla de 8*8 celdas.


1 - Creamos un proyecto llamado: BuscaMinas
Lo almacenamos en el paquete: android.BuscaMinas
Borramos el TextView que agrega automticamente el plug-in de Eclipse y procedemos a
inicializar la propiedad Id del LinearLayout con el valor LinearLayout1:

Luego codificamos las clases BuscaMinasActivity y Casilla:


package android.buscaminas;
public class Casilla {
public int x,y,ancho;
public int contenido=0;
public boolean destapado=false;
public void fijarxy(int x,int y, int ancho) {
this.x=x;
this.y=y;
this.ancho=ancho;
}
public boolean dentro(int xx,int yy) {
if
(xx>=this.x
&&
xx<=this.x+ancho
yy<=this.y+ancho)
return true;
else
return false;
}
}

&&

yy>=this.y

&&

Y la clase:
package android.buscaminas;
import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Context;
android.graphics.Canvas;
android.graphics.Paint;
android.graphics.Typeface;
android.os.Bundle;
android.view.MotionEvent;
android.view.View;
android.view.View.OnTouchListener;
android.view.Window;
android.view.WindowManager;
android.widget.LinearLayout;
android.widget.Toast;

public
class
BuscaMinasActivity
OnTouchListener {

extends

Activity

implements

private Tablero fondo;


int x,y;
private Casilla[][] casillas;
private boolean activo=true;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout
layout
(LinearLayout)findViewById(R.id.linearLayout1);
fondo=new Tablero(this);
fondo.setOnTouchListener(this);
layout.addView(fondo);
casillas=new Casilla[8][8];
for(int f=0;f<8;f++) {
for(int c=0;c<8;c++) {
casillas[f][c]=new Casilla();
}
}
this.disponerBombas();
this.contarBombasPerimetro();
}
public void presionado(View v) {
casillas=new Casilla[8][8];

for(int f=0;f<8;f++) {
for(int c=0;c<8;c++) {
casillas[f][c]=new Casilla();
}
}
this.disponerBombas();
this.contarBombasPerimetro();
activo=true;
fondo.invalidate();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (activo)
for(int f=0;f<8;f++) {
for(int c=0;c<8;c++) {
if
(casillas[f][c].dentro((int)event.getX(),(int)event.getY()))
{
casillas[f][c].destapado=true;
if (casillas[f][c].contenido==80)
{
Toast.makeText(this,"Booooooooommmmmmmmmmmm", Toast.LENGTH_LONG).show();
activo=false;
}
else
if (casillas[f][c].contenido==0)
recorrer (f, c);
fondo.invalidate();
}
}
}
if (gano() && activo)
{
Toast.makeText(this,"Ganaste", Toast.LENGTH_LONG).show();
activo=false;
}

return true;
}
class Tablero extends View {
public Tablero(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
canvas.drawRGB(0, 0,0 );
int ancho=0;

if (canvas.getWidth()<canvas.getHeight())
ancho=fondo.getWidth();
else
ancho=fondo.getHeight();
int anchocua=ancho/8;
Paint paint=new Paint();
paint.setTextSize(20);
Paint paint2=new Paint();
paint2.setTextSize(20);
paint2.setTypeface(Typeface.DEFAULT_BOLD);
paint2.setARGB(255, 0,0, 255);
Paint paintlinea1=new Paint();
paintlinea1.setARGB(255,255,255,255);
int filaact=0;
for(int f=0;f<8;f++) {
for(int c=0;c<8;c++) {
casillas[f][c].fijarxy(c*anchocua,filaact,anchocua);
if (casillas[f][c].destapado==false)
paint.setARGB(153, 204,204,204);
else
paint.setARGB(255, 153,153, 153);
canvas.drawRect(c*anchocua,
filaact,
c*anchocua+anchocua-2,filaact+anchocua-2,paint);
//linea blanca
canvas.drawLine(c*anchocua,
filaact,
c*anchocua+anchocua, filaact, paintlinea1);
canvas.drawLine(c*anchocua+anchocua-1,
filaact,
c*anchocua+anchocua-1, filaact+anchocua, paintlinea1);
if
(casillas[f][c].contenido>=1
casillas[f][c].contenido<=8 && casillas[f][c].destapado)

&&

canvas.drawText(String.valueOf(casillas[f][c].contenido),
c*anchocua+(anchocua/2)-8, filaact+anchocua/2, paint2);
if
(casillas[f][c].contenido==80
casillas[f][c].destapado)
{
Paint bomba=new Paint();
bomba.setARGB(255,255,0,0);
canvas.drawCircle(c*anchocua+(anchocua/2),
filaact+(anchocua/2), 8, bomba);
}
}
filaact=filaact+anchocua;
}
}
}

&&

private void disponerBombas ()


{
int cantidad = 8;
do
{
int fila = (int) (Math.random () * 8);
int columna = (int) (Math.random () * 8);
if (casillas[fila] [columna].contenido == 0)
{
casillas [fila] [columna].contenido=80;
cantidad--;
}
}
while (cantidad != 0);
}
private boolean gano()
{
int cant=0;
for (int f = 0 ; f < 8 ; f++)
for (int c = 0 ; c < 8 ; c++)
if (casillas [f] [c].destapado)
cant++;
if (cant==56)
return true;
else
return false;
}
private void contarBombasPerimetro ()
{
for (int f = 0 ; f < 8 ; f++)
{
for (int c = 0 ; c < 8 ; c++)
{
if (casillas [f] [c].contenido==0)
{
int cant = contarCoordenada (f, c);
casillas [f] [c].contenido=cant;
}
}
}
}
int contarCoordenada (int fila, int columna)
{
int total = 0;
if (fila - 1 >= 0 && columna - 1 >= 0)
{
if (casillas [fila - 1] [columna - 1].contenido == 80)
total++;

}
if (fila - 1 >= 0)
{
if (casillas [fila - 1] [columna].contenido == 80)
total++;
}
if (fila - 1 >= 0 && columna + 1 < 8)
{
if (casillas [fila - 1] [columna + 1].contenido == 80)
total++;
}
if (columna + 1 < 8)
{
if (casillas [fila] [columna + 1].contenido == 80)
total++;
}
if (fila + 1 < 8 && columna + 1 < 8)
{
if (casillas [fila + 1] [columna + 1].contenido == 80)
total++;
}
if (fila + 1 < 8)
{
if (casillas [fila + 1] [columna].contenido == 80)
total++;
}
if (fila + 1 < 8 && columna - 1 >= 0)
{
if (casillas [fila + 1] [columna - 1].contenido == 80)
total++;
}
if (columna - 1 >= 0)
{
if (casillas [fila] [columna - 1].contenido == 80)
total++;
}
return total;
}

private void recorrer (int fil, int col)


{
if (fil >= 0 && fil < 8 && col >= 0 && col < 8)
{
if (casillas [fil] [col].contenido==0)
{
casillas [fil] [col].destapado=true;
casillas [fil] [col].contenido=50;
recorrer (fil, col + 1);

recorrer
recorrer
recorrer
recorrer
recorrer
recorrer
recorrer

(fil, col
(fil + 1,
(fil - 1,
(fil - 1,
(fil - 1,
(fil + 1,
(fil + 1,

- 1);
col);
col);
col col +
col +
col -

1);
1);
1);
1);

}
else
if (casillas [fil] [col].contenido>=1 &&
[fil][col].contenido<=8)
{
casillas [fil] [col].destapado=true;
}
}
}
}
La interfaz visual de la aplicacin es:

Final del BuscaMinas.

casillas

47 - Archivo strings.xml
El archivo strings.xml se utiliza para almacenar todas las constantes de cadenas de caracteres que se
necesitan en un programa (por ejemplo las etiquetas de los objetos Button, los textos fijos de los controles
TextView y todos los controles que muestran un texto fijo en el dispositivo)

La idea fundamental es tener todos los mensajes que muestra nuestra aplicacin en un archivo
(strings.xml)
Ya veremos en el prximo concepto que uno de las ventajas que presenta esta agrupacin de
string es la posibilidad de facilitar la implementacin de aplicaciones en mltiples idiomas.
Problema:

Crear un proyecto que solicite la carga de dos valores. Mediante dos RadioButton permitir
seleccionar si queremos sumar o restar. Cuando se presione un botn mostrar en un TextView el
resultado de la operacin.
Creamos un proyecto llamado: proyecto045
Lo almacenamos en el paquete: android.proyecto045
El Plugin de Eclipse nos crea automticamente el archivo strings.xml en la carpeta values que se
encuentra en la carpeta res:

Si vemos en su interior podemos ver que ya define dos string llamados app_name y hello:

Lo que se encuentra entre las marcas string es lo que se visualizar, por ejemplo en la constante
hello se almacena el valor "Hello World, Proyecto045Activity!". En este archivo crearemos todas
las constantes a incluir en nuestro programa. Si vemos en la parte inferior de la ventana donde se
visualiza el archivo xml hay una pestaa llamada Resource que nos permite ingresar las distintas
constantes de una forma visual:

Creamos primero la interfaz visual disponiendo dos controles de tipo EditText, un RadioGroup
con dos RadioButton, un Button y un TextView donde se muestra el resultado de la operacin:

Ahora si crearemos los mensajes que mostrarn los dos RadioButton y el Button. Para esto
seleccionamos el archivo strings y procedemos a crear las tres constantes:

Una vez que tenemos abierto el archivo strings.xml en modo "Resources" procedemos a
presionar el botn "Add..." y seleccionamos "String":

Creamos los nombres de las constantes y los valores, por ejemplo para el mensaje que mostrar
el primer RadioButton llamamos la constante con el nombre "radiosuma" y el valor que almacena
es "Sumar"

De forma similar creamos las constantes "radioresta" con el valor "Restar" y el boton para operar
lo llamamos "botonoperacion" con el valor "Operar". Si seleccionamos la pestaa strings.xml
luego podemos ver las tres constantes que hemos creado (podemos borrar la constante que cre
el plugin de Eclipse "hello" ya que no lo utilizaremos):

Ahora debemos asociar estas constantes a los controles visuales. Seleccionamos el archivo
main.xml y seleccionamos primero el primer RadioButton y buscamos la propiedad Text,
presionamos el botn que aparece a la derecha:

En este dilogo seleccionamos la constante de string que acabamos de crear ("radiosuma"):

Ahora tenemos asociada la constante "radiosuma" con la propiedad text del control RadioButton.
Lo mismo podramos haber hecho esto escribiendo en la propiedad @string/radiosuma (@string
lo utilizamos para indicar que el siguiente dato despus de la barra se trata de una constante
definida en el archivo strings.xml)
Utilizar el dilogo de seleccin de recursos nos facilita no tener que recordar todas las
constantes.
Lo mismo hacemos para asociar las constantes para el segundo RadioButton y el Button de
operar. Es decir las propiedades text del radio1 debe quedar con el valor "@string/radioresta" y el
valor de la propiedad text del objeto button1 debe ser "@string/botonoperacion"
Como vemos cuando asociamos las propiedades text de los controles con las constantes
automticamente vemos en pantalla que los textos de los controles se actualizan con los valores
almacenados en dichas constantes.
Para que funcione nuestro programa inicializamos la propiedad On click del Button con el mtodo
que sumar o restar:

El cdigo fuente del programa ser:


package android.proyecto045;
import
import
import
import
import
import

android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.EditText;
android.widget.RadioButton;
android.widget.TextView;

public class Proyecto045Activity extends Activity {


EditText et1,et2;

RadioButton rb1,rb2;
TextView tv1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.editText1);
et2=(EditText)findViewById(R.id.editText2);
rb1=(RadioButton)findViewById(R.id.radio0);
rb2=(RadioButton)findViewById(R.id.radio1);
tv1=(TextView)findViewById(R.id.textView1);
}
public void operar(View v) {
int v1=Integer.parseInt(et1.getText().toString());
int v2=Integer.parseInt(et2.getText().toString());
if (rb1.isChecked()){
int suma=v1+v2;
tv1.setText(String.valueOf(suma));
}
else
if (rb2.isChecked()) {
int resta=v1-v2;
tv1.setText(String.valueOf(resta));
}
}
}
El resultado final del programa en el dispositivo es:

48 - Internacionalizacin y archivo
strings.xml
La internacionalizacin de un programa en Android se resuelve implementando varios archivos
strings.xml (uno por cada idioma que necesitemos implementar)
Problema:

Modificar el proyecto025 de tal manera que muestre su interfaz en castellano o ingles segn la
configuracin del idioma seleccionado en el dispositivo.
Crearemos primero una nueva carpeta llamada values-en (las abreviaturas para los distintos
lenguajes los podemos ver en la pgina ISO 639-1 Code (segunda columna)
Es decir creamos otra carpeta con el mismo nombre (values) ms un guin y la extensin del
lenguaje a implementar:

Creamos un archivo xml llamado strings.xml en la carpeta que acabamos de crear y copiamos
todo el archivo strings.xml de la otra carpeta values. Procedemos a traducir los valores
almacenados en cada string:

Solamente con esto ya tenemos nuestra aplicacin funcionando en dos idiomas. Para probar
debemos acceder al emulador de Android y configurarlo en ingls (tecla home -> tecla menu ->
configuracin > Idioma y teclado > Seleccionar idioma -> "English (United Stated)

Luego de esto lanzamos la aplicacin y deberemos ver la interfaz con los string que configuramos
en el archivo strings.xml de la carpeta values-en:

49 - Localizacin y archivo strings.xml


Hemos visto si queremos tener traducida nuestra aplicacin a varios idiomas debemos utilizar el
concepto de internacionalizacin. Pero hay muchos casos donde queremos hilar ms fino. Por
ejemplo el ingles de Estados Unidos no es exactamente igual que el ingles de Inglaterra o de
Autralia. Para estas situaciones podemos crear varios archivos strings.xml para distintas
localidades que tienen el mismo idioma.
Problema:

Modificar el proyecto025 de tal manera que muestre su interfaz no solo para el idioma por defecto
(espaol) e ingles, sino para el portugus de Brasil y el portugus de Portugal.
Las abreviaturas para los distintos lenguajes los podemos ver en la pgina ISO 639-1 Code
(segunda columna) y para obtener las distintas regiones utilizamos la tabla ISO 3166-1-alpha-2
Luego debemos crear una carpeta con el nombre values, luego un guin y el cdigo de
internacionalizacin, finalmente otro guin el caracter r y finalmente el cdigo de regin.
En nuestro problemas crearemos dos directorios llamados:
values-pt-rBR
values-pt-rPT
Luego de crear estos dos directorios copiaremos el archivo strings.xml de la carpeta values y
procederemos a traducirlo al portugus de Brasil y al portugus de Portugal.
Luego de crear las dos carpetas copiar el archivo strings.xml y proceder a traducirlo primero al
portugus de Brasil y luego en la otra carpeta traducirlo al portugus de Portugal, solo nos resta
compilar y probar la aplicacin.
Para probar debemos acceder al emulador de Android y configurarlo en portugus de Brasil (tecla
home -> tecla menu -> configuracin > Idioma y teclado > Seleccionar idioma -> "Portugus
(Brasil)

Seguidamente ejecutar la aplicacin y ver como resultado que tenemos los mensajes que
definimos en el archivo strings.xml asociado con el portugus de Brasil:

Lo mismo podemos luego configurar el idioma portugus de Portugal y obtener como resultado
en una nueva ejecucin del programa:

También podría gustarte