You are on page 1of 46

Search

Home

Blog

Sguenos

Trasteando un HTC Desire IV. Cambiando


HBOOT e instalando ROM

Concenos

Contacto

Creando una aplicacin de Android: primeros


pasos

Creando una aplicacin de Android: la


presentacin
Publicado el 21 julio, 2011 por meta
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Hace tiempo adquirimos un par de HTC Desire con la intencin de aprender un poco de desarrollo
de aplicaciones para dispositivos con Android. Buscando por la web se encuentran tutoriales y
guas muy buenas y snippets tambin muy buenos. Pero la mayora son cosas puntuales,
inconexas.
Bien, el objetivo de la siguiente serie de entradas ser el de desarrollar una aplicacin completa
para dispositivos con Android, empezando desde cero y acabando por la publicacin de la
aplicacin en el Market.
No os voy a engaar, a mi lo que me gustan son los juegos. Por esta razn, la aplicacin que
vamos a desarrollar ser el famoso Pong, pasando por todas las fases. Alguna de las fases ser
menos propia de Android, como la lgica del juego; alguna de las fases ser ms especfica de los
juegos que de una aplicacin tradicional, en este caso grficos y sonidos.
Sin embargo mi meta es, con la excusa de hacer un Pong, la explicacin del desarrollo de una
aplicacin completa tocando muchas de las cosas importantes de Android. Estas entradas
supondrn una gua, lo cual significa que los cdigos pueden no ser eficientes, que pueden estar
programados de una forma ms enfocada a la claridad, y que pueden no ser como yo hago mis
programas finales.
Cosas que vas a aprender:
Instalacin de las herramientas necesarias en Ubuntu (Linux): Android SDK, Eclipse IDE y el
puente entre ellos.
Crear proyectos de Android y entender para qu sirve cada fichero creado automticamente
por el IDE.
Crear una interfaz de usuario bsica, uso de imgenes y despligue de mensajes en pantalla.
Crear nuevas Actividades para usar en cada parte de la aplicacin.
Ejecutar las nuevas Actividades y pasar datos entre ellas.
Pintar elementos en pantalla (texto, formas primitivas).
Entender y usar el control tctil.
Crear hilos que se encarguen de tareas concretas.
Usar la vibracin del dispositivo.
Reproducir sonidos.
Usar Fonts propias.
Usar el acelermetro.
Impedir el bloqueo de la pantalla.
Crear una cuenta de Android Developer.
Publicar la aplicacin en el Android Market.
Crear una actualizacin de la aplicacin y publicarla.
Puedes descargar la aplicacin del Android Market antes de empezar el curso, para que veas qu

Categoras
Android
Curso introduccin
Android
Programacin
Seguridad
Sistemas Operativos

Entradas recientes
Colorshapes, el juego de
velocidad mental y figuras
de colores para Android
eyeOS: Trabajando en la
nube
Integrando Google
Analytics en aplicaciones
Android
Integrando Twitter en
aplicaciones Android con
SignPost y Twitter4J
Entrenando con
Metasploitable (IV). Desde
postgres a ssh, pasando
por openSSL

Etiquetas

activity
algoritmo android
aplicacion android
arbol backtrack bash BD
acelerometro

BEeF

canvas contraseas csrf

dns dns spoof

eclipse

expresiones regulares

graficos android

graphics android htc

desire intent java


javascript layout menu

vas a crear. El resultado ser como ste:

metasploit

metasploitable mitm
mysql oauth owasp

pentesting php seguridad


por defecto shodan

smartphones SQL SQLi


trasteando twitter twitter4j
VirtualBox wireshark xml xss
persistente

Sitios de inters
Android Developers
Android.es
Backtrack
Command Line Kung Fu
DragonJAR
El Androide Libre

Espero que sean de ayuda para todos los lectores!

EDITADO:

Exploits Database
Flu Project

El equipo de Android Market ha decidido a fecha 20-09-2011 retirar dicha aplicacin por violacin
de las polticas de contenido, a pesar de que nunca cobramos por dicha aplicacin ni obtuvimos
ganancias por publicidad ni negamos que Atari fuera la depositaria de los derechos de autor.

Gran Angular
Hispasec
Microsiervos

Por este motivo hemos decidido alojar la aplicacin en nuestro propio servidor para que pueda
seguir descargndose pulsando aqu (MD5: 039bf32bfaa8c64a6112bc364d456aa0).

OpenLibra
Pentester.es

Gracias a todos por vuestra comprensin y apoyo.

Poesa Binaria
Security By Default

Twittear

19

Share

Esta entrada fue publicada en Android, Curso introduccin Android, Programacin y etiquetada
como aplicacion android.

Trasteando un HTC Desire IV. Cambiando


HBOOT e instalando ROM

Creando una aplicacin de Android: primeros


pasos

4 Respuestas a Creando una aplicacin de Android: la


presentacin
1.

LuiS! dijo:
22 julio, 2011 at 0:07
Hmmm me gusta lo del pong !! Yo tenia uno por algun lado programado en Visual basic y la
verdad esque me enganche a programar con el pong hasta el punto de ir de empalmada a
clase xD. Tengo un par de ideas para juegos / programas de utilidad para android xD ya
hablaremos. Kisses!LuiS!
Responder

2. Pingback: Poesa binaria C.I. XII: La evolucin de la web, 20 aniversario de Linux, DateTime
para php, instalar Arch Linux, Creando una aplicacin en Android y un pedal con Arduino

3. Pingback: Aprendiendo Android | Blog Interno de Tecnologa

4.

Diseo de Pagina Web dijo:


29 agosto, 2012 at 23:04
Muy buenooo!!!
Responder

Deja un comentario
Tu direccin de correo electrnico no ser publicada. Los campos necesarios estn marcados *
Nombre *

Un informtico en el lado
del mal
World Wide Web
Consistorium

Home

Blog

Creando una aplicacin de Android: la


presentacin

Sguenos

Concenos

Contacto

Escribe aqu para buscar...

Inyecciones SQL. Qu son y como combatirlas

Creando una aplicacin de Android: primeros


pasos
Publicado el 21 julio, 2011 por meta
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Bienvenidos a la primera parte de la serie de entradas en el ciclo Creando una aplicacin de
Android. Si an no lo has hecho, comienza desde la primera entrada mostrada en el men
inmediatamente superior.
En esta entrada vamos a dar los primeros pasos en el desarrollo de nuestra aplicacin: instalar las
herramientas necesarias y crear nuestro Hello, world.
En este caso vamos a poner a punto el Android SDK sobre Eclipse (nuestro entorno de desarrollo),
y todo ello sobre Ubuntu 11.04. Sin embargo, esta entrada no tiene que ver con la instalacin de
Ubuntu, slo con la del SDK y el IDE.
Tngase en cuenta que las versiones de estas tres plataformas son las ltimas en el momento de
la publicacin de esta entrada
He de avisar de que lo que vamos a hacer en esta entrada ser descargar muchas cosas, lo cual va
a tardar bastante (sobre todo el Android SDK).
Comencemos!
Vamos a dar por hecho que tenemos nuestro Ubuntu 11.04 recin instalado. Lo primero que
debemos hacer ser actualizar el sistema (y lgicamente ponerlo a nuestro gusto con los
programas que queramos). Es en este momento cuando comenzamos la instalacin de las
herramientas.

Paso 0: preparacin
Ubuntu no trae instalado por defecto el Java SDK, por lo que lo primero que debemos hacer es
instalarlo. Para ello, abrimos una Terminal y escribimos:
sudoaptgetinstallsunjava6bin

Introducimos la contrasea del usuario y esperamos a que descargue los ~106MB de los paquetes
necesarios.
Nota: si el Ubuntu sobre el que estis trabajando es de 64 bits, necesitis ejecutar el siguiente
comando en una terminal:

Categoras
Android
Curso introduccin
Android
Programacin
Seguridad
Sistemas Operativos

Entradas recientes
Automatizando la
creacin de entornos de
desarrollo con Vagrant
Colorshapes, el juego de
velocidad mental y figuras
de colores para Android
eyeOS: Trabajando en la
nube
Integrando Google
Analytics en aplicaciones
Android
Integrando Twitter en
aplicaciones Android con
SignPost y Twitter4J

Etiquetas

activity
algoritmo android
aplicacion android
arbol backtrack bash BD
acelerometro

BEeF

canvas contraseas csrf

dns dns spoof

sudoaptgetinstallia32libs

eclipse

expresiones regulares

Esto es necesario porque el SDK usa las libreras de 32 bits.

graficos android

Recomendamos crearnos nuestro directorio de desarrollo, para tenerlo todo organizado. Por
ejemplo en /home/[user_name]/AndroidDev o /media/[data_disk]/AndroidDev.
Una vez completado esto, vamos al siguiente paso.

desire intent java

Paso 1: descargar Eclipse


Hemos elegido Eclipse como IDE solamente porque el Android SDK tiene un plugin para Eclipse
que hace la vida muy fcil y que lo integra perfectamente.
Lo primero que tenemos que hacer es ir a la pgina de descargas de Eclipse. Vamos a elegir la

graphics android htc


javascript layout menu

metasploit

metasploitable mitm
mysql oauth owasp

pentesting php seguridad


por defecto shodan

primera opcin (o al menos la que era primera opcin cuando se cre esta entrada), la cual es
Eclipse IDE for Java EE Developers, 210 MB. La web debera detectar que estamos en un Linux, y
sin haber hecho click en el link tendremos a la derecha las opciones Linux 32 bit y Linux 64 bit. En
mi caso, 32 bit. Elegimos el mirror y comenzamos la descarga. Eclipse no se instala, es portable,
por lo que el lugar donde lo descomprimimos es el lugar de la instalacin. Lo dejamos
descargando en la ubicacin que queramos y avanzamos al siguiente paso.

Paso 2: descargar Android SDK


Nos dirigimos a la pgina de descargas del Android SDK en Android Developers. Aqu elegiremos,
en nuestro caso, Linux (i386). Lo descargamos a nuestro disco en la ubicacin que queramos y lo
descomprimimos. Abrimos una terminal, y ejecutamos:
[path_development]/androidsdklinux_x86/tools/android

Donde [path_development] ser la ubicacin donde hayamos descomprimido el SDK (en el cual
tendremos el directorio android-sdk-linux_x86). Este comando nos mostrar el Android SDK and
AVD Manager, como en la siguiente imagen:

smartphones SQL SQLi


trasteando twitter twitter4j
VirtualBox wireshark xml xss
persistente

Sitios de inters
Android Developers
Android.es
Backtrack
Command Line Kung Fu
DragonJAR
El Androide Libre
Exploits Database
Flu Project
Gran Angular
Hispasec
Microsiervos
OpenLibra
Pentester.es
Poesa Binaria

Lo siguiente que vamos a hacer es instalar las API del SDK que vamos a querer. En nuestro caso
van a ser todas, por si quisiramos desarrollar para una versin ms o menos antigua. Para ello nos
vamos a Available Packages, y seleccionamos los dos grupos por completo.

Despus de esto hacemos click en Install Selected, en la parte inferior derecha.


Nos pedir que aceptemos las licencias de las API del SDK y veremos la siguiente pantalla:

Elegimos Accept All en la parte derecha y hacemos click en Install.


Tardar lo suyo en descargar todo, as que tranquilamente podemos navegar por
vidasConcurrentes durante un rato.
Eventualmente Eclipse se habr descargado, as que podemos ir descomprimindolo en la
ubicacin que hayamos elegido.
Una vez se hayan instalado las API volveremos a nuestra ventana del Android SDK and AVD
Manager, donde podemos pinchar en Installed Packages y comprobar que hemos instalado todo
correctamente:

Durante estos pasos debers reiniciar el adb al menos una vez, aunque slo hay que dar a S,
reiniciarlo cuando nos lo pida.

Security By Default
Un informtico en el lado
del mal
World Wide Web
Consistorium

Enhorabuena, has instalado el Android SDK!

Paso 3: configurar Eclipse con el Android SDK


Llegados a este punto, si hemos seguido todos los pasos, tendremos un directorio con lo siguiente:
Directorio con Eclipse (llamado eclipse).
Directorio con el Android SDK (llamado android-sdk-linux_x86).
Fichero comprimido con Eclipse.
Fichero comprimido con el Android SDK.
Podemos borrar ya los comprimidos. Ahora vamos a configurar Eclipse para funcionar con el
Android SDK. Para ello lo primero que tenemos que hacer es navegar hasta el directorio donde
descomprimimos Eclipse y ejecutar el fichero eclipse. Para mayor comodidad podemos aadir
este path a los paths del sistema, pero eso ya es cosa de cada uno.
Ejecutamos Eclipse y nos pedir la ruta del Workspace. Este workspace (espacio de trabajo) va a
ser el directorio donde se guarden todos nuestros proyectos. Podemos tener varios workspaces, o
podemos tener uno solo y usar siempre el mismo. En mi caso voy a usar esta instalacin de
Eclipse slo para Android, por lo que voy a crear mi workspace en
[path_development]/workspace, y voy a pulsar en la opcin de usar esta ruta y no volver a
preguntarme.
Cerramos la pestaita del inicio que nos ha salido la primera vez que hemos ejecutado Eclipse, y
nos encontramos el IDE listo para ser configurado.
Lo que vamos a hacer ahora es instalar el plugin de Eclipse para trabajar con el Android SDK. Para
ello vamos a Help > Install new software. En la parte superior nos encontramos con un campo de
texto y el botn Add a la derecha. Pulsamos sobre l para obtener lo siguiente:

Escribimos lo siguiente:
Name: Android Plugin (en realidad, el nombre que queramos darle).
Location: https://dl-ssl.google.com/android/eclipse
Y pulsamos en OK. En la siguiente pantalla debemos elegir todo y pulsar en Next:

Aceptamos la licencia e instalamos. Tendremos que reiniciar Eclipse para completar dicha
instalacin.
El ltimo paso de la configuracin es decirle a Eclipse dnde est el Android SDK. Para ello vamos
a Window > Preferences > Android, y donde pone SDK Location escribimos la ruta absoluta. Existe
un bug en el momento de la creacin de esta entrada, por el cual no podemos pulsar en Proceed
en el pop-up que veremos hasta que no escribamos la ruta y demos a Enter. Recomiendo escribir
la ruta en lugar de buscarlo con el botn Browse, para evitar quedarnos bloqueados.
Ahora s, hemos acabado de configurar las herramientas. Ahora es momento de comprobar que
funciona!

Paso 4: crear el Hello, world


Llegado este punto tendremos todas las herramientas necesarias para desarrollar aplicaciones
para Android. Sin embargo lo que no tenemos es el dnde. Disponemos de dos alternativas, a
saber: un dispositivo fsico (preferentemente) o un dispositivo virtual.
Dispositivo fsico: tenemos que conectar el dispositivo por USB y habilitar la Depuracin
USB. Para esto, y dependiendo de la versin de Android que tengamos (o en mi caso la
ROM instalada), tenemos que ir a Ajustes > Aplicaciones > Desarrollo y activar Depuracin
USB. Con esto, al ejecutar nuestro Hello, world se instalar y ejecutar en el dispositivo fsico
directamente.
Nota: podemos asegurarnos de que nuestro dispositivo est reconocido cuando, despus de
conectar ejecutamos:
[path_development]/androidsdklinux_x86/platformtools/adbdevices

Si hemos visto algn dispositivo, es que est reconocido perfectamente. Siempre podemos
reiniciar el servicio con los siguientes dos comandos:
cd[path_development]

androidsdklinux_x86/platformtools/adbkillserver
androidsdklinux_x86/platformtools/adbstartserver

Dispositivo virtual: si no disponemos de un dispositivo fsico podemos usar el emulador que


nos ofrece el Android SDK. Si bien es una opcin muy buena, no dispone de aceleracin
hardware ni soporte para muchas de las funcionalidades, as que un dispositivo fsico es
siempre la mejor opcin.
Para poder crear un dispositivo virtual vamos a Window > Android SDK and AVD Manager y
pulsamos en New. Damos un nombre a nuestro dispositivo virtual, por ejemplo
VirtualAndroid7. Y por qu 7? Pues porque en Target vamos a elegir Android 2.1-update1
API Level 7. Finalmente pulsamos en Create AVD.
Como paso final, nos queda crear un nuevo proyecto que sea nuestro Hello, world. Para ello
vamos a File > New > Project y buscamos Android > Android Project.
Damos nombre a nuestro proyecto, por ejemplo Hello world. Elegimos la API de nivel 7 para la
que hemos configurado el emulador (Android 2.1 es razonablemente viejo por ahora para obtener
buena compatibilidad en las aplicaciones).
Application Name lo dejamos como est. Package Name DEBE ser un nombre de paquete nico,
pues no podemos tener dos paquetes del mismo nombre en el mismo dispositivo. Lo ms normal
es poner nuestro namespace en el formato tpico en estos casos, por ejemplo para m:
com.vidasconcurrentes.helloworld.
Sin mirar ni siquiera al cdigo, hacemos click derecho en el proyecto y elegimos Run As >
Android Application.
Si todo ha ido bien, la aplicacin ejecutar. Si tenemos el dispositivo virtual creado, pero no hay
ningn dispositivo fsico conectado, esperamos a que cargue el emulador (puede tardar bastante)
y la aplicacin estar ejecutando:

Si por el contrario hemos conectado nuestro dispositivo fsico, tendremos algo parecido a lo
siguiente:

Hasta aqu la primera entrada del ciclo de entradas llamado Creando una aplicacin de Android.
En sucesivas entradas veremos cmo continuar, creando nuestra aplicacin y dando los primeros
pasos en las decisiones de diseo.
Hasta pronto!
Ms informacin:
Android Developers
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin

Home

Blog

Sguenos

Concenos

Inyecciones SQL. Qu son y como


combatirlas

Contacto

Escribe aqu para buscar...

Cross Site Scripting (XSS)

Creando una aplicacin de Android: visin de


conjunto y diseo del men
Publicado el 27 julio, 2011 por meta
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Bienvenidos a la segunda parte de la serie de entradas en el ciclo Creando una aplicacin de
Android. Si an no lo has hecho, comienza desde la primera entrada mostrada en el men
inmediatamente superior.
Como vimos en la primera parte de este ciclo de entradas, tenemos instalado y configurado
nuestro entorno de desarrollo Eclipse para trabajar con el Android SDK. En esta entrada vamos a
centrarnos en nuestro proyecto. Vamos a crearlo, vamos a comentar para qu sirve cada uno de
los ficheros que nos crea Eclipse al hacer el proyecto, vamos a explicar brevemente las partes de
las que va a consistir nuestra aplicacin y vamos a crear el men principal del juego.
El primer paso de esta entrada va a ser abrir nuestro Eclipse para poder comenzar a trabajar (duh).
Una vez haya cargado y hayamos elegido nuestro workspace, entraremos a Eclipse. Ahora vamos
a crear nuestro proyecto. Para ello vamos a File > New > Android Project (o si es nuestra primera
vez, File > New > Project y elegimos Android > Android Project en la ventana emergente).
En la ventana de creacin de proyecto que aparecer vamos a escribir y elegir lo siguiente:
Project Name: Pong-vC
Build Target: Android 2.1-update1 (API level 7)
Application Name: Pong-vC
Package Name: com.vidasconcurrentes.pongvc
Create Activity: PongvCActivity
Min SDK Version: 7
El resto de cosas que no he dicho las dejamos por defecto. Pero por qu hemos elegido estas
opciones?
El Build Target es la versin de Android mnima en la que vamos a querer que se ejecute nuestra
aplicacin. Esto significa que el SDK nos ofrecer las funciones que estn disponibles para esa
versin, y si elegimos una muy baja no tendremos ciertas funcionalidades. Por contra, si elegimos
una muy nueva, puede ser que los dispositivos ms antiguos no puedan ejecutar nuestra
aplicacin. En este compromiso vamos a elegir Android 2.1 porque nuestra aplicacin no va a
necesitar las funcionalidades del Android 2.3 y la 2.1 es una versin que es relativamente joven y
extendida.

Categoras
Android
Curso introduccin
Android
Programacin
Seguridad
Sistemas Operativos

Entradas recientes
Automatizando la
creacin de entornos de
desarrollo con Vagrant
Colorshapes, el juego de
velocidad mental y figuras
de colores para Android
eyeOS: Trabajando en la
nube
Integrando Google
Analytics en aplicaciones
Android
Integrando Twitter en
aplicaciones Android con
SignPost y Twitter4J

Etiquetas

activity
algoritmo android
aplicacion android
arbol backtrack bash BD
acelerometro

BEeF

canvas contraseas csrf

dns dns spoof

eclipse

El Application Name va a ser el texto que aparezca en nuestro dispositivo debajo del icono cuando
queramos ejecutarlo.

expresiones regulares

El Package Name es el nombre del paquete de esta aplicacin. Es importante recordar que en el
mismo dispositivo slo puede haber instalada una aplicacin con el mismo package name, por lo
que necesitamos que sea nico. Se recomienda que se usen las convenciones de nombrado de
paquetes de software, por las cuales debemos usar minsculas y usaremos el dominio de la
compaa empezando desde la derecha, y al final el nombre de nuestra aplicacin.

graphics android htc

El campo Create Activity sirve para crear la actividad por defecto. Tiene restricciones a la hora de
poner smbolos en el nombre, as que elegiremos nuestra actividad de dicha forma.

metasploitable mitm

El campo Min SDK Version contiene la versin del SDK que aparezca en el Build Target que
hayamos elegido. Normalmente se pone por defecto, pero debemos ponerla en caso contrario.

por defecto shodan

Ahora tenemos nuestro proyecto creado, con todos los ficheros por defecto. Veremos algo as:

graficos android

desire intent java


javascript layout menu

metasploit

mysql oauth owasp

pentesting php seguridad

smartphones SQL SQLi


trasteando twitter twitter4j
VirtualBox wireshark xml xss
persistente

Sitios de inters

Por lo que podemos ver, tenemos varios directorios, dos ficheros .java y tres ficheros .xml.
Veamos para qu sirve cada uno:

PongvCActivity.java: este es el fichero de la actividad por defecto que nos ha creado Eclipse.
Vamos a entender esto como el mainde una aplicacin Java tradicional, el punto de entrada
al ejecutar la aplicacin. Su cdigo es:
packagecom.vidasconcurrentes.pongvc;
importandroid.app.Activity;
importandroid.os.Bundle;
publicclassPongvCActivityextendsActivity{
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Esta clase hereda de Activity y redefine la funcin onCreate(). Esta funcin toma un Bundle,

Android Developers
Android.es
Backtrack
Command Line Kung Fu
DragonJAR
El Androide Libre
Exploits Database
Flu Project
Gran Angular
Hispasec
Microsiervos
OpenLibra
Pentester.es
Poesa Binaria
Security By Default
Un informtico en el lado
del mal
World Wide Web
Consistorium

que es la forma que tiene Android de pasar elementos primitivos entre actividades. Por as
decirlo (y muy cogido con pinzas) es como pasarle a la actividad el estado del sistema. Luego
usa la funcin setContentView(), que dice qu debe mostrarse en la pantalla. Ahora veremos
qu es R.layout.main.

R.java: este es un fichero generado automticamente por el propio Eclipse y que no


deberamos tocar bajo ningn concepto. Contiene informacin sobre los recursos que
pueden usarse (bajo el directorio res), de modo que podamos acceder a ello como una
constante escribiendo R.<directorio>.<recurso>.
main.xml: en este fichero se define la Interfaz de Usuario (UIen adelante). El plugin de
Android para Eclipse nos permite ver este fichero como texto o como un editor grfico, lo
cual simplifica mucho las cosas. Inicialmente contiene el siguiente cdigo:
<?xmlversion="1.0"encoding="utf8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>

Aqu vemos por primera vez LinearLayout. Define la forma de la que se van a distribuir los
elementos que vayan dentro de ella. En este caso, define que los elementos deben
colocarse uno detrs de otro. Existe una explicacin en detalle de todas las vistas y layouts
disponibles en Android Developers. Vemos que hay tambin un TextView, que es un widget
que permite mostrar un texto. Este texto puede ser hardcoded (es decir, escrito a mano ah)
o que venga del fichero strings.xml. Se recomienda usar la opcin de strings.xml siempre
que podamos, entre otras cosas porque nos ayudar a las traducciones de nuestros textos (si
queremos aceptar varios idiomas).

strings.xml: este fichero define cadenas de texto. Es muy til en situaciones de querer
cambiar un texto que aparece en muchos sitios, que en lugar de tener que buscarlo en todas
partes y cambiarlo, slo lo cambiamos aqu y ya aparece en todos.
AndroidManifest.xml: toda aplicacin debe tener este fichero en su directorio raiz, y entre
otras cosas define el nombre del paquete de la aplicacin, los componentes (actividades y
sus configuraciones, servicios), los permisos que necesita la aplicacin, el nivel de la API
mnimo que necesita, las libreras que el proyecto necesita Se puede editar (y de hecho
tendremos que editarlo antes o despus), y cuenta con una vista grfica muy buena para
esta edicin.
Hemos visto que en el directorio res encontramos todos los recursos (grficos tambin) que va a
usar el proyecto. layouts guarda las distribuciones, values guarda los strings, drawable guarda las
imagenes
Hasta aqu la explicacin de los componentes de nuestro proyecto creado por defecto.
Ahora s, vamos a empezar nuestro proyecto. Como hemos dicho, vamos a crear un Pong. Ser
una aplicacin sencilla, muy sencilla. La aplicacin ejecutar y mostrar un men desde el cual
podremos seleccionar tres opciones: Jugar, Opciones y Salir. Jugar ejecutar el juego, Opciones nos
llevar a elegir la configuracin del juego, y Salir cerrar la aplicacin. En esta entrada vamos a
crear este primer men.
Si ejecutamos el proyecto ahora (click derecho en el proyecto, Run as > Android Application),
veremos lo siguiente:

Como vemos, nos muestra la barra de notificaciones, el nombre de la aplicacin y lo que contiene
R.layout.main. Sin embargo nosotros no queremos que aparezca nada ms que nuestro
R.layout.main. Para hacer esto, vamos a aadir las siguientes lneas de cdigo en PongvCActivity:
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

Con esto estamos pidiendo al sistema de ventanas de Android que nos quite el nombre de la
aplicacin y que adems oculte la barra de notificaciones. Veremos lo siguiente:

Existe otra manera de hacer esto, y es modificando el AndroidManifest.xml. Sin embargo vamos a
hacerlo de forma programtica aqu (con cdigo) y haremos otra cosa de forma estructural (con los
xml) al final de la entrada. Ahora vamos a crear nuestro men. Esta aplicacin va a ser muy simple,
por lo que no vamos a fijarnos en que sea artstico, sino funcional. Para comenzar, vamos a crear
un nuevo directorio en res/ y vamos a llamarlo drawable. Dentro vamos a guardar estas tres
imgenes:

En mi caso, van a llamarse pong.png, button_bg.png y vc.png, respectivamente. Una vez


guardado, el fichero R.java se recrear y podremos acceder a estos recursos. Adems, queremos
que nuestro men tenga tres botones. Recordemos que hemos dicho que es importante usar el
fichero strings.xml todo lo posible. Por tanto, vamos a modificarlo para que sea de esta forma:

<?xmlversion="1.0"encoding="utf8"?>
<resources>
<stringname="hello">HelloWorld,PongvCActivity!</string>
<stringname="app_name">PongvC</string>
<stringname="menu_play">Jugar</string>
<stringname="menu_options">Opciones</string>
<stringname="menu_exit">Salir</string>
</resources>

Ahora vamos a modificar main.xml. El cdigo es el siguiente:

<?xmlversion="1.0"encoding="utf8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1">
<ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/pong"android:layout_gravity="center"android:layout_marginB
<TextViewandroid:layout_height="wrap_content"android:text="@string/menu_play"android:textAppearance="?android:attr/textAppearanceLarge"android:layout_width="wrap_c
<TextViewandroid:layout_height="wrap_content"android:text="@string/menu_options"android:textAppearance="?android:attr/textAppearanceLarge"android:layout_width="wra
<TextViewandroid:layout_height="wrap_content"android:text="@string/menu_exit"android:textAppearance="?android:attr/textAppearanceLarge"android:layout_width="wrap_c
<ImageViewandroid:id="@+id/imageView1"android:layout_width="314dp"android:layout_height="wrap_content"android:src="@drawable/vc"android:layout_gravity="center|bot
</LinearLayout>

Si hemos hecho todo como he explicado, no habr errores. Es tan largo porque est aplicado ya
un poco de maquetado para que quede colocado. Podemos ejecutar nuestra aplicacin ahora y
veremos lo siguiente:

Ahora solamente tenemos que darle funcionalidad a los elementos que hemos colocado. Esto lo
hacemos en el fichero PongvCActivity.java. Primero vamos a aadir funcionalidad al botn de
Jugar. Para ello, al final del cdigo que tenemos, escribimos:
TextViewplay=(TextView)findViewById(R.id.play_button);
play.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
Toast.makeText(getApplicationContext(),R.string.menu_play,
Toast.LENGTH_SHORT).show();
}
});

En este cdigo obtenemos el TextView cuyo identificador es play_button y le ponemos un


OnClickListener que detectar que hemos tocado con el dedo encima (evento de la accin click).
Adems vamos a crear annimamente este OnClickListener de modo que redefinimos su
comportamiento para la funcin onClick(). sta lo que hace es mostrar un mensaje en pantalla con
el texto del botn pulsado. As hemos visto cmo referirnos a un string desde los XML y desde el
cdigo Java.
El cdigo para los dems botones ser el mismo, slo cambiando el texto mostrado en el Toast.
Aqu est el cdigo completo para el fichero PongvCActivity.java:
packagecom.vidasconcurrentes.pongvc;
importandroid.app.Activity;
importandroid.content.Intent;
importandroid.net.Uri;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.view.Window;
importandroid.view.WindowManager;
importandroid.view.View.OnClickListener;
importandroid.widget.ImageView;
importandroid.widget.TextView;
importandroid.widget.Toast;
publicclassPongvCActivityextendsActivity{
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
TextViewplay=(TextView)findViewById(R.id.play_button);
play.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
Toast.makeText(getApplicationContext(),
R.string.menu_play,Toast.LENGTH_SHORT).show();
}
});
TextViewoptions=(TextView)findViewById(R.id.options_button);
options.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
Toast.makeText(getApplicationContext(),
R.string.menu_options,Toast.LENGTH_SHORT).show();
}
});
TextViewexit=(TextView)findViewById(R.id.exit_button);
exit.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
Toast.makeText(getApplicationContext(),
R.string.menu_exit,Toast.LENGTH_SHORT).show();
}
});
ImageViewlogo=(ImageView)findViewById(R.id.imageView1);
logo.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
IntentviewIntent=newIntent("android.intent.action.VIEW",
Uri.parse("http://www.vidasconcurrentes.com"));
startActivity(viewIntent);
}
});
}
}

Vamos a hacer un acto de fe en la ltima parte del cdigo y vamos a quedarnos con que el cdigo
del ultimo bloque hace que se abra el navegador web del dispositivo y lleve a este blog. En la
siguiente entrada explicaremos esto en detalle, pero para no hacer ms larga esta entrada vamos a
tomarlo as.
Ahora podemos ejecutar la aplicacin y por ejemplo tocar en Opciones, y veremos lo siguiente:

Slo nos queda un ltimo truco, y es irnos al AndroidManifest.xml y poner


android:screenOrientation=portrait en <activity android:name=.PongvCActivity
android:label=@string/app_name>. De esta manera obligamos a que no se cambie de
orientacin al mover el dispositivo, o si no encontraramos problemas como este al girarlo:

Hasta aqu la entrada de esta semana. En ella hemos visto cmo crear el proyecto de nuestra
aplicacin, de qu partes se compone este proyecto, para qu sirve cada una de estas partes,
hemos diseado nuestro men principal del juego y le hemos dado funcionalidad.
Puedes descargar el proyecto completo en un fichero comprimido, listo para importar en tu
Eclipse, pulsando aqu (MD5: 354b8fb840d9aeb6e91cb2ef35f3203f).
En la siguiente entrada crearemos el juego en s, todas las clases necesarias para representar un
Pong y la lgica de movimientos, adems de mostrar todo esto en pantalla al dar al botn Jugar
del men.
Un saludo a todos los lectores!
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Like

Twittear

Follow

Share

Esta entrada fue publicada en Android, Curso introduccin Android, Programacin y etiquetada
como activity, aplicacion android, eclipse, java, layout, menu.

Inyecciones SQL. Qu son y como


combatirlas

Cross Site Scripting (XSS)

5 Respuestas a Creando una aplicacin de Android: visin de


conjunto y diseo del men
1.

Gonzalo dijo:
9 febrero, 2014 at 14:48
Hola, en primer lugar gracias por tu aporte.
Quera comentarte que tengo algn problema a la hora de seguir los pasos.
En primer lugar el codigo que se me genera en PongvCActivity.java no es igual al que
muestras (esto puede ser por que estoy usando Ubuntu 13.10.
En segundo luegar a la hora de aadir el codigo:
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
me da error donde quiera que lo ponga.
Alguna sugerencia?
muchas gracias por todo

2.

Josue dijo:
5 septiembre, 2011 at 0:30
Fijate q yo quiero hacer q el pong funcione en 2 celulares por medjio de un servidor. Me
pregunto si me podrias explicar como hacerlo. Solo la explicacion sin la necesidad de poner
el codigo

meta dijo:
5 septiembre, 2011 at 0:43
As como primera idea, en fro se me ocurre nicamente lo siguiente:
Podras hacer que el servidor manejase, entre otras cosas, la coordenada en la que se
encuentra cada raqueta y la bola en cada momento. Continuamente (quiz en un
nmero fijo de veces por segundo), cada dispositivo se comunicara con el servidor
mandando paquetes de informacin (dependiendo de si es por Internet, Bluetooth
ser de forma distinta), y el servidor estara enviando a cada uno de los dispositivos
informacin sobre la posicin de ambas raquetas y de la bola.
Cada dispositivo recibira dicha informacin y la usara para actualizar su interfaz
(incluso podra detectar errores en la precisin del servidor o de s mismo, al incluir
redundancia en los datos contnuamente).
Cuando se marca un punto, el servidor sera notificado (l sabra qu tiene que hacer,
puesto que sabe la posicin de la bola siempre) y enviara tambin la informacin a los
dispositivos (o no, porque ellos tambin pueden llevar la cuenta de sus puntos en
local. Lo importante es que el volumen de informacin que se transfiera sea el mnimo
posible, para poder hacerlo rpido.
Es slo una idea, no tienes por qu seguirla ^^

Home

Blog

Cross Site Scripting (XSS)

Sguenos

Concenos

Contacto

Escribe aqu para buscar...

Creando una aplicacin de Android: el juego y la


lgica (parte 2)

Creando una aplicacin de Android: el juego y la


lgica (parte 1)
Publicado el 5 agosto, 2011 por meta
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Bienvenidos a la tercera parte de la serie de entradas en el ciclo Creando una aplicacin de
Android. Si an no lo has hecho, comienza desde la primera entrada mostrada en el men
inmediatamente superior.
Partiremos del resultado de la entrada anterior en la cual tenamos el men creado como en la
siguiente imagen:

En esta entrada vamos a crear el juego, incluyendo todas las clases necesarias para que funcione y
en la siguiente entrada crearemos la lgica de movimientos.
Comencemos!
Importante: esta entrada va a basarse en los cdigos creados en las anteriores entradas del ciclo al
que pertenece. Tienes disponible pinchando aqu (MD5: 354b8fb840d9aeb6e91cb2ef35f3203f)
el proyecto de Eclipse con todo lo hecho hasta ahora, el cual puedes importar a tu Eclipse y
comenzar a trabajar.
Lo primero que vamos a hacer es crear una nueva Activity que ser el juego, y que se ejecutar en
el momento en que pinchemos en el botn Jugar del men mostrado arriba.
Vamos a comenzar aadiendo una nueva clase a nuestro proyecto, que ser nuestra nueva
actividad. Sin embargo esta es la primera vez que vamos a crear una actividad sin que sea el
propio asistente de Eclipse el que cree el cdigo por defecto, y es interesante darse cuenta de que
no se sobrescribe la funcin onCreate() automticamente.
Hacemos click derecho sobre el paquete com.vidasconcurrentes.pongvc y seleccionamos New >
Class. En la ventana emergente que aparece vamos a donde pone Superclass y a la derecha
pulsamos en Browse. Escribimos android.app.Activity y aceptamos. Escribimos el nombre para
nuestra clase, por ejemplo PongJuego, y creamos la clase. Ahora pinchamos en Source >
Override/Implement methods, y buscamos onCreate(Bundle). Ahora nuestra clase debera ser
parecida a esta:

Categoras
Android
Curso introduccin
Android
Programacin
Seguridad
Sistemas Operativos

Entradas recientes
Automatizando la
creacin de entornos de
desarrollo con Vagrant
Colorshapes, el juego de
velocidad mental y figuras
de colores para Android
eyeOS: Trabajando en la
nube
Integrando Google
Analytics en aplicaciones
Android
Integrando Twitter en
aplicaciones Android con
SignPost y Twitter4J

Etiquetas

activity
algoritmo android
aplicacion android
arbol backtrack bash BD
acelerometro

BEeF

canvas contraseas csrf

dns dns spoof

eclipse

expresiones regulares

graficos android

graphics android htc

desire intent java


javascript layout menu

metasploit

metasploitable mitm
mysql oauth owasp

pentesting php seguridad


por defecto shodan

packagecom.vidasconcurrentes.pongvc;
importandroid.app.Activity;
importandroid.os.Bundle;

smartphones SQL SQLi


trasteando twitter twitter4j
VirtualBox wireshark xml xss

publicclassTestextendsActivity{

persistente

@Override
protectedvoidonCreate(BundlesavedInstanceState){
//TODOAutogeneratedmethodstub
super.onCreate(savedInstanceState);
}

Sitios de inters

Como vemos, no tiene un View que pintar, as que lo que vamos a hacer ahora es crearlo. Para
hacerlo, vamos a seguir el siguiente tutorial que hice hace unas semanas. Pincha en el enlace, sigue
los pasos y tendrs algo como esto:
PongJuego.java:
packagecom.vidasconcurrentes.pongvc;
importcom.vidasconcurrentes.pongvc.pintado.PongGameView;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.Window;
importandroid.view.WindowManager;
publicclassPongJuegoextendsActivity{
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(newPongGameView(this));
}
}

PongGameView.java:
packagecom.vidasconcurrentes.pongvc.pintado;
importandroid.content.Context;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceView;
publicclassPongGameViewextendsSurfaceView
implementsSurfaceHolder.Callback{
privatePongGameThreadpaintThread;
publicPongGameView(Contextcontext){
super(context);
getHolder().addCallback(this);
}
@Override
publicvoidsurfaceChanged(SurfaceHolderholder,intformat,
intwidth,intheight){}
@Override
publicvoidsurfaceCreated(SurfaceHolderholder){
paintThread=newPongGameThread(getHolder(),this);
paintThread.setRunning(true);
paintThread.start();
}
@Override
publicvoidsurfaceDestroyed(SurfaceHolderarg0){
booleanretry=true;
paintThread.setRunning(false);
while(retry){
try{
paintThread.join();
retry=false;
}catch(InterruptedExceptione){}
}
}
@Override
publicvoidonDraw(Canvascanvas){
canvas.drawColor(Color.WHITE);
}
}

PongGameThread.java:
packagecom.vidasconcurrentes.pongvc.pintado;
importandroid.graphics.Canvas;
importandroid.view.SurfaceHolder;
publicclassPongGameThreadextendsThread{
privateSurfaceHoldersh;
privatePongGameViewview;
privatebooleanrun;

Android Developers
Android.es
Backtrack
Command Line Kung Fu
DragonJAR
El Androide Libre
Exploits Database
Flu Project
Gran Angular
Hispasec
Microsiervos
OpenLibra
Pentester.es
Poesa Binaria
Security By Default
Un informtico en el lado
del mal
World Wide Web
Consistorium

publicPongGameThread(SurfaceHoldersh,PongGameViewview){
this.sh=sh;
this.view=view;
run=false;
}
publicvoidsetRunning(booleanrun){
this.run=run;
}
publicvoidrun(){
Canvascanvas;
while(run){
canvas=null;
try{
canvas=sh.lockCanvas(null);
synchronized(sh){
view.onDraw(canvas);
}
}finally{
if(canvas!=null)
sh.unlockCanvasAndPost(canvas);
}
}
}
}

Nota: es importante darse cuenta de que estas dos clases estn dentro de un nuevo paquete
llamado com.vidasconcurrentes.pongvc.pintado. Es interesante mantener los cdigos de nuestros
proyectos ordenados, y los paquetes nos ayudan a agrupar aquellas clases que sirven para el
mismo fin.
Ya tenemos todo lo necesario para pintar nuestra nueva Activity. Ahora slo nos falta ejecutarla.
Para ello vamos a usar un Intent. El Intent es una abstraccin para definir operaciones asncronas
como ejecutar nuevas actividades y pasar informacin entre stas, entre otras.
Una Activity creada de esta forma puede considerarse una sub-actividad si est previsto que
devuelva algn dato a la actividad que la cre. Contamos con dos funciones para crear actividades:

startActivity(): esta funcin crea una nueva Activity que no devolver informacin al acabar.
Una actividad creada de esta forma se considera una actividad aparte.
startActivityForResult(): esta funcin crea una sub-actividad que devolver ciertos valores al
finalizar. Cuando lo haga, la actividad que la cre entrara en su funcin onActivityResult(),
para procesar los datos necesarios.
Despus de esta breve teora, vamos a lo que nosotros necesitamos. Hemos de recordar que las
actividades forman una pila, de modo que si ejecutamos el juego desde el men y luego
acabamos esa actividad (por ejemplo con la tecla apropiada en nuestro terminal), vamos a volver
al men. Por ahora no vamos a necesitar guardar el progreso del juego, por lo que no vamos a
devolverle al men informacin alguna. Ejecutemos entonces nuestra nueva Activity. Recordemos
que nuestro men tena una parte del cdigo as:
[...]
TextViewplay=(TextView)findViewById(R.id.play_button);
play.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
Toast.makeText(getApplicationContext(),R.string.menu_play,
Toast.LENGTH_SHORT).show();
}
});
[...]

Pues ahora la modificamos para que sea as:


[...]
TextViewplay=(TextView)findViewById(R.id.play_button);
play.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
Toast.makeText(getApplicationContext(),R.string.menu_play,
Toast.LENGTH_SHORT).show();
empiezaJuego();
}
});
[...]

Donde la funcin empiezaJuego() es:


privatevoidempiezaJuego(){
Intentjuego=newIntent(this,PongJuego.class);
this.startActivity(juego);
}

El constructor de Intent recibe qu clase crea la Activity y de qu clase es esta Activity nueva. Slo
nos resta aadir cdigo a la funcin onCreate() de nuestra nueva Activity. Escribimos lo siguiente
en ella:
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(newPongGameView(this));
}

An nos falta una cosa, y es aadir nuestra nueva actividad al AndroidManifest.xml. Si no lo


aadimos no podremos ejecutar la actividad. Aadimos lo siguiente antes de </application>.
<activityandroid:name=".PongJuego"android:label="@string/app_name"
android:screenOrientation="landscape">
</activity>

Ahora s, podemos ejecutar nuestro proyecto. Click derecho sobre el proyecto, Run as > Android
Application. Si todo est bien hecho, veremos el men, y al pulsar sobre Jugar nos abrir una
nueva ventana con el fondo blanco. Ya hemos creado nuestra actividad para pintar el juego!
Lo siguiente que vamos a hacer son los elementos que van a hacer falta en el juego. Haciendo un
pequeo anlisis previo (con poca vista al futuro), vamos a necesitar una bola y dos raquetas.
Tanto las raquetas como la pelota tienen que moverse por la pantalla (y sin salirse), pero no
necesitan ms funcionalidad.
Es ahora el momento en el que diseamos nuestro juego. Debemos recordar que los ordenadores
(y en este caso nuestros dispositivos) son estpidos, no saben nada. Un computador no sabe qu
es una Raqueta, no sabe qu es una Bola, no sabe qu es una pantalla ni siquiera sabe qu es una
actividad. Sin embargo s que sabe qu es un nmero, qu es un carcter y qu es un booleano
(sabe qu es cada tipo de dato primitivo).
As que podemos pensar que una Raqueta es un rectngulo. Qu es un rectngulo? Un
rectngulo no es ms que un punto origen, un ancho y un alto. Y qu es un punto? Un punto va a
ser un par de coordenadas en un plano (la pantalla).
Por tanto tenemos que una Raqueta es dos nmeros que representan las coordenadas del origen,
un nmero que representa el ancho y un nmero que representa el alto. Y una Bola?
Recordemos que en el Pong original, la bola era un cuadrado. Por tanto, y teniendo en cuenta que
un Cuadrado es un Rectngulo con el ancho y alto iguales, podemos llegar a la conclusin de que
ambas tienen en comn su representacin. Esto nos permite pensar en una superclase
ElementoPong que tenga la funcionalidad necesaria para representar tanto Raquetas como Bolas.
Creamos un nuevo paquete llamado com.vidasconcurrentes.pongvc.juego. En l, creamos una
nueva clase llamada Coordenada, y escribimos el siguiente cdigo:
packagecom.vidasconcurrentes.pongvc.juego;
publicclassCoordenada{
privateintx;
privateinty;
publicCoordenada(intx,inty){
this.x=x;
this.y=y;
}
publicintgetX(){
returnx;
}
publicvoidsetX(intx){
this.x=x;
}
publicintgetY(){
returny;
}
publicvoidsetY(inty){
this.y=y;
}
}

Aadimos los getters y setters para ambos atributos porque queremos poder consultar sus valores
y cuando movamos los elementos, querremos modificarlos.
Ahora creamos una nueva clase llamada ElementoPong, y escribimos el siguiente cdigo:
packagecom.vidasconcurrentes.pongvc.juego;
importandroid.graphics.Rect;
publicabstractclassElementoPong{
protectedCoordenadaorigen;
protectedintancho;
protectedintalto;
publicElementoPong(Coordenadaorigen,intancho,intalto){
this.origen=origen;
this.ancho=ancho;
this.alto=alto;
}
publicintgetOrigenX(){
returnorigen.getX();
}
publicintgetOrigenY(){
returnorigen.getY();
}
publicintgetAncho(){
returnancho;

}
publicintgetAlto(){
returnalto;
}
publicRectgetRectElemento(){
returnnewRect(getOrigenX(),getOrigenY(),
getOrigenX()+ancho,getOrigenY()+alto);
}
}

Con esto estamos creando un elemento del juego. Con el modificador abstract en la declaracin
de la clase estamos diciendo que no se pueden instanciar objetos de esta clase, con lo que
obligamos a crear clases que hereden de sta (y por tanto hereden todos los atributos y
funcionalidad ya descrita). La funcin getRectElemento() nos ser til a la hora de pintar los
elementos, entre otras.
Adems querremos que nuestros elementos se muevan, pero cada uno se mover de forma
distinta. En este caso vamos a crear una interfaz que obligue a las clases que la implementen a
incluir una funcin para moverse. El cdigo es el siguiente:
packagecom.vidasconcurrentes.pongvc.juego;
publicinterfaceElementoPongMovil{
publicvoidmove();
}

Ahora slo resta crear nuestra clase Raqueta y nuestra clase Bola. El cdigo para la clase Raqueta
ser:
packagecom.vidasconcurrentes.pongvc.juego;
publicclassRaquetaextendsElementoPong
implementsElementoPongMovil{
publicRaqueta(Coordenadaorigen,intancho,intalto){
super(origen,ancho,alto);
}
@Override
publicvoidmove(){
}
}

Y el cdigo para la clase Bola ser:


packagecom.vidasconcurrentes.pongvc.juego;
publicclassBolaextendsElementoPong
implementsElementoPongMovil{
publicBola(Coordenadaorigen,intancho,intalto){
super(origen,ancho,alto);
}
@Override
publicvoidmove(){
}
}

Son iguales por ahora, ya que no hemos dado funcionalidad al mtodo move() an.
Para acabar con esta primera parte en la creacin de la Activity del juego, vamos a mostrar todo en
la pantalla. El primer paso va a ser aadir dos raquetas y una bola a nuestra aplicacin. Para ello,
vamos a la clase PongGameView y le aadimos los tres nuevos atributos, de modo que sean:
privatePongGameThreadpaintThread;
privateElementoPongraquetaIzda;
privateElementoPongraquetaDcha;
privateElementoPongbola;

Ahora instanciamos dichos atributos. Dependiendo de si nuestras instanciaciones van a necesitar


de las dimensiones de nuestra superficie, crearemos nuestros objetos en el constructor de
PongGameView si no lo necesitamos, o dentro del mtodo surfaceCreated() si vamos a
necesitarlo. En este caso vamos a necesitarlo, as que nuestro surfaceCreated() ser as:
@Override
publicvoidsurfaceCreated(SurfaceHolderholder){
raquetaIzda=newRaqueta(newCoordenada(50,getHeight()/250),
20,100);
raquetaDcha=newRaqueta(newCoordenada(getWidth()70,
getHeight()/250),20,100);
bola=newBola(newCoordenada(getWidth()/25,getHeight()/25),
10,10);
paintThread=newPongGameThread(getHolder(),this);
paintThread.setRunning(true);
paintThread.start();
}

Esto hace que tengamos las raquetas en los laterales a la misma distancia de su pared, y la bola
centrada en pantalla. Las raquetas sern de 20100 pxeles mientras que la bola ser de 1010
pxeles.

Slo nos resta aadir cdigo al pintado para que muestre dichos elementos. Para ello
modificamos el mtodo onDraw() de la siguiente forma:
@Override
publicvoidonDraw(Canvascanvas){
Paintpaint=newPaint();
paint.setColor(Color.WHITE);
canvas.drawColor(Color.BLACK);
canvas.drawRect(raquetaIzda.getRectElemento(),paint);
canvas.drawRect(raquetaDcha.getRectElemento(),paint);
canvas.drawRect(bola.getRectElemento(),paint);
}

Et voil! Podemos ejecutar nuestra aplicacin y probar que lo que hemos hecho est bien. Si has
seguido el tutorial paso a paso, tendrs lo siguiente al pulsar Jugar en el men:

En esta entrada hemos continuado el cdigo de la entrada anterior en la que tenamos un men, y
hemos aadido la funcionalidad para que al pulsar en un determinado elemento del men se cree
nuestro juego. Adems hemos creado las clases necesarias para representar nuestro juego y
hemos pintado estos elementos en pantalla.
Puedes descargar el proyecto de Eclipse con todo lo hecho hasta ahora pulsando aqu (MD5:
e50037a2c1219ea0b5e8e464c72390aa). Adems puedes importarlo a tu workbench
directamente y trabajar con ello.
En la siguiente entrada vamos a crear la lgica del juego: movimientos de las raquetas,
movimiento de la pelota, restricciones de dichos movimientos (que no se salga de la pantalla, que
rebote la pelota) y la creacin del bucle de juego.
Un saludo a todos los lectores, y gracias por dedicarle tiempo!
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Like

Twittear

Follow

Share

Esta entrada fue publicada en Android, Curso introduccin Android, Programacin y etiquetada
como activity, aplicacion android, eclipse, graficos android, intent, java.

Cross Site Scripting (XSS)

Creando una aplicacin de Android: el juego y la


lgica (parte 2)

4 Respuestas a Creando una aplicacin de Android: el juego y la


lgica (parte 1)
1.

william ayala dijo:


20 noviembre, 2013 at 6:39
Hola muy buen sitio, a la vez necesitando de su ayuda, soy nuevo en programacin y
estamos trabajando en hacer un gps en android el problema es que no me genera error, y
pues no se ejecuta me gustara si me dan la oportunidad de enviarles una copia de mi
proyecto y los detalles especficos por email, saludos desde el salvador y gracias

2.

Rohe dijo:
30 octubre, 2013 at 18:50
Si no quisiera pintar un rectangulo sino un Bitmap, la clase elementopong, solo cambiara en
el mtodo public Rect getRectElemento()? o qu debera hacer?

Home

Blog

Sguenos

Creando una aplicacin de Android: el juego y


la lgica (parte 1)

Concenos

Contacto

Escribe aqu para buscar...

Fingerprinting con wireshark y FOCA

Creando una aplicacin de Android: el juego y la


lgica (parte 2)
Publicado el 8 agosto, 2011 por meta
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Bienvenidos a la cuarta parte de la serie de entradas en el ciclo Creando una aplicacin de Android.
Si an no lo has hecho, comienza desde la primera entrada mostrada en el men inmediatamente
superior.
Esta entrada se basa en el resultado de completar la anterior parte, en la que construamos una
nueva Activity para ejecutar nuestro juego. Adems crebamos las clases necesarias para el
pintado del juego y las necesarias para representar los elementos del juego. El resultado al que
habamos llegado era mostrar lo siguiente:

En esta entrada vamos a completar la lgica del juego, haciendo que las raquetas y la bola se
muevan y, en definitiva, se pueda jugar.
Comenzamos!
Importante: esta entrada va a basarse en los cdigos creados en las anteriores entradas del ciclo al
que pertenece. Tienes disponible pinchando aqu (MD5: e50037a2c1219ea0b5e8e464c72390aa)
el proyecto de Eclipse con todo lo hecho hasta ahora, el cual puedes importar a tu Eclipse y
comenzar a trabajar.
Nota: esta entrada es bastante larga, pero incluye mucho cdigo. Quedis avisados!
Recordemos que en la anterior entrada creamos una serie de clases que nos iban a servir para
representar nuestros elementos del juego. Disponamos de una superclase ElementoPong que
describa la representacin de un elemento del juego (un rectngulo definido por una coordenada
origen, un ancho y un alto), una interfaz ElementoPongMovil que obliga a implementar el mtodo
move() y dos clases que heredaban de la primera e implementaban la segunda (Raqueta y Bola).
Vamos a comenzar con el movimiento de las palas. Queremos que se muevan al tocar con el
dedo sobre ellas, y se muevan donde vaya nuestro dedo.
Para hacer esto, vamos a sobrescribir el mtodo onTouchEvent() en nuestro PongGameView:
@Override
publicbooleanonTouchEvent(MotionEventevent){
intx=(int)event.getX();
inty=(int)event.getY();
returntrue;
}

Categoras
Android
Curso introduccin
Android
Programacin
Seguridad
Sistemas Operativos

Entradas recientes
Automatizando la
creacin de entornos de
desarrollo con Vagrant
Colorshapes, el juego de
velocidad mental y figuras
de colores para Android
eyeOS: Trabajando en la
nube
Integrando Google
Analytics en aplicaciones
Android
Integrando Twitter en
aplicaciones Android con
SignPost y Twitter4J

Etiquetas

activity
algoritmo android
aplicacion android
arbol backtrack bash BD
acelerometro

BEeF

canvas contraseas csrf

dns dns spoof

eclipse

expresiones regulares

graficos android

graphics android htc

desire intent java


javascript layout menu

metasploit

metasploitable mitm
mysql oauth owasp

pentesting php seguridad


por defecto shodan

De esta forma estamos detectando las coordenadas X e Y en las que se ha detectado el evento,
aunque de momento no hacemos nada con ellas. El siguiente paso es detectar qu tipo de accin
se ha hecho. Hemos pulsado, hemos arrastrado o hemos levantado el dedo? Son los tres eventos
que vamos a detectar. Para ello aadimos lo siguiente:
@Override
publicbooleanonTouchEvent(MotionEventevent){
intx=(int)event.getX();
inty=(int)event.getY();
switch(event.getAction()){
caseMotionEvent.ACTION_DOWN:
//hemospulsado
break;
caseMotionEvent.ACTION_MOVE:
//hemosarrastrado
break;
caseMotionEvent.ACTION_UP:
//hemoslevantado
break;
}
returntrue;
}

El evento ACTION_DOWN se produce en el momento en que tocamos con el dedo en pantalla.


El evento ACTION_MOVE se produce cuando, despus de un ACTION_DOWN, movemos el
dedo sin levantarlo. Finalmente, el evento ACTION_UP se produce al levantar el dedo de la
pantalla.

smartphones SQL SQLi


trasteando twitter twitter4j
VirtualBox wireshark xml xss
persistente

Sitios de inters
Android Developers
Android.es
Backtrack
Command Line Kung Fu
DragonJAR
El Androide Libre
Exploits Database
Flu Project
Gran Angular
Hispasec
Microsiervos
OpenLibra

En nuestro Pong vamos a querer poder mover la raqueta izquierda y la raqueta derecha, pero la
bola deber moverse sola. Por tanto, en nuestro ACTION_DOWN vamos a ver si hemos tocado
en la raqueta izquierda, la derecha o en ninguna de ellas (siendo el estado inicial ninguna). Si
hemos tocado en una de las dos, tenemos que quedarnos con cual es la que hemos tocado para
poder aplicarle los movimientos del ACTION_MOVE. Una vez que hagamos ACTION_UP lo que
haremos ser decir ya no estoy tocando ninguna de las raquetas.

Pentester.es
Poesa Binaria

Formas de hacer esto hay muchas y muy buenas, como por ejemplo usar un identificador para
cada elemento, tener una coleccin de elementos mviles y pulsables y luego iterar sobre ella
para encontrar el elemento sobre el que se puls y quedarse con su identificador Sin embargo
nosotros vamos a hacerlo simple, puesto que slo vamos a permitir tocar en dos figuras (y eso
slo cuando jueguen dos personas). Adems, para calcular un desplazamiento, necesitamos la
posicin que vamos a llamar origen y la actual.

World Wide Web


Consistorium

Lo primero, entonces, ser aadir un nuevo parmetro al PongGameView, que ser el elemento
activo, y el origen del movimiento, que ser la posicin del eje Y donde hemos puesto el dedo:
privateElementoPongelementoActivo=null;
privateintorigenY;

Se inicializa a null porque inicialmente no hay ningn elemento activo.


Ahora vamos a modificar el caso del ACTION_DOWN de la siguiente forma:
caseMotionEvent.ACTION_DOWN:
//hemospulsado
if(raquetaIzda.getRectElemento().contains(x,y)){
elementoActivo=raquetaIzda;
origenY=y;
break;
}
if(raquetaDcha.getRectElemento().contains(x,y)){
elementoActivo=raquetaDcha;
origenY=y;
break;
}
break;

Lo que hacemos es asignar al elemento activo el elemento sobre el que hemos tocado (si es que
hemos tocado en alguno), y adems asignamos el la posicin Y en la que hemos pulsado a nuestra
variable origenY. Repetimos el cdigo de la asignacin en lugar de hacerlo siempre para evitar
asignaciones innecesarias (los dispositivos son suficientemente rpidos como para procesar unas
miles de asignaciones extra pero es interesante valorar el lugar donde vamos a poner nuestras
instrucciones con respecto del nmero de veces que se ejecutarn). El mtodo contains(int,int) de
la clase Rect nos viene de perlas para no tener que hacer una lnea con 4 and. Aunque nunca en
nuestro juego puede darse que estemos tocando la raqueta izquierda y adems la raqueta
derecha, hacemos un break despus de asignar el elemento para curarnos en salud, y de paso
ejecutar un par de operaciones menos.
Lo siguiente que vamos a hacer es el caso del ACTION_UP, que es tan simple como volver a null
el elemento activo. La variable origenY no la vamos a devolver a ningn estado nulo porque no
nos hace falta (no hacemos comprobaciones con ella). Podramos hacer una comprobacin para
poner null si el elemento activo no lo es ya, pero como en nuestro caso queremos que no haya
nada activo al soltar, lo hacemos de la siguiente forma:
caseMotionEvent.ACTION_UP:
//hemoslevantado
elementoActivo=null;
break;

Finalmente, el caso de arrastrar. El concepto es: si hemos pulsado en un elemento durante el


ACTION_DOWN, entonces queremos moverle. Sin embargo, no queremos que nuestras raquetas
se muevan horizontalmente, sino slo verticalmente. Por tanto la modificacin de la coordenada

Security By Default
Un informtico en el lado
del mal

ser slo en la Y. Recordemos que en los grficos de Android (y en Java en general), se considera el
origen de coordenadas la esquina superior izquierda, y no la inferior izquierda como en un sistema
de coordenadas cartesianas. Por tanto, si vamos hacia abajo sumamos y si vamos hacia arriba
restamos.
Es, por tanto, el momento de implementar el mtodo move() para las raquetas. Por ahora, vamos
a tomar la decisin de diseo de cambiar el mtodo move() de la interfaz ElementoPongMovil,
para hacerla de la siguiente forma:
packagecom.vidasconcurrentes.pongvc.juego;
publicinterfaceElementoPongMovil{
publicvoidmove(intx,inty);
}

Ahora al mtodo move() le pasamos dos nmeros enteros, que son el nmero de pxeles que
debe moverse en el eje X y el Y.
El mtodo move() de la Raqueta y la Bola va a necesitar modificar su origen de coordenadas, por
lo que hemos de aadir los siguientes mtodos a ElementoPong:
publicvoidsetOrigenX(intnewX){
origen.setX(newX);
}
publicvoidsetOrigenY(intnewY){
origen.setY(newY);
}

La clase Coordenada ya tena la funcionalidad para modificar sus valores.


Ahora s, el mtodo move() para las Raquetas:
@Override
publicvoidmove(intx,inty){
origen.setY(origen.getY()+y);
}

Simple. Recordemos que no nos interesa ningn desplazamiento en el eje X, as que nos da igual
el valor de X que venga.
Volviendo al ACTION_MOVE, ste es su cdigo:
caseMotionEvent.ACTION_MOVE:
//hemosarrastrado
if(elementoActivo!=null){
Raquetar=(Raqueta)elementoActivo;
r.move(0,yorigenY);
}
origenY=y;
break;

Slo calculamos la diferencia de posiciones para mandrselo al mtodo move(). Necesitamos


hacer el casting explcito a Raqueta porque si no, no disponemos de move(). A move() le pasamos
como primer parmetro un 0 que, aunque nos da igual su valor, nos ayuda a ver que no nos
moveremos en el eje X sin tener que saber el cdigo de move().
Bien, ahora podemos mover las raquetas por pantalla y slo verticalmente pero echemos un ojo
a la siguiente imagen:

Esto ocurre porque no hemos puesto restricciones por los lados (en este caso arriba y abajo). Es
momento de aadrselas.
Una buena prctica de Programacin Orientada a Objetos consiste en tener claro que cada objeto
es un conjunto de atributos y funciones relativas a una entidad. Es decir, cada objeto conoce sus
atributos y sabe operar con ellos, pero no tiene que saber cmo lo hacen los dems.
Pongamos un ejemplo muy simple. Digamos que tenemos una clase Persona que tiene atributos
para definir nombre, apellidos, DNI y operaciones para cambiar y consultar estos datos.
Digamos que queremos escribir un objeto de esta clase Persona por pantalla. Lo primero que
podemos pensar es hacer una funcin dentro de Persona que sea mostrarPorPantalla() y que
escriba en la salida estndar los datos. Sin embargo esto viola nuestra idea de POO, y veamos por
qu. Imaginemos que ahora queremos escribirlo en un fichero. Y en una base de datos. Y en un
Socket. Al final acabamos con una clase Persona que tiene mil y una funciones slo encargadas de
escribir esta clase Persona en diferentes lugares. Tambin podramos hablar de leer de fichero, de
base de datos, de Socket, de entrada estndar
Lo correcto es que nuestra clase Persona tenga funciones para servir sus datos de las formas que
se necesiten, y sean otras clases las encargadas de realizar la entrada y salida. Incluso, una clase se
puede encargar de la entrada y salida de Personas en un fichero, otra en una base de datos, otra
en un Socket En proyectos complejos es interesante crear clases ms simples y especializadas

que operen con un conjunto relativamente pequeo de datos, para facilitar la modularidad.
Despus de este tostn de buenas prcticas, volvamos a lo nuestro y analicemos las restricciones.
No queremos que nuestra Raqueta se salga por arriba ni por abajo (no nos podemos mover en
horizontal, as que izquierda y derecha ni nos interesan). Y, siguiendo nuestra encapsulacin
explicada arriba, es la Raqueta quien sabe sus atributos, por tanto es ella quien sabe si puede
moverse a un sitio o no, y no las dems clases. Una de las cosas que podemos hacer es crear una
nueva funcin para las raquetas que nos diga si podemos hacer un movimiento antes de hacerlo,
que tambin vamos a usar en la Bola (y adems va a ser igual). Para ello aadimos una nueva
declaracin a nuestra superclase ElementoPong:
publicbooleanpuedoMover(intx,inty,Rectscreen){
returnscreen.contains(origen.getX()+x,origen.getY()+y,
origen.getX()+ancho+x,origen.getY()+alto+y);
}

De esta forma podemos consultar si nuestro elemento (sea Raqueta o Bola) podr realizar el
movimiento o no. Con esta funcin estamos pasndole el rectngulo que forma la pantalla para
que la propia Raqueta Modificamos nuestro ACTION_MOVE para que quede as:
caseMotionEvent.ACTION_MOVE:
//hemosarrastrado
if(elementoActivo!=null){
Raquetar=(Raqueta)elementoActivo;
if(r.puedoMover(0,yorigenY,newRect(0,0,getWidth(),getHeight())))
r.move(0,yorigenY);
}
origenY=y;
break;

Ahora podemos ejecutar de nuevo el proyecto e intentar sacar las palas de la pantalla, el resultado
ser similar a este:

Hasta aqu el movimiento de las Raquetas.


El siguiente paso es crear el movimiento de la Bola, la cual va a moverse automticamente y
rebotar contra los laterales y las Raquetas. Para hacerlo simple, ya que esto no es un tutorial
sobre Cmo hacer un clon del Pong, vamos a simplificar mucho las posibilidades de movimiento y
rebote.
En nuestro caso, vamos a permitir solamente movimientos en las diagonales principales del
sistema cartesiano (es decir, ngulos de 45, 135, 225 y 315). De esta forma, aadimos los
siguientes atributos a nuestra clase Bola:
publicstaticfinalintDCHA_ARRIBA=1;
publicstaticfinalintIZDA_ARRIBA=2;
publicstaticfinalintIZDA_ABAJO=3;
publicstaticfinalintDCHA_ABAJO=4;
privateintdireccion;

Parece ser que Android y los tipos enumerados de datos no se llevan especialmente bien y que se
recomienda usar static final int en lugar de enums, as que esta es la razn que influye para este
diseo. El constructor de la Bola sera el siguiente:
publicBola(Coordenadaorigen,intancho,intalto){

super(origen,ancho,alto);

direccion=1;
}

La variable direccin queda inicializada a 1 por ahora, pero ms adelante la cambiaremos (en otra
entrada). El mtodo move() queda de la siguiente forma:
@Override
publicvoidmove(intx,inty){
switch(direccion){
caseDCHA_ARRIBA:
origen.setX(origen.getX()+x);
origen.setY(origen.getY()y);
break;
caseIZDA_ARRIBA:
origen.setX(origen.getX()x);
origen.setY(origen.getY()y);
break;
caseIZDA_ABAJO:
origen.setX(origen.getX()x);
origen.setY(origen.getY()+y);
break;
caseDCHA_ABAJO:
origen.setX(origen.getX()+x);
origen.setY(origen.getY()+y);
break;
}

Bsicamente nos quitamos de trigonometra para hacer la explicacin ms simple ya que eso no
tiene nada que ver con Android. Ahora es el momento de hacer que automticamente la bola se
mueva. Para ello vamos a crear una nueva clase llamada BolaMoveThread con el siguiente cdigo:
packagecom.vidasconcurrentes.pongvc.juego;
publicclassBolaMoveThreadextendsThread{
privateBolabola;
privatebooleanrun;
privateintspeed;
publicBolaMoveThread(Bolabola){
this.bola=bola;
this.run=false;
this.speed=1;
}
publicvoidsetRunning(booleanrun){
this.run=run;
}
@Override
publicvoidrun(){
while(run){
try{
Thread.sleep(10);
}catch(InterruptedExceptione){
e.printStackTrace();
}
bola.move(speed,speed);
}
}
}

Es muy similar al Thread que se encarga del pintado. Ahora tenemos que ejecutar el Thread. Para
ello, en la clase PongGameView, aadimos como nuevo atributo este Thread, de modo que ahora
tenemos todos estos atributos:
privatePongGameThreadpaintThread;
privateBolaMoveThreadbolaThread;
privateElementoPongraquetaIzda;
privateElementoPongraquetaDcha;
privateElementoPongbola;
privateElementoPongelementoActivo=null;
privateintorigenY;

Ahora, creamos el Thread y lo arrancamos en surfaceCreated(), de modo que el cdigo queda:


@Override
publicvoidsurfaceCreated(SurfaceHolderholder){
raquetaIzda=newRaqueta(newCoordenada(50,getHeight()/250),20,100);
raquetaDcha=newRaqueta(newCoordenada(getWidth()70,getHeight()/250),20,100);
bola=newBola(newCoordenada(getWidth()/25,getHeight()/25),10,10);
paintThread=newPongGameThread(getHolder(),this);
paintThread.setRunning(true);
paintThread.start();
bolaThread=newBolaMoveThread((Bola)bola);
bolaThread.setRunning(true);
bolaThread.start();
}

Y por ltimo, en surfaceDestroyed() paramos el hilo, para que deje de mover la bola y muera:
@Override
publicvoidsurfaceDestroyed(SurfaceHolderarg0){
booleanretry=true;
paintThread.setRunning(false);
bolaThread.setRunning(false);
while(retry){
try{
paintThread.join();
bolaThread.join();
retry=false;
}catch(InterruptedExceptione){}
}
}

Ahora podemos ejecutar el proyecto y veremos que la bola se mueve en la diagonal del primer
cuadrante. Aqu tenemos un par de fotos de la ejecucin:

Como vemos, no estamos aplicando restricciones de movimiento, de modo que la pelota se va de


la pantalla y sigue movindose, pero lgicamente no se pinta porque no est en pantalla. El
siguiente paso, y ltimo de esta entrada, consiste en hacer que la pelota rebote.
Para ello, vamos a aadirle a la Bola dos nuevos mtodos. Uno se llamar puedoMover() como
hicimos en la Raqueta y el otro se llamar rebota().
Comenzamos creando el mtodo puedoMover(). Vamos a sobrecargar dicha funcin que viene
heredada de ElementoPong para agregar funcionalidad de la siguiente forma:
publicbooleanpuedoMover(intx,inty,Rectscreen,
RectraquetaIzda,RectraquetaDcha){
if(!puedoMover(x,y,screen))
returnfalse;
if(chocaraCon(x,y,raquetaIzda))
returnfalse;
if(chocaraCon(x,y,raquetaDcha))
returnfalse;
returntrue;
}

Siendo la funcin chocaraCon() la siguiente:


privatebooleanchocaraCon(intx,inty,Rectraqueta){
if(raqueta.contains(origen.getX()+x,origen.getY()+y))
returntrue;
if(raqueta.contains(origen.getX()+ancho+x,origen.getY()+y))
returntrue;
if(raqueta.contains(origen.getX()+x,origen.getY()+alto+y))
returntrue;
if(raqueta.contains(origen.getX()+ancho+x,origen.getY()+alto+y))
returntrue;
returnfalse;
}

De esta forma hacemos como cortocircuito las comprobaciones, apoyndonos en el


puedoMostrar() primitivo. Bsicamente comprobamos que al hacer el movimiento no nos
metemos en ninguna raqueta ni nos salimos de la pantalla (de ah el sumar x e y en cada paso).
Ahora vamos a modificar el mtodo run() del BolaMoveThread, de la siguiente forma:
@Override
publicvoidrun(){
while(run){
try{
Thread.sleep(10);
}catch(InterruptedExceptione){
e.printStackTrace();
}
if(bola.puedoMover(speed,speed,screen,
raquetaIzda.getRectElemento(),raquetaDcha.getRectElemento()))
bola.move(speed,speed);
}
}

Si ejecutamos esto, llegaremos a la siguiente imagen:

Ahora tenemos que crear los rebotes, primero con las paredes y luego con las raquetas. Por ahora
vamos a hacer que rebote con todos los lados de la pantalla. Para ello, creamos el siguiente
mtodo en la clase Bola:
publicvoidrebota(intx,inty,Rectscreen,
RectraquetaIzda,RectraquetaDcha){
if(!puedoMover(x,y,screen)){
switch(direccion){
caseDCHA_ARRIBA:
direccion=(origen.getY()y<=screen.top)?
DCHA_ABAJO:IZDA_ARRIBA;
break;
caseIZDA_ARRIBA:
direccion=(origen.getY()y<=screen.top)?

IZDA_ABAJO:DCHA_ARRIBA;
break;
caseIZDA_ABAJO:
direccion=(origen.getY()+alto+y>=screen.bottom)?
IZDA_ARRIBA:DCHA_ABAJO;
break;
caseDCHA_ABAJO:
direccion=(origen.getY()+alto+y>=screen.bottom)?
DCHA_ARRIBA:IZDA_ABAJO;
break;
}
}
}

Con esto estamos haciendo una pequea lgica de rebotes con la pantalla. Para hacernos una
idea, pongamos el ejemplo de que la bola vaya hacia arriba a la derecha (DCHA_ARRIBA). En este
caso slo podemos estar chocando con la parte de la derecha o la parte de arriba. Por ahora (ya lo
cambiaremos en la siguiente entrada), si choca en la derecha va a rebotar en lugar de marcar un
punto. Por tanto, si estamos yendo hacia la derecha y arriba (ngulo de 45), rebotaremos hacia
abajo y a la derecha (ngulo de 315, 45+315=360, con lo que comprobamos que est bien). Para
comprobar esto miramos que la parte mas alta de nuestra Bola, despus de moverse, haya
atravesado la pantalla por arriba. Si no es as, es que estamos chocando con la otra opcin: la
derecha.
La misma idea se usa para el resto de las situaciones.
Slo resta modificar el cdigo del run() en el BolaMoveThread:
@Override
publicvoidrun(){
while(run){
try{
Thread.sleep(10);
}catch(InterruptedExceptione){
e.printStackTrace();
}
if(!bola.puedoMover(speed,speed,screen,
raquetaIzda.getRectElemento(),raquetaDcha.getRectElemento()))
bola.rebota(speed,speed,screen,
raquetaIzda.getRectElemento(),raquetaDcha.getRectElemento());
bola.move(speed,speed);
}
}

Falta cambiar la creacin del Thread en PongGameView por:


bolaThread=newBolaMoveThread((Bola)bola,(Raqueta)raquetaIzda,
(Raqueta)raquetaDcha,newRect(0,0,getWidth(),getHeight()));
bolaThread.setRunning(true);
bolaThread.start();

De modo que el constructor y los atributos de BolaMoveThread ahora son:


privateBolabola;
privateRaquetaraquetaIzda;
privateRaquetaraquetaDcha;
privateRectscreen;
privatebooleanrun;
privateintspeed;
publicBolaMoveThread(Bolabola,Raquetaizda,Raquetadcha,Rectscreen,Contextcontext){

this.bola=bola;

this.raquetaIzda=izda;

this.raquetaDcha=dcha;

this.screen=screen;

this.run=false;

this.speed=1;
}

Si ejecutamos ahora, la bola rebotar indefinidamente por la pantalla atravesando las Raquetas.
Ahora vamos a crear los rebotes con stas. Para esta entrada vamos a comprobar los rebotes por
todos los lados de cada raqueta, aunque en el juego final hay colisiones que no tenemos que
comprobar (como el caso del lado izquierdo de la raqueta izquierda, o el del lado derecho de la
raqueta derecha). Modificamos el cdigo del mtodo rebota() aadiendo el siguiente cdigo:
Rectraqueta=null;
if(chocaraCon(x,y,raquetaIzda))

raqueta=raquetaIzda;
if(chocaraCon(x,y,raquetaDcha))

raqueta=raquetaDcha;
if(raqueta!=null){

switch(direccion){

caseDCHA_ARRIBA:

direccion=(origen.getX()+ancho<raqueta.left)?

IZDA_ARRIBA:DCHA_ABAJO;

break;

caseIZDA_ARRIBA:

direccion=(origen.getX()>raqueta.right)?

DCHA_ARRIBA:IZDA_ABAJO;

break;

caseIZDA_ABAJO:

direccion=(origen.getX()>raqueta.right)?

IZDA_ARRIBA:DCHA_ABAJO;

break;

caseDCHA_ABAJO:

direccion=(origen.getX()+ancho<raqueta.left)?

IZDA_ABAJO:DCHA_ARRIBA;

break;

Bsicamente es comprobar por dnde estamos chocando, y rebotar en la direccin correcta.


Si ejecutamos el cdigo ahora tendremos un Pong en el cual la bola rebota en todas las paredes y
ambas raquetas, que era nuestro objetivo.
Aqu acaba esta segunda parte de la lgica del juego. Ha sido una entrada muy larga, pero he de
decir en mi defensa que contiene mucho cdigo para que sea fcil de seguir y comprender. Vaya,
lo que es un paso a paso.
En esta entrada hemos ampliado la funcionalidad del proyecto que tenamos hasta ahora, para
aadir la lgica de movimientos de las raquetas y la bola, incluyendo los rebotes de sta con cada
elemento y la creacin de un Thread que se encarga de actualizar la posicin de la misma.
En la siguiente entrada del ciclo Cmo crear una aplicacin en Android vamos a aadir los ltimos
retoques: el marcador del juego y su representacin en pantalla, la posibilidad de aumentar la
dificultad cambiando la velocidad de la bola y posiblemente una Inteligencia Artificial muy simple.
Como siempre, podis descargar el proyecto completo hasta el momento desde aqu (MD5:
31b264db2de4125fa01c52d4d169bc99), e importarlo a vuestro Eclipse.
Muchas gracias por la lectura!
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Like

Twittear

Follow

Share

Esta entrada fue publicada en Android, Curso introduccin Android, Programacin y etiquetada
como aplicacion android, eclipse, graficos android, java, thread.

Creando una aplicacin de Android: el juego y


la lgica (parte 1)

Fingerprinting con wireshark y FOCA

2 Respuestas a Creando una aplicacin de Android: el juego y la


lgica (parte 2)
1.

Darker dijo:
27 julio, 2012 at 3:22
Muy buen tutorial!!!! Pero necesito ayuda, he seguido todos los pasos hasta el final de esta
parte, y se muestran las figuras pero no hay manera de moverlas. Me descargu tu versin y
esta todo igual. No se a que puede deberse y me estoy volviendo loco.
Gracias por adelantado y encantado de haber encontrado un tutorial as!

2.

ohcan dijo:
9 agosto, 2011 at 0:30
Buen trabajo META,prefiero que hagas el paso a paso,asi comprendo el codigo y su
funcion.UNsaludo

vidasConcurrentes
Sitio creado por meta y sshMan

Home

Blog

Fingerprinting con wireshark y FOCA

Sguenos

Concenos

Contacto

Escribe aqu para buscar...

Nessus en Backtrack 5: Instalacin e integracin


con Metasploit

Creando una aplicacin de Android: mejoras


(parte 1)
Publicado el 21 agosto, 2011 por meta
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Bienvenidos a la quinta parte de la serie de entradas en el ciclo Creando una aplicacin de
Android. Si an no lo has hecho, comienza desde la primera entrada mostrada en el men
inmediatamente superior.
En esta entrada vamos a continuar con el resultado de la entrada anterior, en la que habamos
acabado la lgica de movimientos y las colisiones. Aadiremos funcionalidades durante esta
entrada y la siguiente para acabar la aplicacin.
Para esta entrada aadiremos vibracin del dispositivo, reproduccin de sonidos y uso del
acelermetro para los movimientos de las raquetas.
Comenzamos!
Importante: esta entrada va a basarse en los cdigos creados en las
anteriores entradas del ciclo al que pertenece. Tienes disponible pinchando aqu (MD5:
31b264db2de4125fa01c52d4d169bc99) el proyecto de Eclipse con todo lo hecho hasta ahora, el
cual puedes importar a tu Eclipse y comenzar a trabajar.
El Android SDK incluye una gran cantidad de clases que hace muy sencillo el uso de los sensores
del dispositivo, la vibracin, la reproduccin de audio Para mostrar cmo de sencillo es,
comenzamos aadindole vibracin a nuestra aplicacin. Comenzamos abriendo nuestro Eclipse.

Vibracin
Para que una aplicacin pueda vibrar, ya que necesita acceder a un elemento del sistema, necesita
que el usuario acepte el uso de este elemento. Para ello tenemos que aadir al
AndroidManifest.xml que queremos usar vibracin. Tenemos dos formas, la primera es aadiendo
<uses-sdk android:minSdkVersion=7 /> justo detrs de la etiqueta <manifest >.
La segunda forma consiste en ir a la pestaa Permissions del manifest, pulsar en Add, elegir Uses
Permission y aceptar, y luego escribir android.permission.VIBRATE en el cuadro de la derecha. Lo
siguiente es programar el uso del vibrador.
El uso de la vibracin est definido por un Context, por lo que vamos a necesitar usar el contexto
de nuestra aplicacin para poder obtener el vibrador y posteriormente hacerlo vibrar. La vibracin
la vamos a realizar solamente cuando la Bola rebote en una de las dos Raquetas. Si recordamos
las entradas anteriores, nuestra Bola y nuestra Raqueta tenan una funcin llamada puedoMover(),
heredada de su superclase ElementoPong, que deca si se poda mover este elemento sin salirse
de la pantalla. Sabemos que cuando una bola rebota es porque se ha chocado con algo. Si se ha
chocado con algo pero an se puede mover por la pantalla significa que, por eliminacin, se ha
chocado con una raqueta. Ya tenemos planteado lo que vamos a hacer, as que hagmoslo.
Primero vamos a aadir un nuevo atributo a la clase BolaMoveThread de la siguiente forma:
privateVibratorv=null;

Este ser nuestro vibrador. Ahora necesitamos inicializarle, puesto que est a null y si lo usramos
ahora la aplicacin se morira debido a un NullPointerException (de ah que se inicialice a null, para
debuggearlo ms fcil). Para inicializarle necesitamos el Context de la aplicacin, de modo que al
constructor de BolaMoveThread le vamos a pasar el Context, quedando as:
publicBolaMoveThread(Bolabola,Raquetaizda,Raquetadcha,
Rectscreen,Contextcontext){

this.bola=bola;

this.raquetaIzda=izda;

this.raquetaDcha=dcha;

this.screen=screen;

this.run=false;

this.speed=1;

this.v=(Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
}

Categoras
Android
Curso introduccin
Android
Programacin
Seguridad
Sistemas Operativos

Entradas recientes
Automatizando la
creacin de entornos de
desarrollo con Vagrant
Colorshapes, el juego de
velocidad mental y figuras
de colores para Android
eyeOS: Trabajando en la
nube
Integrando Google
Analytics en aplicaciones
Android
Integrando Twitter en
aplicaciones Android con
SignPost y Twitter4J

Etiquetas

activity
algoritmo android
aplicacion android
arbol backtrack bash BD
acelerometro

BEeF

canvas contraseas csrf

dns dns spoof

eclipse

expresiones regulares

graficos android

graphics android htc

desire intent java


javascript layout menu

metasploit

metasploitable mitm
mysql oauth owasp

pentesting php seguridad


por defecto shodan

smartphones SQL SQLi


trasteando twitter twitter4j
VirtualBox wireshark xml xss
persistente

Sitios de inters

Android Developers
Android.es
Backtrack
bolaThread=newBolaMoveThread((Bola)bola,(Raqueta)raquetaIzda,
Command Line Kung Fu
(Raqueta)raquetaDcha,newRect(0,0,getWidth(),getHeight()),
this.getContext());
DragonJAR
El Androide Libre
Por ltimo slo queda hacer que vibre, para ello vamos a modificar el cdigo del run() del
BolaMoveThread de la siguiente forma:
Exploits Database
@Override
Flu Project
publicvoidrun(){
Gran Angular

while(run){

try{
Hispasec

Thread.sleep(10);

}catch(InterruptedExceptione){
Microsiervos

e.printStackTrace();

}
OpenLibra

if(!bola.puedoMover(speed,speed,screen,raquetaIzda.getRectElemento(),raquetaDcha.getRectElemento())){

bola.rebota(speed,speed,screen,raquetaIzda.getRectElemento(),raquetaDcha.getRectElemento());
Pentester.es

if(bola.puedoMover(speed,speed,screen))
Poesa Binaria

v.vibrate(50);

}
Security By Default

bola.move(speed,speed);

}
Un informtico en el lado
}
del mal
Con esto estamos haciendo una vibracin breve (50 milisegundos) cada vez que rebotamos
World Wide Web
contra una raqueta. Fcil, verdad?
Consistorium
Faltara cambiar la forma en que se crea este Thread de la siguiente forma (en el mtodo
surfaceCreated() del PongGameView:

Como informacin extra tenemos que saber que un objeto de la clase Vibrator tambin puede
vibrar dado un patrn, utilizando la funcin vibrate(pattern, repeat), siendo pattern un long[] y
repeat un int que dice cuntas veces se repite (-1 si no queremos repetir).
Sonido

El siguiente paso consistir en aadir sonido a los rebotes, el tpico sonido metlico. Existen
diversas formas de usar sonidos en Android, pero vamos a usar la ms simple de todas: el
MediaPlayer. Lo primero que tenemos que hacer es buscar un sonido que nos valga. Por lo general
se recomienda usar ficheros codificados en formato .ogg (Ogg Vorbis) por ser el ms compatible y
tener una gran compresin. Yo he elegido el siguiente sonido. Si quieres usar el mismo, haz click
derecho sobre el enlace y selecciona Guardar enlace como (y gurdalo con un nombre distinto, en
minsculas, sin espacios y sin tildes).
Ahora crearemos una nueva carpeta dentro de la carpeta res de nuestro proyecto, y la llamaremos
raw. Dentro de ella meteremos nuestro fichero de audio (en mi caso pong.ogg). A partir de ahora
podremos acceder a ello referenciando a R.raw.pong. Aadimos un nuevo atributo a
BolaMoveThread:
privateMediaPlayermp=null;

Y el constructor queda as:


publicBolaMoveThread(Bolabola,Raquetaizda,
Raquetadcha,Rectscreen,Contextcontext){

this.bola=bola;

this.raquetaIzda=izda;

this.raquetaDcha=dcha;

this.screen=screen;

this.run=false;

this.speed=1;

this.v=(Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);

this.mp=MediaPlayer.create(context,R.raw.pong);
}

La llamada a MediaPlayer.create() crea y prepara el audio local para ser reproducido. Existe una
funcin de los objetos MediaPlayer llamada prepare() que hace lo mismo (pero slo hay que
llamarla en ciertos momentos, ahora explicamos ms). Falta hacer que reproduzca el sonido, de
modo que vamos a la funcin run(), que queda:
@Override
publicvoidrun(){

while(run){

try{

Thread.sleep(10);

}catch(InterruptedExceptione){

e.printStackTrace();

if(!bola.puedoMover(speed,speed,screen,raquetaIzda.getRectElemento(),raquetaDcha.getRectElemento())){

mp.start();

bola.rebota(speed,speed,screen,raquetaIzda.getRectElemento(),raquetaDcha.getRectElemento());

if(bola.puedoMover(speed,speed,screen))

v.vibrate(50);

bola.move(speed,speed);

}
}

Podramos hacer un stop() y prepare() despus y antes (respectivamente) de cada start(). Sin
embargo eso sera un consumo muy grande de los recursos, y start() ya mantiene preparado el
audio para hacer un replay. Sera interesante, sin embargo, hacer una llamada a stop() y prepare()
dentro del setRunning() dependiendo de si paramos o iniciamos el thread. Agregar sonidos
simples ha resultado ser tambin muy fcil, no?

Activar y desactivar
Ahora mismo tenemos que la aplicacin hace que el dispositivo vibre al rebotar con una pala, y
hace que reproduzca un sonido de choque metlico cada vez que rebote con algo (sea pared o
raqueta). Recordemos que tenemos un men en el cual tenamos una parte de Opciones, pero
que no tena nada dentro. Es ahora el momento de crear las opciones del juego, permitiendo
activar y desactivar estas dos funcionalidades.
Comenzamos creando un nuevo layout que tendr el siguiente cdigo:
<?xmlversion="1.0"encoding="utf8"?>
<TableLayoutxmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"android:layout_width="fill_parent"

android:layout_height="fill_parent">

<TableRowandroid:id="@+id/tableRow1"android:layout_width="wrap_content"

android:layout_height="wrap_content">

<TextViewandroid:textAppearance="?android:attr/textAppearanceLarge"

android:layout_width="wrap_content"android:layout_height="wrap_content"

android:width="250dip"android:paddingLeft="30dip"android:id="@+id/labelSonido"

android:text="@string/sonidoMenu"></TextView>

<CheckBoxandroid:layout_width="wrap_content"android:id="@+id/checkBoxSonido"

android:layout_height="wrap_content"android:checked="true"></CheckBox>

</TableRow>

<TableRowandroid:id="@+id/tableRow2"android:layout_width="wrap_content"

android:layout_height="wrap_content">

<TextViewandroid:textAppearance="?android:attr/textAppearanceLarge"

android:layout_width="wrap_content"android:layout_height="wrap_content"

android:paddingLeft="30dip"android:id="@+id/labelVibracion"

android:text="@string/vibracionMenu"></TextView>

<CheckBoxandroid:layout_width="wrap_content"android:id="@+id/checkBoxVibracion"

android:layout_height="wrap_content"android:checked="true"></CheckBox>

</TableRow>
</TableLayout>

Teniendo en cuenta que tenemos que aadir los Strings a strings.xml:


<?xmlversion="1.0"encoding="utf8"?>
<resources>

<stringname="app_name">Pong</string>

<stringname="menu_play">Jugar</string>

<stringname="menu_options">Opciones</string>

<stringname="menu_exit">Salir</string>

<stringname="sonidoMenu">Sonido</string>

<stringname="vibracionMenu">Vibracin</string>
</resources>

Tenemos que aadir la Activity al AndroidManifest.xml igual que hicimos en otra de las entradas.
Para ello abrimos el AndroidManifest.xml y aadimos lo siguiente antes de </application>:
<activityandroid:name=".PongOpcionesActivity"android:screenOrientation="portrait"></activity>

Lo siguiente que necesitamos hacer es aadir el cdigo necesario para crear una actividad nueva
que muestre este nuevo layout. Creamos una nueva clase llamada PongOpcionesActivity, cuyo
cdigo es el siguiente:
packagecom.vidasconcurrentes.pongvc;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.Window;
importandroid.view.WindowManager;
publicclassPongOpcionesActivityextendsActivity{

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

setContentView(R.layout.options);

}
}

Ahora slo falta hacer el cdigo en la actividad principal para que se ejecute esta. Para ello vamos a
la clase PongvCActivity (la principal), y aadimos la funcin:
privatevoidmuestraOpciones(){

Intentopciones=newIntent(this,PongOpcionesActivity.class);

this.startActivity(opciones);
}

Ahora en el onCreate() de esta clase, vamos al lugar donde registramos el listener para el botn de
Opciones y cambiamos el contenido por lo siguiente:

TextViewoptions=(TextView)findViewById(R.id.options_button);
options.setOnClickListener(newOnClickListener(){

@Override

publicvoidonClick(Viewv){

muestraOpciones();

}
});

Ahora s, si hacemos una ejecucin, obtendremos esto tras pulsar en el botn Opciones del men
principal:

Ahora tenemos que programar qu pasa cuando activamos y desactivamos estos checkboxes. He
elegido hacer lo siguiente con un patrn Singleton. A grandes rasgos, un patrn Singleton ofrece la
garanta de que existe como mximo una instancia de una clase y que es accesible globalmente.
Nosotros queremos poder acceder al estado de estas opciones desde el juego, pero modificarlas
desde esta actividad. De modo que comenzamos creando nuestra clase PongOpciones dentro de
un nuevo paquete llamado com.vidasconcurrentes.pongvc.opciones:
packagecom.vidasconcurrentes.pongvc.opciones;
publicclassPongOpciones{

privatestaticPongOpcionesopciones=null;
privatebooleansonido;
privatebooleanvibracion;

privatePongOpciones(){

sonido=true;

vibracion=true;
}

publicstaticsynchronizedPongOpcionesgetInstance(){

if(opciones==null)

opciones=newPongOpciones();

returnopciones;
}

publicvoidtoggleSound(){

sonido=!sonido;
}

publicvoidtoggleVibration(){

vibracion=!vibracion;
}

publicbooleansoundEnabled(){

returnsonido;
}

publicbooleanvibrationEnabled(){

returnvibracion;
}

Las ponemos inicializadas a true porque, por defecto, nuestra aplicacin va a tener ambas
activadas. Ahora aadimos el comportamiento al pulsar sobre los checkboxes. Para ello vamos al
onCreate() de la clase PongOpcionesActivity y aadimos lo siguiente al final:
CheckBoxsonido=(CheckBox)findViewById(R.id.checkBoxSonido);
sonido.setOnClickListener(newOnClickListener(){

@Override

publicvoidonClick(Viewv){

PongOpciones.getInstance().toggleSound();

}
});
CheckBoxvibracion=(CheckBox)findViewById(R.id.checkBoxVibracion);
vibracion.setOnClickListener(newOnClickListener(){

@Override

publicvoidonClick(Viewv){

PongOpciones.getInstance().toggleVibration();

}
});
sonido.setChecked(PongOpciones.getInstance().soundEnabled());
vibracion.setChecked(PongOpciones.getInstance().vibrationEnabled());

Como vemos, lo ltimo que hacemos es poner el estado de cada CheckBox acorde con el estado
de la instancia del patrn Singleton. Cuando pulsamos en un CheckBox, cambiamos el valor de la
variable a la que se refiere de true a false y viceversa.
Efectivamente, si ejecutsemos ahora, comprobaramos que podemos tener ambas activas,
desactivadas o una activa y otra no.

Acelermetro
El acelermetro del dispositivo va a permitirnos registrar movimientos de ste para saber si se ha
cambiado la inclinacin con respecto de la posicin inicial con la que se comenz el juego. Existen
varias formas de usar el acelermetro, y por supuesto existen muchsimas e infinitas formas de
programar dnde debe ir cada cosa en nuestro proyecto.
Mis decisiones han sido las siguientes:
Queremos que se ejecute un Thread que controle la raqueta izquierda con el acelermetro.
Queremos quitar el registro del acelermetro cuando no lo necesitemos.
Queremos reanudar el uso del acelermetro al volver al juego.
Al igual que hicimos al crear los hilos anteriores (pintado y movimiento de la bola), vamos a crear
un hilo nuevo para las raquetas:
packagecom.vidasconcurrentes.pongvc.juego;
importandroid.graphics.Rect;
publicclassRaquetaMoveThreadextendsThread{

privateRaquetaraqueta;
privateRectscreen;

privatebooleanrun;

publicRaquetaMoveThread(Raquetar,Rects){

raqueta=r;

screen=s;
}

publicvoidsetRunning(booleanrun){

this.run=run;
}

publicvoidrun(){

while(run){

try{

Thread.sleep(10);

}catch(InterruptedExceptione){

e.printStackTrace();

}
//nuestrocodigovaaqui

En PongGameView creamos el hilo en surfaceCreated() y lo matamos en surfaceDestroyed():


//estodentrodesurfaceCreated()
raquetaThread=newRaquetaMoveThread((Raqueta)raquetaIzda,
newRect(0,0,getWidth(),getHeight()));
raquetaThread.setRunning(true);
raquetaThread.start();
//estoseriaelsurfaceDestroyed():
@Override
publicvoidsurfaceDestroyed(SurfaceHolderarg0){

booleanretry=true;

paintThread.setRunning(false);

bolaThread.setRunning(false);

raquetaThread.setRunning(false);

while(retry){

try{

paintThread.join();

bolaThread.join();

raquetaThread.join();

retry=false;

}catch(InterruptedExceptione){}

}
}

Ahora es el momento de crear nuestro acelermetro. Para ello vamos a crear una clase envolvente
para la funcionalidad que queremos que nos ofrezca. Un dispositivo emulado no puede usar
acelermetro, as que ser necesario el uso de un dispositivo fsico.
Nosotros vamos a querer que se mueva la raqueta. Esta raqueta pertenece a una actividad que
est en modo landscape (apaisado) continuamente. Un dispositivo fsico tiene su eje X a lo alto, es
decir, es una lnea imaginaria que va desde los botones del dispositivo hasta el auricular. Si lo
prefers: de abajo a arriba. Su eje Y es el perpendicular a ste que cruza de lado a lado. Como hasta
ahora hemos visto a la hora de pintar, con el dispositivo en modo apaisado, el eje X ser el ancho y
el eje Y ser el alto. De modo que si nosotros rotamos el dispositivo hacia delante en modo
apaisado, queremos que nuestra pala suba. Si rotamos el dispositivo hacia nosotros en modo
apaisado, queremos que nuestra pala baje.
Dicho en otras palabras: si la rotacin del eje X es negativa, queremos que vaya arriba; si es
positiva, queremos que vaya abajo. Para ms informacin sobre los ejes de coordenadas
tridimensionales pulsa aqu.
Por tanto slo nos interesa la rotacin del eje X para nuestra pala, pero podemos acceder a los
valores de Y y Z consultando event.values[1] y event.values[2] respectivamente. Creamos una
nueva clase AcelerometroPong en el paquete com.vidasconcurrentes.pongvc.juego:
packagecom.vidasconcurrentes.pongvc.juego;
importandroid.content.Context;
importandroid.hardware.Sensor;
importandroid.hardware.SensorEvent;
importandroid.hardware.SensorEventListener;
importandroid.hardware.SensorManager;
publicclassAcelerometroPongimplementsSensorEventListener{

privateSensorManagersm=null;
privateintx;

publicAcelerometroPong(Contextcontext){

sm=(SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
}

publicvoidregister(){

sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_GAME);

publicvoidunregister(){

sm.unregisterListener(this);
}

@Override
publicvoidonAccuracyChanged(Sensorsensor,intaccuracy){}

@Override
publicvoidonSensorChanged(SensorEventevent){

if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){

x=Math.round(event.values[0]*100);

}
}

publicintgetXInclination(){

returnx;
}

Desde la Activity PongJuego vamos a usar esta clase como atributo, y aadiremos dos nuevos
mtodos de modo que quedar as:
packagecom.vidasconcurrentes.pongvc;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.Window;
importandroid.view.WindowManager;
importcom.vidasconcurrentes.pongvc.juego.AcelerometroPong;
importcom.vidasconcurrentes.pongvc.pintado.PongGameView;
publicclassPongJuegoextendsActivity{

privateAcelerometroPongacelerometro;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
acelerometro=newAcelerometroPong(this.getApplicationContext());

setContentView(newPongGameView(this,acelerometro));

@Override
protectedvoidonResume(){

super.onResume();

acelerometro.register();
}

@Override
protectedvoidonStop(){

super.onStop();

acelerometro.unregister();
}

Es importante no usar el sensor si no es necesario, de ah onResume() y onStop().


Nuestro PongGameView ahora recibe tambin el acelermetro, as que tendremos que modificar
el constructor para que as lo reciba y aadir un atributo nuevo.
privateIntegerxInit=null;
privateAcelerometroPongacelerometro;
publicPongGameView(Contextcontext,AcelerometroPongacelerometro){

super(context);

getHolder().addCallback(this);

this.acelerometro=acelerometro;

Ahora, queremos que sea el Thread que controla el movimiento de la raqueta el encargado de
consultar el acelermetro, as que igualmente cambiamos el constructor de ste y lo aadimos

como atributo a RaquetaMoveThread:


privateAcelerometroPongacelerometro;
publicRaquetaMoveThread(Raquetar,Rects,AcelerometroPonga){

raqueta=r;

screen=s;

this.acelerometro=a;
}

Adems, aadimos esta nueva variable xInit de tipo Integer (para poder inicializarla a null). Y por
qu queremos inicializarla a null? Es tan slo una pequea treta que se me ha ocurrido para poder
realizar una calibracin en cada ejecucin. Si es null es que an no hemos calibrado la posicin en
la que est el dispositivo al arrancar el Thread, si no es null es que ya est calibrado.
Ahora modificaremos el run() de este Thread, de la siguiente forma:
publicvoidrun(){

if(xInit==null)

xInit=acelerometro.getXInclination();

while(run){

try{

if(Math.abs(xInitacelerometro.getXInclination())<200)

Thread.sleep(5);

else

Thread.sleep(2);

}catch(InterruptedExceptione){

e.printStackTrace();

if(xInit<acelerometro.getXInclination()UMBRAL||

xInit<acelerometro.getXInclination()+UMBRAL)

if(raqueta.puedoMover(0,1,screen))

raqueta.move(0,1);

if(xInit>acelerometro.getXInclination()UMBRAL||

xInit>acelerometro.getXInclination()+UMBRAL)

if(raqueta.puedoMover(0,1,screen))

raqueta.move(0,1);
}

Lo primero que hacemos es inicializar la posicin de calibrado, si es null. Lo siguiente que hacemos
es hacer que el movimiento de la raqueta sea ms o menos rpido dependiendo de si hemos
inclinado mucho el dispositivo o no. En nuestro caso, si hay una diferencia absoluta (positiva o
negativa) de menos de 200 unidades, entonces nos vamos a mover a una velocidad normal. Si
esto es mayor significa que hemos inclinado el dispositivo mucho ms, por lo que deseamos que
se mueva ms rpido. La variable UMBRAL no es ms que una variable final de la clase que en este
caso tiene el valor de 20. Este UMBRAL nos sirve para no mover la raqueta si el movimiento es
demasiado pequeo (quiz por errores de medida o de redondeo). Adems aadimos la
comprobacin de si puedoMover() para evitar salirse de la pantalla.
Con esto ya tenemos la raqueta izquierda funcionando para moverse con el acelermetro, pero a
la vez funciona con el dedo y esto no es lo deseable.

Activar / desactivar acelermetro


Igual que hicimos con el sonido y la vibracin, ahora queremos poder cambiar acelermetro por
tctil y viceversa. Para ello vamos a nuestra clase PongOpciones y aadimos un nuevo atributo, de
modo que queda:
privatestaticPongOpcionesopciones=null;
privatebooleansonido;
privatebooleanvibracion;
privatebooleanacelerometro;
privatePongOpciones(){

sonido=true;

vibracion=true;

acelerometro=false;
}

Aadimos tambin los siguientes dos mtodos, para cambiar el valor y consultarlo:
publicvoidtoggleAcelerometro(){

acelerometro=!acelerometro;
}
publicbooleanaccelerometerEnabled(){

returnacelerometro;
}

Ahora tenemos que llamar a estos mtodos desde la actividad de las opciones, la cual necesita ser
cambiada para aadir una nueva fila. Por tanto, antes del </TableLayout> de options.xml,
aadimos:

<TableRowandroid:id="@+id/tableRow3"android:layout_width="wrap_content"android:layout_height="wrap_content">

<TextViewandroid:textAppearance="?android:attr/textAppearanceLarge"android:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/labe

<CheckBoxandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/checkBoxAccel"></CheckBox>
</TableRow>

Hay que aadir tambin el String al fichero strings.xml. De esta forma veramos la siguiente
imagen al ejecutar:

En el onCreate() de PongOpcionesActivity, aadimos:


CheckBoxacelerometro=(CheckBox)findViewById(R.id.checkBoxAccel);
acelerometro.setOnClickListener(newOnClickListener(){

@Override

publicvoidonClick(Viewv){

PongOpciones.getInstance().toggleAcelerometro();

}
});
acelerometro.setChecked(PongOpciones.getInstance().accelerometerEnabled());

De esta forma cambiamos la variable de activado a desactivado y viceversa.


Es el momento ahora de hacer que la aplicacin use una u otra. Todo el cdigo se va a poner por
tanto en PongGameView. El Thread de la raqueta slo se ejecuta cuando est activado el
acelermetro, por tanto modificamos el cdigo de surfaceCreated() y cambiamos:
if(PongOpciones.getInstance().accelerometerEnabled()){

raquetaThread=newRaquetaMoveThread((Raqueta)raquetaIzda,
newRect(0,0,getWidth(),getHeight()),acelerometro);

raquetaThread.setRunning(true);

raquetaThread.start();
}

Adems, si este Thread no se ha iniciado, no se puede matar. As que en surfaceDestroyed():


@Override
publicvoidsurfaceDestroyed(SurfaceHolderarg0){

booleanretry=true;

paintThread.setRunning(false);
bolaThread.setRunning(false);
if(PongOpciones.getInstance().accelerometerEnabled())

raquetaThread.setRunning(false);
while(retry){

try{

paintThread.join();

bolaThread.join();

if(PongOpciones.getInstance().accelerometerEnabled())

raquetaThread.join();

retry=false;

}catch(InterruptedExceptione){}
}

Adems, si activamos el acelermetro no queremos poder mover la raqueta con el dedo. De


modo que en el onTouchEvent() vamos a envolverlo todo con un:
if(!PongOpciones.getInstance().accelerometerEnabled(){

//aquitodoelcodigoanterior,incluyendoelswitch
}
returntrue;

Hecho esto podemos ejecutar la aplicacin y trastear con ella activando y desactivando cosas,
reiniciando el juego La idea es iniciar el juego, pulsar la tecla de actividad anterior que nos lleva
al men, elegir Opciones y cambiarlas, dar a actividad anterior y luego a Jugar.
Aqu llega el final de la entrada de hoy. En ella hemos visto cmo usar distintos sensores del
sistema como la vibracin o el acelermetro, adems de las herramientas que nos ofrece para
reproducir sonidos locales. En la siguiente entrada acabaremos la aplicacin aadiendo las ltimas
mejoras como un pequeo umbral para el juego tctil, el marcador de juego y la posibilidad de que
se cuele la bola y por ltimo una pequea Inteligencia Artificial para la raqueta derecha.
Como siempre, podis descargar el proyecto de Eclipse desde aqu (MD5:
1e3eeda28b041716b8526aa59f1aa312) e importarlo a vuestro Eclipse.
Muchas gracias por la lectura y hasta la prxima semana!
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Like

Twittear

Follow

Share

Esta entrada fue publicada en Android, Curso introduccin Android, Programacin y etiquetada
como acelerometro, activity, aplicacion android, mejoras, sonido, vibracion.

Fingerprinting con wireshark y FOCA

Nessus en Backtrack 5: Instalacin e integracin


con Metasploit

Una respuesta a Creando una aplicacin de Android: mejoras


(parte 1)
1.

ohcan dijo:
22 agosto, 2011 at 0:02
Gracias como siempre,en cuanto tenga tiempo me pongo a picar codigo,desarrollas cosas
muy interesantes en este simple juego

vidasConcurrentes
Sitio creado por meta y sshMan

Home

Blog

Sguenos

Nessus en Backtrack 5: Instalacin e


integracin con Metasploit

Concenos

Contacto

Escribe aqu para buscar...

Post-exploitation con WCE y Flu

Creando una aplicacin de Android: mejoras


(parte 2)
Publicado el 30 agosto, 2011 por meta
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Bienvenidos a la sexta parte de la serie de entradas en el ciclo Creando una aplicacin de Android.
Si an no lo has hecho, comienza desde la primera entrada mostrada en el men inmediatamente
superior.
En esta entrada acabaremos el desarrollo de la aplicacin, mejoraremos el control tctil para
hacerlo ms tolerante e incluiremos todo lo necesario para el uso del marcador (y que se guarde si
volvemos al men). En la prxima y ltima entrada de la serie, publicaremos la aplicacin.
Comencemos!
Importante: esta entrada va a basarse en los cdigos creados en las
anteriores entradas del ciclo al que pertenece. Tienes disponible pinchando aqu
(MD5:1e3eeda28b041716b8526aa59f1aa312) el proyecto de Eclipse con todo lo hecho hasta
ahora, el cual puedes importar a tu Eclipse y comenzar a trabajar.

Mejora del control tctil


El primer paso para esta entrada va a ser el aadir un pequeo umbral al control tctil de las
raquetas. Ahora mismo el control exige que toquemos exactamente dentro de la raqueta, de
modo que si tocas un pxel por fuera no te va a detectar nada. El feedback de la gente que ha
probado la aplicacin en mi dispositivo es que necesita ser ms tolerante, as que all vamos.
Con nuestro Eclipse abierto, localizamos la clase PongGameView, que es la clase encargada de
procesar el control tctil. Vamos a aadir el siguiente atributo a la clase, que a fin de cuentas es
una constante:
1 publicstaticfinalintUMBRAL_TACTIL=70;
El nmero que pongamos a esta variable ser el nmero de pxeles de ms que queremos que
acepte por la izquierda y la derecha.
Ahora vamos a aadir este umbral al procesado del control tctil. Para ello vamos a la funcin
onTouchEvent() que, si recordamos, consta principalmente de un switch con tres casos. El primer
caso se activa al pulsar, el segundo se activa al arrastrar despus de haber pulsado y el tercero se
activa al soltar. Nosotros estamos interesados en el primer caso, as que lo modificaremos de la
siguiente forma:
1
2
3
4
5
6
7
8
9
10
11
12

Categoras
Android
Curso introduccin
Android
Programacin
Seguridad
Sistemas Operativos

Entradas recientes
Automatizando la
creacin de entornos de
desarrollo con Vagrant
Colorshapes, el juego de
velocidad mental y figuras
de colores para Android
eyeOS: Trabajando en la
nube
Integrando Google
Analytics en aplicaciones
Android
Integrando Twitter en
aplicaciones Android con
SignPost y Twitter4J

Etiquetas

activity
algoritmo android
aplicacion android
arbol backtrack bash BD
acelerometro

BEeF

canvas contraseas csrf

dns dns spoof

eclipse

expresiones regulares

caseMotionEvent.ACTION_DOWN:
//hemospulsado
Rectaux;

aux=newRect(raquetaIzda.getRectElemento());
aux.set(aux.leftUMBRAL_TACTIL,aux.top,
aux.right+UMBRAL_TACTIL,aux.bottom);

graficos android

if(aux.contains(x,y)){
elementoActivo=raquetaIzda;
origenY=y;
break;
}

metasploitable mitm

graphics android htc

desire intent java


javascript layout menu

metasploit

mysql oauth owasp

pentesting php seguridad


por defecto shodan

13
14
15
16
17
18
19
20
21
22

aux=newRect(raquetaDcha.getRectElemento());
aux.set(aux.leftUMBRAL_TACTIL,aux.top,
aux.right+UMBRAL_TACTIL,aux.bottom);
if(aux.contains(x,y)){
elementoActivo=raquetaDcha;
origenY=y;
break;
}
break;

As, usamos un rectngulo a partir de los rectngulos definidos por las raquetas, con la salvedad de
que los expandimos por los lados tantas unidades como UMBRAL_TACTIL diga. Hasta aqu la
mejora del control tctil.

Marcador
Lo siguiente que vamos a hacer es crear el marcador de juego y todo lo necesario para que
funcione. Es decir, cuando completemos esta seccin tendremos algo jugable de principio a fin.
Comenzamos creando una clase Marcador:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

packagecom.vidasconcurrentes.pongvc.juego;

publicclassMarcador{

publicstaticfinalintMAX_PUNT=9;

privateintpuntosIzda;
privateintpuntosDcha;

publicvoidinitMarcador(){
puntosIzda=0;
puntosDcha=0;
}

publicMarcador(){
initMarcador();
}

publicintgetPuntosIzda(){
returnpuntosIzda;
}

publicintgetPuntosDcha(){
returnpuntosDcha;
}

publicvoidaddPuntoIzda(){
puntosIzda++;
}

publicvoidaddPuntoDcha(){
puntosDcha++;
}

publicbooleanacabado(){
returnpuntosDcha==MAX_PUNT||puntosIzda==MAX_PUNT;
}
}

De esta forma estamos definiendo que el juego acabar cuando uno de los dos jugadores haga 9
puntos. Adems estamos definiendo los comportamientos necesarios para inicializar el marcador,
consultar el valor y aadir un punto a los jugadores.
Una cosa est clara cuando programamos, y es que queremos ver que las cosas que hacemos
funcionan, y queremos verlo lo antes posible. Por esta razn lo siguiente que vamos a hacer es lo
necesario para mostrar en pantalla el marcador para que veamos que lo que vayamos haciendo
realmente funciona.
Vamos a la clase PongGameView y aadimos un nuevo atributo de clase Marcador:
1 privateMarcadormarcador;
Adems, aadimos el constructor de este objeto al constructor de la clase, de modo que el
constructor quedar:
1 publicPongGameView(Contextcontext,AcelerometroPongacelerometro)
{
2
3
4
5
6
7

super(context);
getHolder().addCallback(this);

this.acelerometro=acelerometro;
this.marcador=newMarcador();
}

Ahora ya contamos con un marcador. Lo siguiente ser crear en PongGameView las funciones
necesarias para pintar los nmeros en pantalla. Queremos crear una linea divisoria a la mitad de la
pantalla, al estilo Pong original. Comenzamos creando este mtodo:

smartphones SQL SQLi


trasteando twitter twitter4j
VirtualBox wireshark xml xss
persistente

Sitios de inters
Android Developers
Android.es
Backtrack
Command Line Kung Fu
DragonJAR
El Androide Libre
Exploits Database
Flu Project
Gran Angular
Hispasec
Microsiervos
OpenLibra
Pentester.es
Poesa Binaria
Security By Default
Un informtico en el lado
del mal
World Wide Web
Consistorium

1
2
3
4
5
6
7
8
9
10
11
12

privatevoiddrawCenterLine(Canvascanvas,Paintpaint){
intw=6;
inth=20;
intgap=10;
intini=gap/2;//porestetica,sinoseria0

for(inti=0;i<this.getHeight()/(h+gap);i++){
canvas.drawRect(this.getWidth()/2w/2,ini,
this.getWidth()/2+w/2,ini+h,paint);
ini+=h+gap;
}
}

En este cdigo tenemos unas variables iniciales, que muy bien podan ser parte de los atributos de
la clase puesto que no vamos a modificarlos en ningn momento, pero quera mantener la
explicacin en cdigos breves. La variable w ser el ancho de cada una de las lineas divisorias. Se
recomienda que sea par. La variable h es la altura de cada linea divisoria y gap es el espacio entre
una y otra linea. La variable ini define dnde comenzaremos a pintar. He elegido gap / 2 para su
inicializacin para que est igual de separada por arriba que por abajo de los lmites, pero es una
eleccin emprica. En el bucle vamos pintando cada uno de los tramos de la linea discontnua
hasta llegar abajo. Slo faltara aadir la llamada a este mtodo dentro del onDraw():
1
2
3
4
5
6
7
8
9
10
11

@Override
publicvoidonDraw(Canvascanvas){
Paintpaint=newPaint();
paint.setColor(Color.WHITE);

canvas.drawColor(Color.BLACK);
drawCenterLine(canvas,paint);
canvas.drawRect(raquetaIzda.getRectElemento(),paint);
canvas.drawRect(raquetaDcha.getRectElemento(),paint);
canvas.drawRect(bola.getRectElemento(),paint);
}

Aqu tenemos una captura de pantalla de la ejecucin actual de la aplicacin:

Lo siguiente que vamos a aadir es el pintado de los nmeros de las puntuaciones de cada
jugador. Adems, vamos a usar una font propia, que no viene en el SDK de Android. Lo primero
ser buscar una, yo eleg la font Kelly Slab de Google Web Fonts. Ahora la incluimos en nuestra
aplicacin, para lo cual vamos a aadir un directorio llamado fonts en nuestro directorio assets, y
ah incluimos nuestra recin descargada font:

Atencin: continuar leyendo antes de crear ningn cdigo!


Lo siguiente ser crear el mtodo donde cargamos el tipo de letra, de la siguiente forma:
1
2
3
4
5
6
7
8
9
10
11

privatevoiddrawMarcador(Canvascanvas,Paintpaint){
paint.setTextAlign(Align.CENTER);
paint.setTypeface(Typeface.createFromAsset(this.getContext().getAssets(),
"fonts/KellySlabRegular.ttf"));
paint.setTextSize(80);
paint.setAntiAlias(true);
canvas.drawText(Integer.toString(marcador.getPuntosIzda()),
getWidth()/280,80,paint);
canvas.drawText(Integer.toString(marcador.getPuntosDcha()),
getWidth()/2+80,80,paint);
}

Con esto aadimos opciones al objeto Paint y pintamos los nmeros del marcador. Si ahora
modificamos el mtodo onDraw():
1
2
3
4

@Override
publicvoidonDraw(Canvascanvas){
Paintpaint=newPaint();
paint.setColor(Color.WHITE);

5
6
7
8
9
10
11
12

canvas.drawColor(Color.BLACK);
drawCenterLine(canvas,paint);
drawMarcador(canvas,paint);
canvas.drawRect(raquetaIzda.getRectElemento(),paint);
canvas.drawRect(raquetaDcha.getRectElemento(),paint);
canvas.drawRect(bola.getRectElemento(),paint);
}

Podemos ejecutar la aplicacin y obtendremos una captura como la siguiente:

Si continuamos con el cdigo actual, con lo de arriba explicado, hagamos una reflexin. Pongamos
que la carga de esa font gastara 1KB de memoria por cada ejecucin. Nuestos dispositivos tienen
512MB de media, as que eso no es un problema! Falso.
Nuestra aplicacin no ejecuta un nmero de frames por segundo fijo, sino que ejecuta todo lo
rpido que puede. Por ejemplo, la aplicacin podra estar refrescando la pantalla a una velocidad
de 60FPS, lo que conlleva una carga de la font en cada refresco con el consecuente tiempo de
carga y el consecuente gasto de memoria. Si esto lo prolongamos con el tiempo entonces nos
vamos a quedar sin memoria (been there, done that).
Por lo tanto, dado que esto no es un PC de mesa que suelen tener varios GB de memoria RAM
es de especial importancia no realizar la carga de ficheros sin necesidad (y otras operaciones
costosas y que comen RAM). Si podemos hacerlas una sola vez, mejor.
Ahora s, vamos a crear el cdigo necesario y relativamente optimizado. Lo primero va a ser
agregar el siguiente atributo a la clase PongGameView:
1 privatePaintpaint;
Ahora el constructor de la clase ser de la siguiente forma (puesto que el objeto Paint no se
modifica en los dems mtodos):
1 publicPongGameView(Contextcontext,AcelerometroPongacelerometro)
{
2 super(context);
3 getHolder().addCallback(this);
4
5 this.acelerometro=acelerometro;
6 this.marcador=newMarcador();
7
8 paint=newPaint();
9 paint.setColor(Color.WHITE);
10 paint.setTextAlign(Align.CENTER);
11 paint.setTypeface(Typeface.createFromAsset(this.getContext().getAssets(),
12 "fonts/KellySlabRegular.ttf"));
13 paint.setTextSize(80);
14 paint.setAntiAlias(true);
15 }
El mtodo de pintado completo ser el conjunto de lo siguiente:
1 @Override
2 publicvoidonDraw(Canvascanvas){
3 canvas.drawColor(Color.BLACK);
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

drawCenterLine(canvas);
drawMarcador(canvas);
canvas.drawRect(raquetaIzda.getRectElemento(),paint);
canvas.drawRect(raquetaDcha.getRectElemento(),paint);
canvas.drawRect(bola.getRectElemento(),paint);
}

privatevoiddrawCenterLine(Canvascanvas){
intw=6;
inth=20;
intgap=10;
intini=gap/2;//porestetica,sinoseria0

for(inti=0;i<this.getHeight()/(h+gap);i++){
canvas.drawRect(this.getWidth()/2w/2,ini,
this.getWidth()/2+w/2,ini+h,paint);
ini+=h+gap;
}
}

privatevoiddrawMarcador(Canvascanvas){
canvas.drawText(Integer.toString(marcador.getPuntosIzda()),
getWidth()/280,80,paint);
canvas.drawText(Integer.toString(marcador.getPuntosDcha()),

28 getWidth()/2+80,80,paint);
29 }
Ahora s, tenemos un pintado inteligente intentando optimizar el uso de Paint.
El siguiente paso ser hacer que, al tocar en uno de los laterales de la pantalla (izquierdo o
derecho), se sume un punto al jugador en cuestin.
Comenzamos modificando el mtodo rebota() de la Bola, de modo que ahora va a devolver un
valor. Devolver -1 si la bola entr por la izquierda, 1 si entr por la derecha y 0 si sigue en la
pantalla. Por tanto, este mtodo ahora es:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

publicintrebota(intx,inty,Rectscreen,RectraquetaIzda,
RectraquetaDcha){
if(!puedoMover(x,y,screen)){
switch(direccion){
caseDCHA_ARRIBA:
if(origen.getY()y<=screen.top)
direccion=DCHA_ABAJO;
else
return1;
break;
caseIZDA_ARRIBA:
if(origen.getY()y<=screen.top)
direccion=IZDA_ABAJO;
else
return1;
break;
caseIZDA_ABAJO:
if(origen.getY()+alto+y>=screen.bottom)
direccion=IZDA_ARRIBA;
else
return1;
break;
caseDCHA_ABAJO:
if(origen.getY()+alto+y>=screen.bottom)
direccion=DCHA_ARRIBA;
else
return1;
break;
}
}

Rectraqueta=null;
if(chocaraCon(x,y,raquetaIzda))
raqueta=raquetaIzda;
if(chocaraCon(x,y,raquetaDcha))
raqueta=raquetaDcha;
if(raqueta!=null){
switch(direccion){
caseDCHA_ARRIBA:
direccion=(origen.getX()+ancho<raqueta.left)?
IZDA_ARRIBA:DCHA_ABAJO;
break;
caseIZDA_ARRIBA:
direccion=(origen.getX()>raqueta.right)?
DCHA_ARRIBA:IZDA_ABAJO;
break;
caseIZDA_ABAJO:
direccion=(origen.getX()>raqueta.right)?

49
50
51
52
53
54
55
56
57
58
59

IZDA_ARRIBA:DCHA_ABAJO;
break;
caseDCHA_ABAJO:
direccion=(origen.getX()+ancho<raqueta.left)?
IZDA_ABAJO:DCHA_ARRIBA;
break;
}
}

return0;
}

De esta forma hemos modificado la primera parte del cdigo del mtodo, si ahora mismo
ejecutsemos la aplicacin podramos ver que la bola se cuela por los lados, pero no ocurre nada.
Ahora es cuando haremos que ocurra ese algo al colarse.
Comenzamos aadiendo el Marcador a la clase BolaMoveThread, pues va a ser ste el que se
encargue de modificarlo. El constructor con el nuevo atributo quedara:
1
2
3
4
5
6
7
8
9
10
11

privateMarcadormarcador;

publicBolaMoveThread(Bolabola,Raquetaizda,Raquetadcha,
Rectscreen,Contextcontext,Marcadormarcador){
this.bola=bola;
this.raquetaIzda=izda;
this.raquetaDcha=dcha;
this.screen=screen;
this.run=false;
this.speed=1;
this.v=(Vibrator)

context.getSystemService(Context.VIBRATOR_SERVICE);
12 this.mp=MediaPlayer.create(context,R.raw.pong);
13 this.marcador=marcador;
14 }
Ahora vamos a modificar el mtodo run() de esta clase. Queremos que, si el mtodo bola.rebota()
devuelve 0, haga lo que hace hasta ahora. Si devuelve -1 queremos que sume un punto a la
raqueta derecha y si devuelve 1 que sume a la raqueta izquierda (recordamos que el signo indica
por qu lado entr). De esta forma, modificamos as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

@Override
publicvoidrun(){
while(run){
try{
Thread.sleep(5);
}catch(InterruptedExceptione){
e.printStackTrace();
}
if(punto){
try{
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
if(!marcador.acabado()){
punto=false;
}
continue;
}

if(!bola.puedoMover(speed,speed,screen,
raquetaIzda.getRectElemento(),
raquetaDcha.getRectElemento())){
switch(bola.rebota(speed,speed,screen,
raquetaIzda.getRectElemento(),
raquetaDcha.getRectElemento())){
case0:
if(PongOpciones.getInstance().soundEnabled())
mp.start();
if(bola.puedoMover(speed,speed,screen)&&
PongOpciones.getInstance().vibrationEnabled())
v.vibrate(50);
break;
case1:
marcador.addPuntoDcha();
reinitBola();
punto=true;
break;
case1:
marcador.addPuntoIzda();
reinitBola();
punto=true;
break;
}

43
44
45
46

}
bola.move(speed,speed);
}
}

23
24

Aqu hemos hecho varias cosas, expliqumoslas por partes.


Lo primero que hemos hecho es aadir una variable private boolean punto; a los atributos de la
clase, la cual se inicializa a false. Lo siguiente es aadir el primer bloque. Si punto == true, entonces
estamos diciendo que se ha marcado un punto ahora mismo. En este caso queremos que la bola
no se mueva y que se quede dos segundos parada. En caso de haber acabado no volver a
moverse hasta que no volvamos al men y juguemos de nuevo. En caso de no haber acabado,
devolvemos la variable punto a false, lo que significa que quedan puntos. En cualquier caso
continuamos con la siguiente iteracin sin pasar por el resto del cdigo.
El resto del cdigo modificado es un switch con el valor de salida del mtodo bola.rebota(). Si
devuelve 0 ejecutamos el cdigo que ya tenamos. Si devuelve otra cosa, aadimos un punto al
jugador correspondiente, reiniciamos la posicin de la bola y ponemos punto a true. El cdigo de
reinitBola() necesita que hayamos agregado dos nuevos atributos y los hayamos inicializado. Todo
lo necesario para reinitBola() se indica a continuacin:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

privateintbolaInitX;
privateintbolaInitY;
privatebooleanpunto;

publicBolaMoveThread(Bolabola,Raquetaizda,Raquetadcha,
Rectscreen,Contextcontext,Marcadormarcador){
this.bola=bola;
this.bolaInitX=bola.getOrigenX();
this.bolaInitY=bola.getOrigenY();
this.raquetaIzda=izda;
this.raquetaDcha=dcha;
this.screen=screen;
this.run=false;
this.speed=1;
this.v=(Vibrator)

16
17
18
19
20
21
22
23
24

context.getSystemService(Context.VIBRATOR_SERVICE);
this.mp=MediaPlayer.create(context,R.raw.pong);
this.marcador=marcador;
this.punto=false;
}

privatevoidreinitBola(){
bola.setOrigenX(bolaInitX);
bola.setOrigenY(bolaInitY);
}

Adems hemos cambiado el primer Thread.sleep() a 5 para que vaya ms rpido la bola con
respecto de cmo iba hasta ahora. Una pequea y rpida partida jugando a propsito nos podra
dar la siguiente imagen:

Ya tenemos el marcador completo, funcional y en pantalla. Sin embargo, si ahora mismo jugamos
y volvemos al men en mitad de una partida, no mantendremos nuestra puntuacin guardada.
Para ilustrar el paso de datos entre actividades vamos a hacer que se mantenga la puntuacin.
Lo primero que tenemos que hacer es modificar el cdigo en la clase PongvCActivity. Localizamos
el mtodo empiezaJuego(), que contiene este cdigo:
1
2
3
4

privatevoidempiezaJuego(){
Intentjuego=newIntent(this,PongJuego.class);
this.startActivity(juego);
}

Ahora lo modificamos para que sea:


1
2
3
4

privatevoidempiezaJuego(){
Intentjuego=newIntent(this,PongJuego.class);
this.startActivityForResult(juego,Activity.RESULT_OK);
}

De esta forma, en lugar de iniciar una Activity nueva, decimos que queremos que nos mande algo
de vuelta. Ahora tenemos que crear el lugar donde procesar ese algo. Para ello sobrecargamos el
mtodo onActivityResult():
1 @Override
2 publicvoidonActivityResult(intrequestCode,intresultCode,
Intentdata){
3 super.onActivityResult(requestCode,resultCode,data);
4 switch(requestCode){
5 case1:
6 if(resultCode==Activity.RESULT_OK){
7 //solosielcodigodevueltoesRESULT_OK,procesamos
8 }
9 break;
10 }
11 }
Lo siguiente que vamos a hacer es crear el cdigo que devuelve las puntuaciones del marcador.
Vamos a la clase PongJuego, y aadimos el siguiente atributo con la necesaria modificacin del
constructor:
1
2
3
4
5
6
7
8
9
10

privateAcelerometroPongacelerometro;
privatePongGameViewview;

@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
acelerometro=new
AcelerometroPong(this.getApplicationContext());
11 view=newPongGameView(this,acelerometro);
12 setContentView(view);

13 }
Adems, en PongGameView vamos a poner un nuevo mtodo:
1 publicMarcadorgetMarcador(){
2 returnmarcador;
3 }
As podremos consultar el marcador desde la actividad y poder devolver el valor. Para ello, en
PongJuego crearemos el siguiente mtodo:
1
2
3
4
5
6
7
8
9
10
11

@Override
publicvoidonBackPressed(){
Bundlebundle=newBundle();
bundle.putInt("PuntosIzda",
view.getMarcador().getPuntosIzda());
bundle.putInt("PuntosDcha",
view.getMarcador().getPuntosDcha());

IntentmIntent=newIntent();
mIntent.putExtras(bundle);
setResult(Activity.RESULT_OK,mIntent);
super.onBackPressed();
}

Ahora slo falta procesar estos datos devueltos. Lo primero ser aadir dos nuevos atributos en
PongvCActivity, con su inicializacin:
1 privateintpuntosIzdaIniciales=0;
2 privateintpuntosDchaIniciales=0;
Ahora volvemos al mtodo onActivityResult() de la clase PongvCActivity, y aadimos el cdigo
interno a este if:
1
2
3
4
5

if(resultCode==Activity.RESULT_OK&&data.getExtras()!=null){
//solosielcodigodevueltoesRESULT_OK,procesamos
puntosIzdaIniciales=data.getExtras().getInt("PuntosIzda");
puntosDchaIniciales=data.getExtras().getInt("PuntosDcha");
}

Solo falta hacer que se usen estos valores al arrancar la actividad de PongJuego. Para ello vamos a
modificar la forma de llamarla en empiezaJuego(), incluyendo estos dos valores. Usamos la misma
idea de aadir extras, obteniendo este cdigo:
1
2
3
4
5
6

privatevoidempiezaJuego(){
Intentjuego=newIntent(this,PongJuego.class);
juego.putExtra("PuntosIzda",puntosIzdaIniciales);
juego.putExtra("PuntosDcha",puntosDchaIniciales);
this.startActivityForResult(juego,1);
}

Ahora falta usar estos valores en PongJuego, de modo que modificamos el constructor para que
quede as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
acelerometro=new
AcelerometroPong(this.getApplicationContext());

if(getIntent().getExtras()!=null){
intpuntosIzda=
getIntent().getExtras().getInt("PuntosIzda");
intpuntosDcha=
getIntent().getExtras().getInt("PuntosDcha");
if(puntosIzda==Marcador.MAX_PUNT||
puntosDcha==Marcador.MAX_PUNT)
view=newPongGameView(this,acelerometro,0,0);
else
view=newPongGameView(this,acelerometro,puntosIzda,
puntosDcha);
}else
view=newPongGameView(this,acelerometro,0,0);

setContentView(view);
}

Y modificar el constructor de PongGameView as:


1
2
3
4
5
6
7
8

publicPongGameView(Contextcontext,AcelerometroPongacelerometro,
intpuntosIzda,intpuntosDcha){
super(context);
getHolder().addCallback(this);

this.acelerometro=acelerometro;
this.marcador=newMarcador(puntosIzda,puntosDcha);

9
10
11
12
13
14
15
16

paint=newPaint();
paint.setColor(Color.WHITE);
paint.setTextAlign(Align.CENTER);
paint.setTypeface(Typeface.createFromAsset(this.getContext().getAssets(),
"fonts/KellySlabRegular.ttf"));
paint.setTextSize(80);
paint.setAntiAlias(true);
}

Esto, lgicamente, requiere aadir un nuevo constructor al Marcador:


1
2
3
4

publicMarcador(inti,intd){
puntosIzda=i;
puntosDcha=d;
}

Ahora s, podemos ejecutar nuestra aplicacin y veremos que si volvemos al men (por ejemplo
para cambiar alguna opcin) y luego volvemos a dar a Jugar, mantendremos la puntuacin que
tenamos acumulada. Llegados a este punto podra crearse un men emergente que permitiera
elegir continuar partida existente (si la hay) o iniciar una nueva. Sin embargo considero que es
sobrecargar sin necesidad la entrada, y sera una cosa a tener en cuenta si sta fuera una aplicacin
comercial.

Evitar el bloqueo de pantalla


Si utilizamos la aplicacin con el acelermetro nos damos cuenta de que la pantalla acabar por
apagarse eventualmente dependiendo de nuestras opciones del timeout para el bloqueo. Sin
embargo, nosotros queremos que la pantalla no se bloquee automticamente para nuestra
aplicacin si estamos usando el acelermetro. Esto sin embargo puede ser malo para el consumo
de batera si un usuario deja la aplicacin abierta.
Lo primero ser agregar el siguiente atributo a la clase PongJuego e inicializarlo en el constructor:
1
2
3
4
5
6
7
8

privateWakeLockwl;

@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
[...]
setContentView(view);
PowerManagerpm=(PowerManager)
this.getSystemService(Context.POWER_SERVICE);
9 wl=pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,"PongvC");
10 }
Ahora aadimos el mtodo onPause() y modificamos el mtodo onResume():
1
2
3
4
5
6
7
8
9
10
11
12
13
14

@Override
protectedvoidonPause(){
super.onPause();
if(PongOpciones.getInstance().accelerometerEnabled())
wl.release();
}

@Override
protectedvoidonResume(){
super.onResume();
acelerometro.register();
if(PongOpciones.getInstance().accelerometerEnabled())
wl.acquire();
}

Ahora slo falta aadir el permiso de usar ste cdigo en el AndroidManifest.xml, o si no


obtendremos una excepcin que matar nuestra aplicacin. Para aadirlo abrimos el manifest, en
la pestaa de Permissions. Pulsamos en Add > Uses Permission. En el cuadro derecho aadimos
android.permission.WAKE_LOCK.
Para comprobar que hemos hecho todo correctamente, iniciamos la aplicacin vamos a Opciones,
cambiamos el control para usar el acelermetro, volvemos al men y pulsamos en Jugar. Si todo
est bien la aplicacin ejecutar el juego y podremos comprobar que no se apaga la pantalla
(probar sto teniendo un timeout bajo).

ltima mejora
Las ltimas cosas se dejan para el final, y si nos damos cuenta hasta ahora no hemos usado el
botn de Salir del men. Queremos que cuando se pulse se cierre la aplicacin.
Vamos a la clase PongvCActivity, en el mtodo onCreate(), en la parte que aadimos el
onTouchListener() al botn de salir. Modificamos su cdigo as:
1
2
3
4
5
6
7

TextViewexit=(TextView)findViewById(R.id.exit_button);
exit.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
finish();
}
});

Al llamar a la funcin finish() en una actividad lo que hacemos es cerrarla.

Hasta aqu la entrada de hoy. Con esta entrada podemos decir que hemos acabado el desarrollo
de la aplicacin. La siguiente entrada consistir en todos los pasos necesarios para publicar la
aplicacin, desde la creacin de una cuenta de Google Checkout hasta la publicacin.
Quedaran varias cosas que hacer en la aplicacin, como por ejemplo la creacin de una pequea
inteligencia artificial para la raqueta derecha, uso del multitctil para poder jugar dos personas
tocando a la vez o localizacin de idioma para los botones del men principal.
Sin embargo sera sobrecargar demasiado esta serie de tutoriales puesto que estamos intentando
hacer una pequea introduccin a Android con la excusa de crear un juego. Nuestra intencin no
es crear una aplicacin con todo lo que tiene Android a la vez.
Como siempre podis descargar el proyecto de Eclipse completo para poder importarlo y usarlo
pulsando aqu (MD5: 209d4e4393a45dadd15c18bfb22621c1).
Una vez ms, muchas gracias por vuestro tiempo!
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Like

Twittear

Follow

Share

Esta entrada fue publicada en Android, Curso introduccin Android, Programacin y etiquetada
como acelerometro, activity, aplicacion android, canvas, eclipse, graficos android, graphics
android, java, menu, subactivity, wake lock.

Nessus en Backtrack 5: Instalacin e


integracin con Metasploit

Post-exploitation con WCE y Flu

3 Respuestas a Creando una aplicacin de Android: mejoras


(parte 2)
1.

alex dijo:
30 abril, 2012 at 22:39
Gracias por el tuto, en todo caso como quedaria lo de la IA?
saludos

2.

aeropostal tarifas dijo:


17 abril, 2012 at 13:14
He encontrado muy buen material aqui. Lo agregue a mis favoritos para volver a visitar la
pagina

3.

Jumax9 dijo:
15 septiembre, 2011 at 16:44
Muy buen tutorial, muchas gracias! ^____^!

vidasConcurrentes
Sitio creado por meta y sshMan

Home

Blog

Sguenos

Concenos

Post-exploitation con WCE y Flu

Contacto

Escribe aqu para buscar...

Rogue AP con karmetasploit

Creando una aplicacin de Android: empaquetado


y publicacin
Publicado el 8 septiembre, 2011 por meta
0. Creando una aplicacin de Android: la presentacin
1. Creando una aplicacin de Android: primeros pasos
2. Creando una aplicacin de Android: visin de conjunto y diseo del men
3. Creando una aplicacin de Android: el juego y la lgica (parte 1)
4. Creando una aplicacin de Android: el juego y la lgica (parte 2)
5. Creando una aplicacin de Android: mejoras (parte 1)
6. Creando una aplicacin de Android: mejoras (parte 2)
7. Creando una aplicacin de Android: empaquetado y publicacin
Bienvenidos a la sptima y ltima parte de la serie de entradas en el ciclo Creando una aplicacin
de Android. Si an no lo has hecho, comienza desde la primera entrada mostrada en el men
inmediatamente superior. Durante las anteriores entradas nos hemos centrado en el desarrollo de
la aplicacin paso a paso, y hemos llegado a tener la aplicacin acabada. En esta entrada vamos a
crear el paquete de la aplicacin (es decir, el .apk preparado con todo), vamos a crear nuestra
cuenta de desarrollador para el Android Market y vamos a publicar la aplicacin en l.
Comencemos! Importante: esta entrada va a basarse en los cdigos creados en las anteriores
entradas del ciclo al que pertenece. Tienes disponible pinchando aqu (MD5:
209d4e4393a45dadd15c18bfb22621c1) el proyecto de Eclipse con todo lo hecho hasta ahora, el
cual puedes importar a tu Eclipse y comenzar a trabajar.

Preparacin
La primera cosa que tenemos que hacer es preparar la aplicacin para poder publicarla. Esto
implica crear el icono, poner el nombre de la aplicacin y quitar todos los restos de trazas de
cdigo y debug. Para poder poner el nombre a la aplicacin (el que saldr debajo del icono) y el
propio icono, debemos ir al AndroidManifest.xml y localizar la etiqueta <application>, como aqu
mostramos:
1 <applicationandroid:icon="@drawable/icon"
android:label="@string/app_name">
Aqu estamos diciendo que el nombre de la aplicacin aparece en el fichero strings.xml bajo el
string llamado app_name, y que el icono de la aplicacin est en el directorio drawable.
Comprobamos el fichero strings.xml y vemos:
1 <stringname="app_name">Pong</string>
Lo vamos a cambiar por:
1 <stringname="app_name">PongvC</string>
La parte del nombrado de la aplicacin ya est, ahora vamos con el icono. Es interesante consultar
las guas para el diseo de iconos de Android Developers para saber ms acerca de los tamaos
adecuados y diferentes resoluciones. En nuestro caso comenzamos creando un icono en
Photoshop, el cual guardamos con tamao 7272 pxeles y usando Guardar para web y
dispositivos marcando PNG-24 y sin ningn metadato (as, entre otras cosas, reducimos el
tamao). El resultado podra ser el siguiente, que es el que usaremos:

Categoras
Android
Curso introduccin
Android
Programacin
Seguridad
Sistemas Operativos

Entradas recientes
Automatizando la
creacin de entornos de
desarrollo con Vagrant
Colorshapes, el juego de
velocidad mental y figuras
de colores para Android
eyeOS: Trabajando en la
nube
Integrando Google
Analytics en aplicaciones
Android
Integrando Twitter en
aplicaciones Android con
SignPost y Twitter4J

Etiquetas

activity
algoritmo android
aplicacion android
arbol backtrack bash BD
acelerometro

BEeF

canvas contraseas csrf

dns dns spoof

eclipse

expresiones regulares

graficos android

graphics android htc

desire intent java


Lo siguiente que tenemos que hacer es incluirlo en nuestro proyecto. Para ello vamos a nuestra
estructura de directorios del proyecto y pegamos el fichero en drawable-hdpi/icon_pong.png.
Crearemos una versin de 4848 pxeles y otra de 3636 pxeles que guardaremos en drawablemdpi y drawable-ldpi respectivamente. Importante: el nombre del fichero debe ser el mismo!
Como ya no vamos a necesitar los icon.png que estn en estos directorios, vamos a eliminarlos. Es
importante no incluir cosas innecesarias en nuestras aplicaciones para ahorrar espacio. Al

javascript layout menu

metasploit

metasploitable mitm
mysql oauth owasp

pentesting php seguridad


por defecto shodan

eliminarlos veremos que el AndroidManifest.xml se nos queja. Esto es porque nos resta cambiar la
ruta del icono. La etiqueta <application>entonces quedar as:
1 <applicationandroid:icon="@drawable/icon_pong"
android:label="@string/app_name">
Ahora vamos a quitar todos los restos de trazas de cdigo y el debug de la aplicacin. Debemos
quitar, en caso de tenerlo (no en el nuestro, pero quiz s en futuras aplicaciones) la opcin
android:debuggable=true de la etiqueta <application>. Debemos buscar todas las llamadas a la
clase Log, para quitar toda traza que hayamos usado durante el desarrollo. Es tambin muy
importante buscar en nuestros cdigos si hemos incluido por alguna razn informacin privada
que no deseemos que se vea, adems de todo fichero que no sea necesario del proyecto y
posibles ficheros de logging o backup que hayamos usado. Por ltimo es de vital importancia la
versin de la aplicacin, y sera muy interesante echar un vistazo a la gua sobre versionado de
Android Developers. Comenzando por la versin 1.0, por cada actualizacin que hagamos
deberamos aumentarla. Las dos etiquetas importantes que tenemos que tener en cuenta son
android:versionCode y android:versionName en la etiqueta <manifest>. Debemos comprender
para qu sirve cada una de las dos:
versionCode: este atributo es un nmero entero que tpicamente comienza en 1 y que se va
aumentando por cada actualizacin. Representa el orden de la versin. Lo suyo es que, cada
vez que hagamos una actualizacin, aumentemos este nmero en una unidad, ya sea por
una actualizacin grande o pequea.
versionName: este atributo es una cadena de texto que representa la versin tal y como
debe ser mostrada a los usuarios. Comenzando tpicamente en 1.0 ir aumentando a 1.1,
1.2 Si es una actualizacin menor, aumentamos el segundo nmero. Si es una
actualizacin grande aumentaremos el primero (para tener 2.0, luego 2.1).
Por tanto, nuestra etiqueta <manifest>quedar as:
1 <manifest
xmlns:android="http://schemas.android.com/apk/res/android"
2 package="com.vidasconcurrentes.pongvc"android:versionCode="1"
3 android:versionName="1.0">

Firmar la aplicacin
La ltima etapa previa a la publicacin ser el firmado de sta. De nuevo, deberamos consultar la
gua sobre el firmado de Android Developers. Comenzamos haciendo click derecho sobre nuestro
proyecto. Elegimos Android Tools > Export Signed Application Package. Lo siguiente sern una
sucesin de ventanas en las que se nos guiar en el proceso. Lo primero que veremos ser lo
siguiente:

Pulsamos en Next y veremos la siguiente ventana:

Elegimos Create new keystore, y elegimos el lugar con el botn Browse. Lo siguiente es escribir la
contrasea que usaremos para el fichero. Recomendamos usar una contrasea fuerte,
posiblemente creada con algn generador de contraseas. Una vez hemos rellenado los campos,
damos a Next y vemos la siguiente ventana:

smartphones SQL SQLi


trasteando twitter twitter4j
VirtualBox wireshark xml xss
persistente

Sitios de inters
Android Developers
Android.es
Backtrack
Command Line Kung Fu
DragonJAR
El Androide Libre
Exploits Database
Flu Project
Gran Angular
Hispasec
Microsiervos
OpenLibra
Pentester.es
Poesa Binaria
Security By Default
Un informtico en el lado
del mal
World Wide Web
Consistorium

Aqu es donde tenemos que poner toda la informacin de la firma. Alias debe rellenarse con 8
caracteres como mximo, y es el alias de la clave. La contrasea, por experiencia propia, debe ser
la misma que pusimos anteriormente. Lo siguiente es la validez, en aos, que va a tener la clave
(entre 1 y 1000). Los campos de la parte de abajo no son obligatorios, si bien debemos rellenar al
menos uno para poder continuar. Una vez hayamos concluido con esta ventana, pulsamos Next y
veremos esta otra:

Aqu elegimos la ruta donde queremos guardar nuestro .apk ya firmado. Una vez hayamos
concluido pulsamos en Finish y dejamos que Eclipse trabaje. Una vez haya completado el proceso
(dependiendo del tamao de la aplicacin puede resultar un proceso relativamente largo),
tendremos nuestro fichero de la clave y nuestro .apk firmado. Para comprobar que efectivamente
est todo correcto, podemos guardar dicho .apk en nuestro dispositivo (por ejemplo por medio de
USB), y ejecutarlo con un Explorador de Ficheros (primero debemos desinstalarlo si lo tenemos
por haber desarrollado en el dispositivo). Si hacemos esto, podremos ver que nuestro dispositivo
muestra algo similar a lo siguiente:

Una vez instalada veremos que funciona exactamente igual que cuando lo hacamos al desarrollar
en Eclipse y usar Run as Android Application. Ya estamos listos para publicar nuestra aplicacin!

Crear nuestra cuenta de desarrollador del Android Market


Lo siguiente que vamos a hacer ser crear nuestra cuenta de desarrollador. Efectuaremos un nico
pago de 25$ (ms o menos 18) y eso nos permitir publicar nuestras aplicaciones sin lmite en
nmero. Siempre hay un pero, y en este caso es que si queremos llevarnos algn dinero por las
aplicaciones, Google se va a quedar con el 30% de lo que cueste la aplicacin (este porcentaje
puede cambiar si Google as lo desea en un futuro). Para hacer este tutorial lo ms completo
posible, vamos a ir por todos los pasos. Comenzamos visitando la pgina de publicacin de
aplicaciones para el Market. Si no estamos logueados en nuestra cuenta de Google, veremos lo
siguiente:

Meteremos los datos de nuestra cuenta de Google (la de gmail, para entendernos), y continuamos
con la siguiente pantalla:

En ella debemos leer el link que dice Acuerdo de distribucin para desarrolladores de Android
Market. Una vez hemos rellenado los campos (posteriormente podrn editarse), continuamos con
la siguiente pantalla:

Aqu simplemente damos a Continuar. El siguiente paso es poner la informacin para realizar el
pago:

Entiendo que, en caso de ya haber comprado algo con Google Checkout, este paso se omitira o
los campos ya estaran completados. En cualquier caso, rellenamos el formulario (importante
fijarse en el https:// de la barra de direcciones), y continuamos al siguiente paso:

En este paso nada ms que veremos el resumen de la compra que vamos a hacer. Podemos elegir
las opciones que se nos muestran, y luego pulsamos en Realizar pedido ahora. Una vez est
completado veremos lo siguiente, que confirma que nuestra compra se ha realizado
correctamente:

En el cuadro amarillo hay un link que dice sitio de desarrolladores de Android Market, en el cual
pulsaremos. El siguiente paso consiste en leer el acuerdo de licencia en espaol y continuar:

Si todo ha ido sin errores (no debera haberlos) veremos que nuestro registro en el Android Market
se ha aprobado y estaremos frente a nuestra Consola del desarrollador:

Con esto hemos acabado nuestro registro en el Android Market como desarrolladores.

Publicar nuestra aplicacin


Despus del registro, la siguiente parte ser publicar nuestra aplicacin en el Android Market. Para
ello pulsamos en el enlace Subir aplicacin de la ventana anterior. Veremos lo siguiente:

Elegimos la ruta de nuestro .apk firmado, y dejamos que se suba. Una vez subido nos har un
resumen de los datos con el cdigo de versin y el nombre de la versin adems de todos los
permisos que puedan tener que aceptar los usuarios. La siguiente parte consiste en rellenar los
campos (y tambin los opcionales si as lo deseamos). En la Especificacin de detalles, es
importante que nos demos cuenta de que nos pide la informacin en ingls (descripcin, ttulo).
Podemos elegir aadir nuevos idiomas y poner la informacin en cada uno de ellos (incluso
cambiar el idioma predeterminado). Es muy importante esta parte, ya que ser la que vean los
usuarios del Android Market. Dato importante: en caso de que queramos cobrar una cantidad por
nuestras aplicaciones, lo primero que tenemos que hacer ser configurar una cuenta bancaria que
ser en la que recibiremos los pagos. Pulsa en el correspondiente enlace en la seccin de Precios >
Quieres vender aplicaciones? Configura una cuenta de comerciante en Google Checkout. Una
vez hayamos completado toda la informacin (importante tambin el sitio web y el correo de
contacto), procedemos a aceptar los Consentimientos de la parte baja de la web. Finalmente
guardamos nuestros progreso pulsando en Guardar en la parte superior derecha de los formularios
y comprobamos que tenemos correcto todas las opciones que hemos querido rellenar. En la
pestaa Archivos APK tenemos nuestra aplicacin, la cual necesitamos Activar. Una vez hecho
esto slo nos resta pulsar en Publicar, en la parte superior derecha. Seremos redirigidos a la
siguiente ventana:

Nos restara comprobar que, efectivamente, nuestra aplicacin est realmente publicada y
accesible. Se supone que la publicacin en el Android Market es instantnea, pero no podremos
encontrarla usando la herramienta de bsqueda del market hasta que no haya pasado un tiempo
(quiz horas). Veamos las capturas:

Importante: es necesario que probemos que funciona todo correctamente antes de distribuir
enlaces a diestro y siniestro. Y es necesario que desinstalemos nuestra versin previa (sea la que
usamos dirctamente con Eclipse o desde el .apkfirmado).

Aplicar una actualizacin


Lo ltimo que vamos a hacer es crear una actualizacin de nuestra aplicacin, la cual aparecer
para todos los usuarios que la tengan instalada y se pedir su descarga. Para ello modificaremos un
trozo del cdigo y aplicaremos todo lo necesario. Vamos a la clase PongGameView y localizamos
la siguiente seccin de cdigo en el mtodo onTouchEvent():
1 if(!PongOpciones.getInstance().accelerometerEnabled()){
2 .......
3 }
Lo que vamos a hacer es quitar este if y dejar lo que est dentro de l tal cual. Ahora
modificaremos nuestro AndroidManifest.xml para que se muestre una versin nueva. Como
explicamos, modificaremos los atributos versionCode y versionName, quedando as:
1 <manifest
xmlns:android="http://schemas.android.com/apk/res/android"
2 package="com.vidasconcurrentes.pongvc"android:versionCode="2"
3 android:versionName="1.1">
Lo siguiente ser volver a generar el .apk firmado. Para ello hacemos click derecho sobre el
proyecto y elegimos Android Tools > Export Signed Application Package. En esta ocasin
elegiremos el keystore que ya generamos previamente, y pondremos la contrasea que usamos
para generarlo. Elegimos el alias que sale del men desplegable y ponemos la contrasea.
Continuamos hasta generar de nuevo el .apk. Ahora volvemos a nuestra Consola del desarrollador,
y seleccionamos nuestra aplicacin pulsando en el nombre. Ahora vamos a la pestaa Archivos
APK, y hacemos click en Subir APK. Elegimos la ruta en la que se encuentra ste y pulsamos en
Publicar. Ahora tendremos dos APK subidos, uno de la versin 1.0 y otra de la 1.1, por lo que
tenemos que activar la versin 1.1 y desactivar la 1.0 que ya no vale. Pulsamos en Guardar y ya
tenemos la versin 1.1 en el Android Market. Sencillo, no? Nuestros usuarios recibirn en sus
dispositivos el aviso de que tienen que actualizar la aplicacin, pero eso ya no es cosa nuestra.
Con esta entrada hemos llegado al final de nuestro humilde curso de introduccin a la
programacin para dispositivos mviles Android. A lo largo de siete entradas extensas y con
explicaciones detalladas hemos aprendido a usar las herramientas necesarias para el desarrollo.
Entre otras de las cosas aprendidas hemos visto cmo instalar las herramientas necesarias, cmo
crear nuevas Actividades y cmo ejecutarlas a travs de Intents, cmo mandar informacin entre
Actividades, cmo usar la vibracin o el acelermetro y todo ello a travs del desarrollo de una
pequea aplicacin como es un juego sencillo, que nos ha ayudado a no notar la pesadez de
aprender todas estas cosas sin unirlas. Espero sinceramente que hayis encontrado este curso
introductorio lo ms interesante posible, y que hayis aprendido con l tanto como yo aprend
hacindolo. Un saludo a todos los lectores que habis seguido el desarrollo y muchas gracias por
dedicarle el tiempo que requiere. Que tengis buen desarrollo de vuestras propias aplicaciones!
Podis visitar el Android Market y descargar nuestra aplicacin pulsando aqu. Tambin podis ver
cmo habr quedado la aplicacin:

You might also like