Está en la página 1de 51

CURSO DE PROGRAMACIN EN

ANDROID PARA PRINCIPIANTES



IASAndro|d.com



2

IN1kCDUCCICN
Androld es hoy por hoy uno de los slsLemas operaLlvos con ms oporLunldades, donde
un desarrollador puede crear apllcaclones que sean conocldas a nlvel mundlal
uuranLe 10 semanas hemos esLado publlcando en IAsAndro|d un curso en el que
aprender a hacer una apllcacln desde cero. Pa sldo reallzado por kobert ., uno de
los edlLores del blog que Llene a sus espaldas ya algunas apllcaclones, como Pu
ConLacL hoLos.
Ll curso ha sldo recopllado en esLe ul compleLamenLe graLulLo para Lenerlo a mano
en un solo lugar.
1amblen hay a dlsposlcln de qulen qulera usarlo un nILC CIICIAL del curso en
loromvlles.com:
http:]]foromov||es.com]threads]479-Curso-de-programac|n-andro|d
INDICL
1. lnsLalacln de Lcllpse y del Suk
2. LsqueleLo de una apllcacln
3. AcLlvldades y layouLs
4. anLallas de conflguracln de la apllcacln
3. 1hreads
6. CapLura de evenLos
7. Comunlcacln con oLras apps
8. WldgeLs
9. Servlclos
10. CbLener permlsos de superusuarlo

3

CAI1ULC 1
Insta|ac|n de| Andro|d SDk y Lc||pse
Cada vez que Coogle publlca una nueva versln de su slsLema operaLlvo, y mucho
anLes de que esLa llegue a cualqulera de sus Lelefonos de forma oflclal, los de
MounLaln vlew publlcan el SDk (SofLware uevelopmenL klL) del slsLema, que conLlene
una lmagen de esLe y Lodos sus programas, asl como del framework de Androld, y que
slrve a los desarrolladores para adapLar sus apllcaclones a la nueva versln anLes de
que esLa llegue al gran publlco.
ara poder gesLlonar Lodo esLe slsLema de verslones y subverslones en un slsLema
operaLlvo vlvo, como es el caso de Androld, resulLa necesarlo un sofLware que se
encargue LanLo de la slncronlzacln de los paqueLes e lmgenes (denomlnamos
lmagen a una copla compleLa de una parLlcln) ya lnsLaladas, como de la lnsLalacln de
los nuevos de forma lo ms LransparenLe poslble.
Ln este cap|tu|o aprenderemos a |nsta|ar e| gestor de paquetes SDk de Andro|d,
fundamenta| para poder desarro||ar ap||cac|ones para este s|stema, as| como e|
entorno de desarro||o de ap||cac|ones Lc||pse, que s| b|en no es e| ms senc|||o de
ut|||zar, s| que es e| ms comp|eto y ut|||zado por desarro||adores de m|t|p|es
p|ataformas.

Gestor de paquetes SDk
ara ello Coogle proporclona el SDk Manager, un programa que se slncronlza con los
servldores de Coogle y que nos lnforma LanLo de la dlsponlbllldad de nuevos paqueLes
como del esLado de los que ya Lenemos.
La apllcacln esL dlsponlble LanLo para enLornos Wlndows como MAC CS x y Llnux, sl
blen eo este tototlol oos ceottotemos eo lo vetslo poto slstemos Mlctosoft wloJows.

4
Ln el caso de Wlndows la lnsLalacln de la apllcacln puede reallzarse medlanLe un
arch|vo compr|m|do, en formato z|p, que deberemos descomprlmlr en el dlrecLorlo
ralz del slsLema (hablLualmenLe c.\) o blen medlanLe un lnsLalador, lo que mlnlmlza no
slo el Llempo ocupado en el proceso, slno Lamblen las probabllldades de error (en
caso que opLemos por el lnsLalador, es convenlenLe lndlcar el dlrecLorlo c.\ooJtolJ-
sJk-wloJows como dlrecLorlo de lnsLalacln cuando el slsLema nos lo pregunLe).
una vez reallzada la lnsLalacln deberemos e[ecuLar el programa SDk Manager.exe
que, al abrlrlo por prlmera vez, proceder a descargar e lnsLalar el resLo de archlvos
necesarlos para la apllcacln y que no se lncluyen en la descarga lnlclal, para lo cual
neceslLar acceder a lnLerneL.
una vez que el gesLor de Suk esLe compleLamenLe lnsLalado, procederemos a lnsLalar
las verslones del Suk que neceslLemos, dependlendo de las verslones del slsLema para
las cuales vayamos a desarrollar (en nuesLro caso se recomlenda la lnsLalacln de la
versln 13, correspondlenLe a Androld 4.0.3).
Ls lmporLanLe que lnlclemos el gesLor de paqueLes varlas veces, lnsLalando las
acLuallzaclones que hublera, hasLa que el slsLema gesLor lndlque que no hay
acLuallzaclones dlsponlbles.
Aslmlsmo, en deLermlnados ordenadores, dependlendo de la conflguracln de red,
flrewalls, proxys, eLc puede ocurrlr que no se sea poslble esLablecer una conexln
segura (hLLps), en cuyo caso es poslble forzar la descarga a Lraves de una conexln
lnsegura (hLLp) accedlendo a la conflguracln del gesLor (1ools - Optloos) y marcando
la casllla fotze bttps sootces to be fetcbeJ osloq bttp.



3
A[ustes manua|es
Ln algunos slsLemas Wlndows es necesarlo deflnlr una varlable de enLorno
denomlnada ANukOlu_5uk_nOM, cuyo conLenldo ha de ser la ruLa compleLa al
dlrecLorlo de lnsLalacln del 5uk, para que Lodo funclone correcLamenLe.

ue lgual manera, en los slsLemas unlx, deben anadlrse los dlrecLorlos [dlrecLorlo-
lnsLalacln]/plaLform-Lools y [dlrecLorlo-lnsLalacln]/Lools al paLh de slsLema (varlable
de enLorno lA1n).
Insta|ac|n de Lc||pse
Lc||pse es un entorno de desarro||o de ap||cac|ones muy potente y que d|spone de
p|ug|ns para |a mayor|a de |os |engua[es de programac|n, entre e||os Andro|d, que
de hecho es un subcon[unLo de un lengua[e mayor denomlnado !ava, que fue
desarrollado orlglnarlamenLe por Sun y adapLado posLerlormenLe por Coogle.
La lnsLalacln de Lcllpse es muy sencllla y cons|ste en descompr|m|r e| conten|do de
un arch|vo z|p, que conLlene la apllcacln y las llbrerlas, en el dlrecLorlo de nuesLra
eleccln (recomendamos c.\ecllpse).
una vez lnsLalado, procederemos a acceder al mlsmo, haclendo doble cllc en el lcono
de la apllcacln, que se encuenLra en el dlrecLorlo que hayamos creado para la mlsma
(sl lo deseamos podemos crear un acceso dlrecLo al esctltotlo de la forma hablLual).

6

La prlmera vez que accedamos nos pregunLar por el dlrecLorlo de Lraba[o, que ser
aquel en el que se ublcarn Lodos los programas que desarrollemos. or comodldad,
resulLa convenlenLe marcar la casllla que lndlca al slsLema que nuesLra eleccln es
deflnlLlva, lo cual lmpedlr que, en prxlmas e[ecuclones, se nos vuelva a pregunLar
por dlcho dlrecLorlo.
|ug|n AD1 para Lc||pse
Como hemos lndlcado, Lcllpse es un enLorno de desarrollo muy poLenLe dlsponlble
para gran canLldad de lengua[es, a Lraves de los pluglns correspondlenLes.
Ll Au1 (Androld uevelopmenL 1ools) es el plugln desarrollado por Coogle para permlLlr
la lnLegracln del Suk de Androld en Lcllpse, permlLlendo el desarrollo de programas
Androld de forma naLlva desde Lcllpse.
La lnsLalacln se reallza manualmenLe desde el proplo Lcllpse slgulendo los slgulenLes
pasos:
1. Selecclonar nelp - lostoll oew softwote,
2. Pacer cllc en oJJ, en la parLe superlor derecha de la venLana,
3. Ln el dllogo lndlcar Au1 lugln" como oombte y hLLps://dl-
ssl.google.com/androld/ecllpse como locollzoclo,
4. Pacer cllc en ok,
3. Ln la venLana que aparezca, marcar la casllla [unLo a uevelopet 1ools y hacer
cllc en oext,
6. Pacer cllc en el boLn oext (cuando aparezca),
7. Leer y acepLar el acuerdo de llcencla y hacer cllc en flolsb,

7
8. Al acabar la lnsLalacln, y anLes de reallzar los pasos slgulenLes, relnlclar
ecllpse.
Al relnlclar Lcllpse, aparecer una venLana en la que nos lndlcar que, para desarrollar
en Androld es necesarlo lnsLalar el Suk. Paremos cllc en la opcln use exlstloq 5uks"
e lnLroduclremos la ruLa del dlrecLorlo de lnsLalacln que corresponda (comunmenLe
c.\ooJtolJ-sJk-wloJows).
Slo en caso que no apareclera el dllogo lndlcado en el aparLado anLerlor, deberemos
enlazar el Au1 con el gesLor de paqueLes Suk de Androld manualmenLe, para lo cual
reallzaremos los slgulenLes pasos (en Lcllpse):
1. Selecclonar wloJow - ltefeteoces,
2. Selecclonar AoJtolJ en el panel de la lzqulerda,
3. !unLo al cuadro 5uk locotloo, hacer cllc en 8towse y navegar hasLa selecclonar
el dlrecLorlo en el que se ha lnsLalado el gesLor de Suk (comunmenLe
c.\ooJtolJ-sJk-wloJows),
4. Pacer cllc en opply y despues en ok.

Creac|n de una mqu|na v|rtua|
Ll gesLor de paqueLes Suk lncluye un emu|ador Andro|d que podremos e[ecuLar para
probar nuesLras apllcaclones.
ue hecho, e| gestor se |ntegra tan b|en con Lc||pse que podremos |nc|uso debugar las
apllcaclones, generar punLos de parada, comprobar los valores de las dlferenLes
varlables, eLc.

8
ara crear la mqulna vlrLual correspondlenLe a una versln concreLa de Androld
deberemos abrlr el gesLor de paqueLes Suk y acceder a Moooqe Avus, denLro del
menu tools.

ara crear una lnsLancla del emulador haremos cllc en el boLn oew en la venLana de
gesLln de mqulnas vlrLuales, procedlendo a rellenar los campos correspondlenLes del
formularlo con los valores que slgue:
name: lCS
1argeL: Androld 4.0.3 - Al Level 13
Cu/A8l: A8M (armabl-v7a)
Su Card: Slze 32 mb
1amblen ser necesarlo anadlr soporLe para la Lar[eLa de memorla, para lo cual
haremos cllc en el boLn oew en el aparLado correspondlenLe a hardware del
formularlo, procedlendo a selecclonar la propledad 5u cotJ 5oppott, Lras lo cual
haremos cllc en ok y posLerlormenLe en cteote Avu.
Andro|d en tu C
una vez creado el emulador podemos e[ecuLarlo, para lo cual lo haremos cllc en su
nombre (en la panLalla de gesLln de mqulnas vlrLuales, y posLerlormenLe
selecclonaremos stott.
Ls normal que el emulador Larde unos mlnuLos en arrancar, dependlendo de la
poLencla del ordenador en el que lo e[ecuLemos.

9

Ln el prxlmo caplLulo hablaremos de las dlferenLes parLes de una apllcacln Androld y
crearemos nuesLra prlmera apllcacln de prueba, que e[ecuLaremos en el emulador.


10

CAI1ULC 2
Lsque|eto de una ap||cac|n Andro|d

La esLrucLura de las apllcaclones en Androld se orlenLa claramenLe al usuarlo, o qulzs
serla ms exacLo declr a su dlsposlLlvo.
Ln cualquler caso, usuarlo y dlsposlLlvo se expresan en una lengua, y esLe ulLlmo,
adems, Llene unas caracLerlsLlcas flslcas deLermlnadas y e[ecuLa una u oLra versln
del slsLema.
Asl, como veremos a conLlnuacln, cuando creemos una ap||cac|n deberemos tener
en cuenta |as caracter|st|cas de |os d|spos|t|vos a |os que se d|r|ge, tanto en |o
re|ac|onado con e| hardware como con |a vers|n de Andro|d que |o contro|a.

L| man|f|esto
L| man|f|esto (archlvo moolfest.xml en cualquler proyecLo Androld) es un arch|vo en
formato kML (e\teoslble Motkop looqooqe) en e| que se def|nen |as caracter|st|cas
genera|es de una ap||cac|n, a saber:
Ll paqueLe: Ls una cadena que descrlbe de forma unlca a una apllcacln, no
slendo poslble anadlr una apllcacln en la lay SLore sl ya exlsLe oLra con el
mlsmo nombre de paqueLe. ue lgual manera, sl lnsLalamos en nuesLro
dlsposlLlvo una app con el mlsmo nombre (de paqueLe) que oLra ya exlsLenLe,
la nueva susLlLulr a la anLerlor.
Ll nombre: Ls el nombre que aparecer en la Llenda, o el nombre que nos
ensena el lnsLalador cuando nos dlsponemos a lnsLalar la apllcacln.
La versln: Ll slsLema deflne dos numeros dlferenLes para la versln de una
apllcacln: por un lado el numero de compllacln, que debe lncremenLarse en
suceslvas acLuallzaclones (no es poslble acLuallzar en la Llenda una app con un
numero de compllacln lnferlor al de la versln exlsLenLe). ? por oLro el numero
de la versln, que es el numero que se mosLrar al usuarlo y sobre el que no
hay resLrlcclones.
La versln de Androld a la que se dlrlge: Se lndlca en esLe punLo la versln
(mlnlma y mxlma) necesarla para que la apllcacln se e[ecuLe correcLamenLe,

11
no slendo poslble lnsLalar una apllcacln en un dlsposlLlvo que Lenga una
versln de Androld que no se encuenLre en el rango especlflcado.
Los permlsos: LlsLa de permlsos que neceslLa la apllcacln para e[ecuLarse
correcLamenLe, y que se le presenLarn al usuarlo cuando lnsLale la
apllcacln. 1al y como hemos lndlcado en alguna ocasln, Andro|d no soporta
an que e| usuar|o se|ecc|one qu perm|sos desea otorgar, de entre |a ||sta de
perm|sos so||c|tados, asl que esLe deber acepLarlos Lodos para poder lnsLalar
la apllcacln.
LlsLa de acLlvldades, servlclos y recepLores de mensa[es: Lnumeraremos en esLe
aparLado las acLlvldades (venLanas) de nuesLra apllcacln, asl como los servlclos
que esLa ofrecer y los procesos de recepcln de mensa[es, asl como los
parmeLros que acLlvarn cada uno de ellos, sl los hublera.

L[ecutar un programa
Ln Andro|d |os programas no s|o se e[ecutan cuando e| usuar|o |os |nvoca, haclendo
cllc en el lcono correspondlenLe en el urawer, por e[emplo, s|no que stos tamb|n se
act|van automt|camente depend|endo de| estado de| s|stema.
Como veremos en las prxlmas seslones, es poslble lndlcar que una apllcacln, o un
servlclo ofrecldo por esLa, debe e[ecuLarse auLomLlcamenLe cuando el dlsposlLlvo se
lnlcle, o cuando se reclba una llamada o un mensa[e, por e[emplo.
Id|omas
Al prlnclplo de esLe arLlculo nos referlamos al ldloma del dlsposlLlvo, pues blen, en
Andro|d podemos persona||zar |a |engua en |a que se muestra nuestra ap||cac|n de
forma transparente tanto a| usuar|o como a |a prop|a ap||cac|n.

12
ara ello, lglcamenLe, deberemos lnclulr en nuesLra apllcacln las Lraducclones de las
dlferenLes cadenas que vlsuallzamos en esLa.
Ll dlrecLorlo tes, en un proyecLo Androld, conLlene Lodos los daLos relaclonados con los
recursos de una apllcacln, Lales como lmgenes, a las que nos referlremos a
conLlnuacln, y cadenas de caracLeres.
Asl, deberemos crear un dlrecLorlo voloes-\\ (donde \\ es un cd|go de |d|oma) para
cada una de las lenguas a las que Lraduzcamos nuesLra apllcacln, lncluyendo en dlcho
dlrecLorlo un archlvo sttloqs.xml con la descrlpcln de Lodas las cadenas en ese ldloma
concreLo.
Ll proplo slsLema se encargar de acceder al archlvo correcLo dependlendo del ldloma
que se encuenLre acLlvo en el dlsposlLlvo, sl es que hemos Lraducldo nuesLra apllcacln
a ese ldloma, o al ldloma por defecLo (lncluldo en el dlrecLorlo voloes) en caso
conLrarlo.
Ls una norma no escrlLa que en el lengua[e por defecLo de una apllcacln Androld es el
lngles, por lo que las cadenas en lngles se lnclulrn en el archlvo sttloqs.xml del
dlrecLorlo tes/voloes.
AdlclonalmenLe, y como veremos, Lamblen es poslble crear cadenas que varlen segun
la versln de Androld del dlsposlLlvo en el que se e[ecuLe la apllcacln.


13
Imgenes
1al y como ocurre con los ldlomas, es pos|b|e y en muchos casos necesar|o,
espec|f|car |mgenes e |conos d|ferentes para cada una de |as reso|uc|ones de
panta||a de Andro|d.
no hacerlo supondr que nuesLra apllcacln se ver correcLamenLe en los dlsposlLlvos
con una resolucln de panLalla slmllar a la usada duranLe el desarrollo pero no en
dlsposlLlvos con panLalla ms pequena, o ms grande.
La resolucln de una panLalla la deflne la relacln exlsLenLe enLre el Lamano de la
mlsma (que se suele descrlblr segun el Lamano en pulgadas de esLa) y la densldad de
plxeles (que es el numero de esLos que caben en una pulgada), lo que nos permlLe
hablar de panLallas pequenas (lJpl), medlanas (mJpl), grandes (bJpl) y exLra grandes
(xbJpl).
lnclulremos las lmgenes relaLlvas a cada una de las resoluclones en el dlrecLorlo
tes/Jtowoble-\\ (donde \\ es la resolucln de panLalla) que corresponda.
ue lgual manera, el dlrecLorlo tes/Jtowoble lnclulr las lmgenes que no camblan al
camblar la resolucln de la panLalla, sl las hublera.


14
"no|a mundo"
Crearemos a conLlnuacln una pequena apllcacln (de prueba), que no har nada salvo
escrlblr un mensa[e en la panLalla de nuesLro emulador, o de nuesLro Lelefono sl la
lnsLalamos en esLe, pero que nos permlLlr comprobar los concepLos expllcados en
esLe caplLulo.
ara ello reallzaremos los slgulenLes pasos:
1. Abrlr Lcllpse,
2. Selecclonar llle - New - AoJtolJ ptoject en el menu de Lcllpse,
3. Lscrlblr Ml ptlmet ptoyecto AoJtolJ" en el cuadro ltoject Nome" y hacer cllc
en Next,
4. Selecclonar AoJtolJ 4.0.J en la llsLa y hacer cllck en Next,
3. lndlcar com.fopsAoJtolJ.nellowotlJ" en el cuadro lockoqe Nome" y hacer
cllck en llolsb.
Pecho esLo, comprobaremos que en la vlsLa lockoqe xplotet" de Lcllpse ha
aparecldo un elemenLo denomlnado Ml ptlmet ptoyecto AoJtolJ", sobre el que
podremos hacer doble cllc para ver los dlferenLes elemenLos que hemos comenLado
en esLe LuLorlal.
Ln cuanLo a los dlrecLorlos qeo y blo, son dlrecLorlos lnLernos de Lcllpse y no convlene
ellmlnarlos nl modlflcarlos, mlenLras que el dlrecLorlo stc conLlene el cdlgo de nuesLro
programa, que en esLe caso slo crea una venLana que muesLra un mensa[e de LexLo.
Sl e[ecuLamos la apllcacln, comprobaremos que aparece en panLalla el anslado Pello
World". Lllo es debldo a que el esqueleLo de una apllcacln Androld lncluye una unlca
venLana que muesLra el menclonado mensa[e en panLalla.
Sl lo desels, podels camblar el valor de la cadena bello" en el archlvo
tes/voloes/sttloqs.xml.
Ln prxlmos caplLulos aprenderemos a modlflcar esLe esqueleLo para adapLarlo a
nuesLras necesldades concreLas, asl como a crear oLras venLanas segun nuesLras
necesldades.
L[ecuc|n en e| emu|ador
ara e[ecuLar esLe programa en el emulador Lan slo es necesarlo hacer cllc con el
boLn derecho del raLn en el nombre de nuesLra apllcacln y selecclonar koo As -
AoJtolJ Appllcotloo en el menu emergenLe, o hacer cllc dlrecLamenLe en el boLn
e[ecuLar de la barra de boLones de Lcllpse.



13
L[ecuc|n en un d|spos|t|vo
Sl por el conLrarlo, preferlmos e[ecuLar la apllcacln en nuesLro dlsposlLlvo, deberemos
exporLarla, para lo cual reallzaremos los slgulenLes pasos:
1. Selecclonar el nombre de la apllcacln en la vlsLa lockoqe xplotet,
2. Pacer cllc con el boLn derecho del raLn en el nombre de la apllcacln
y selecclonar xpott en el menu emergenLe.
3. Selecclonar AoJtolJ - xpott AoJtolJ Appllcotloo en la panLalla que
aparezca y pulsar Next.
4. ulsar Next,
La prlmera vez Lendremos que crear nuesLro olmoceo Je cloves, para lo cual
selecclonaremos cteote oew keystote", selecclonaremos una ruLa para el almacen de
claves (del que convendr|a tener cop|a de segur|dad) e lnLroduclremos la conLrasena
del mlsmo, que guardaremos en lugar seguro, Lras lo cual haremos cllc en Next.
Ln caso que ya hayamos flrmado alguna apllcacln (o esLa mlsma en alguna oLra
ocasln), selecclonaremos use exlstloq keystote", procedlendo a lnLroduclr la ruLa del
almacen en el cuadro correspondlenLe, asl como su conLrasena, Lras lo cual haremos
cllc en Next.
Ln la slgulenLe panLalla, en caso de que acabemos de crear el almacen de cerLlflcados,
Lendremos que crear un cerLlflcado nuevo, para lo cual deberemos rellenar un
formularlo con nuesLros daLos. Ls lmporLanLe que, por segurldad, la conLrasena no sea
la mlsma que hemos puesLo en el paso anLerlor, mlenLras que el campo ollos nos
servlr para ldenLlflcar el cerLlflcado en caso de que Luvleramos varlos.
Ln caso que el almacen de claves ya exlsLlera, slmplemenLe selecclonaremos use
exlstloq key", y procederemos a selecclonar el allas correspondlenLe, lnLroduclr su
conLrasena y hacer cllc en Next,
llnalmenLe, selecclonaremos la ruLa en la que debe almacenarse la apllcacln en el
cuadro uestlootloo Alk llle" y hacer cllc en llolsb.
uespues Lendremos que coplar el archlvo generado en el dlsposlLlvo e lnsLalarlo, para
lo cual deberemos hablllLar la lnsLalacln de apllcaclones de fuenLes exLernas (hablllLar
cooflqotoclo - seqotlJoJ - otlqeoes JescoooclJos en el dlsposlLlvo).
Un apunte
or eflclencla, Lcllpse uLlllza una cache lnLerna que le permlLe acceder a los archlvos
muy rpldamenLe.
Cuando reallzamos modlflcaclones a Lraves del proplo Lcllpse, LanLo la cache como los
proplos archlvos se acLuallzan correcLamenLe, Lal y como debe ser.

16
Sln embargo, cuando acLuallzamos dlrecLamenLe los archlvos en el dlsco, medlanLe las
uLllldades de coplar-pegar, mover, camblar de nombre, eLc del slsLema operaLlvo,
Lcllpse no reacclona Lan blen como deblera y, en ocaslones, no deLecLa esLos camblos.
ara evlLar esLo es convenlenLe forzar un refresco de la cache en Lcllpse cada vez que
hacemos algun camblo desde fuera del enLorno, para lo cual haremos cllc en el boLn
derecho del raLn enclma del nombre del proyecLo en la vlsLa lockoqe xplotet" y
selecclonaremos la opcln teftesb.
Ln el prxlmo caplLulo empezaremos el desarrollo de la apllcacln que servlr para
presenLar los dlversos componenLes de Androld, un gesLor de archlvos, cenLrndonos
en esa prlmera sesln en el dlseno de la panLalla.

17

CAI1ULC 3
Act|v|dades y Layouts en Andro|d

Una act|v|dad (del lngles octlvlty) es una tarea rea||zada por una ap||cac|n y que se
centra en |a |nteracc|n con e| usuar|o, blen sea porque un proceso neceslLa unos
daLos de esLe o por cualquler oLro moLlvo.
Asl, Lodas las acLlvldades se basan en la creacln de una venLana (a panLalla compleLa
o no), en la que se poslclonan los dlversos componenLes (boLones, cuadros de LexLo o
edlcln, lmgenes, eLc) necesarlos para la comunlcacln con el usuarlo.
Los |ayouts, que se asoclan a las dlferenLes venLanas o vlsLas, def|nen e| mapa que
perm|te a Andro|d pos|c|onar cada uno de |os e|ementos en e| |ugar correspond|ente
de |a panta||a.
1al como lndlcamos en el caplLulo anLerlor, |os |ayouts deben def|n|rse ten|endo en
cuenta LanLo el Lamano de los elemenLos que conLlene como el Lamano del elemenLo,
hablLualmenLe |a panta||a u oLro layouL, que hace de conLenedor del mlsmo, slendo
poslble deflnlr layouLs dlferenLes dependlendo del Lamano de dlcho conLenedor.
C|c|o de v|da de |as act|v|dades
Ln lnformLlca exlsLen dos concepLos bslcos, que se expllcan enLre los Lres prlmeros
dlas de carrera, y que nos acompanan duranLe Loda nuesLra vlda laboral, y que son los
concepLos de pllo y colo.
una pllo es una esLrucLura en la que el ulLlmo elemenLo que enLra es el prlmero que
sale, el penulLlmo en enLrar es el segundo en sallr y suceslvamenLe.
or conLra, una colo es una esLrucLura en la que el prlmer elemenLo en enLrar es
Lamblen el prlmero en sallr, mlenLras que el ulLlmo en enLrar ser, lglcamenLe, el
ulLlmo en sallr.
Ln Androld el slsLema gesLlona las dlferenLes acLlvldades usando el concepLo de plla,
de forma que, en un momenLo deLermlnado, s|o |a act|v|dad que se encuentra en |a
c|ma de esta p||a se est e[ecutando, mlenLras que el resLo esLn en stooJby y la
memorla que ocupan puede ser aslgnada a oLros procesos.
Asl, cuando una acLlvldad se encuenLra en prlmer plano y oLra ocupa la clma de dlcha
plla, aquella pasa a segundo plano y es suscepLlble de ser ellmlnada del slsLema, en lo
que se denomlna clclo Je vlJo Je ooo octlvlJoJ" y que se expresa grflcamenLe en la
slgulenLe lmagen.

18

Crear una act|v|dad
uesgracladamenLe el Au1 no se lnLegra con Lcllpse Lan blen como deberla, asl que
para crear una acLlvldad Lendremos que reallzar una serle de pasos (de forma manual):
Crear |a c|ase asoc|ada a |a act|v|dad, y que |mp|ementar todos sus mtodos
ara ello haremos cllc en llle - New - closs e lnLroduclremos los slgulenLes valores
en la panLalla de creacln de la clase:
ackage: Selecclonaremos el paqueLe al que perLenece la clase de enLre los
deflnldos por nuesLra apllcacln,
Name: lnLroduclremos el nombre de la acLlvldad, Lenlendo en cuenLa que no se
acepLan espaclos nl caracLeres especlales. ue hecho, una buena prcLlca es

19
poner la prlmera leLra de cada palabra que forme el nombre en mayusculas y el
resLo en mlnusculas (por e[emplo MlltlmetoActlvlJoJ),
Superc|ass: lndlcaremos que la clase que esLamos creando es una acLlvldad
lnLroduclendo el Llpo ooJtolJ.opp.Actlvlty.
SeguldamenLe haremos cllc en flolsb para crear la clase, lo cual crear el archlvo
asoclado a la clase y lo mosLrar en el edlLor de Lcllpse, para que podamos
lmplemenLar sus meLodos.

ub||c|tar |a act|v|dad
no obsLanLe, crear una acLlvldad no es slnnlmo de poder uLlllzarla, para lo cual es
necesarlo anadlrla en el manlflesLo de nuesLra apllcacln (archlvo moolfest.xml).

20
Act|var una act|v|dad
una funcln o procedlmlenLo se e[ecuLa de forma sloctooo cuando el flu[o de
e[ecucln del programa en cuesLln no vuelve al procedlmlenLo prlnclpal (el que
reallza la llamada) hasLa que la funcln que ha sldo llamada flnallza, mlenLras que una
funcln se e[ecuLa de forma osloctooo cuando el proceso que reallza la llamada slgue
e[ecuLndose aunque la funcln llamada no haya flnallzado.
La creac|n y act|vac|n de una act|v|dad es un proceso as|ncrono que se reallza
generalmenLe desde oLra acLlvldad, usando para ello las funclones stottActlvlty o
stottActlvltylotkesolt, heredadas de la superclase, y que se dlferenclan en que la
ulLlma permlLe obLener un resulLado, Lamblen de forma aslncrona.
Los |ayouts
Sl un acLlvldad deflne el conLenedor en el que se colocan los componenLes de una
venLana, un layouL descrlbe cmo se colocan dlchos componenLes en la mlsma.
Los |ayouts se estructuran en forma de rbo|, con un e|emento ra|z que se pos|c|ona
sobre |a ventana, y suceslvos comparLlmenLos (nodos) en los que se colocan los
elemenLos flnales u ho[as (lmgenes, cuadros de edlcln o de LexLo, boLones, eLc).


21
Los conLenedores de elemenLos ms uLlllzados son los de Llpo lloeotloyoot y
kelotlveloyoot.
L|nearLayout
Ls un conLenedor en el que los dlferenLes elemenLos se poslclonan uno deba[o del
oLro, o uno a la derecha del oLro, dependlendo de sl se deflne de Llpo verLlcal u
horlzonLal.
ke|at|veLayout
Se LraLa de un conLenedor ms comple[o en el que es poslble lndlcar la poslcln
relaLlva de un elemenLo respecLo de oLro, permlLlendose lncluso el solapamlenLo de
esLos.
ue hecho, por defecLo Lodos los componenLes se allnean en la parLe superlor lzqulerda
del conLenedor, slendo responsabllldad del dlsenador poslclonarlos convenlenLemenLe
medlanLe el uso de aLrlbuLos y la deflnlcln de dependenclas, segun sea el caso.
ara cada uno de |os contenedores, as| como para |os e|ementos f|na|es (botones,
|mgenes, etc) es pos|b|e def|n|r mu|t|tud de atr|butos, como por e[emplo el Lamano
horlzonLal o verLlcal, la vlslbllldad, el color o lmagen de fondo, eLc.
Descarga de |a ap||cac|n de| curso


22
Cs an|mamos a descargaros |a pr|mera parte de |a ap||cac|n que estamos
desarro||ando en este curso Andro|d, que amplla los concepLos lnLroducldos en esLas
prlmeras seslones y que conLlene un cdlgo LoLalmenLe funclonal que podrels probar
en el emulador o en vuesLros dlsposlLlvos.
una vez descarguels la apllcacln, deberels almacenarla en el dlrecLorlo de Lraba[o de
Lcllpse (el que selecclonasLels duranLe el proceso de lnsLalacln).
SeguldamenLe ser necesarlo lmporLarla desde Lcllpse, para que esLe la reconozca y
podls acceder a la mlsma, blen sea para edlLarla o para e[ecuLarla en el emulador,
para lo cual deberels segulr los slgulenLes pasos:
1. Selecclonar la opcln lmpott en el menu llle,
2. Ln la slgulenLe panLalla, selecclonar xlstloq ptoject loto wotkspoce" y pulsar
oext,
3. Pacer cllc en btowse y navegar hasLa el dlrecLorlo en el que hemos almacenado
la apllcacln (hay que enLrar en el dlrecLorlo, hasLa que veamos el archlvo
manlfesL.xml),
4. Pacer cllc en flolsb.
Ln el prxlmo bloque os expllcaremos cmo crear una panLalla de conflguracln para
vuesLras apllcaclones, asl como los meLodos que usa el slsLema para faclllLar el acceso
a los valores especlflcados por el usuarlo.

23

CAI1ULC 4
anta||as de conf|gurac|n

La prcLlca LoLalldad de las apllcaclones dlsponen de una o ms acLlvldades de
conflguracln, y pese a que serla poslble lmplemenLarlas como sl se LraLara de una
acLlvldad cualqulera, lo clerLo es que es mucho ms senc|||o usar |a AI de| s|stema
s|empre que sta ex|sta, y en el caso de las acLlvldades de conflguracln el Lema esL
resuelLo y muy blen resuelLo.
Como veremos en esLa parLe del curso androld, esLe slsLema |ncorpora una AI
espec|f|ca para tratar estas act|v|dades de conf|gurac|n que permlLe no slo
vlsuallzar la propla venLana, que se muesLra de ldenLlca manera para Lodas las
apllcaclones, proporclonando al usuarlo una sensacln de conLlnuldad que me[ora la
experlencla de uso, slno que lncorpora adems funclones especlflcas para acceder
fcllmenLe a los valores especlflcados por el usuarlo, asl como oLras que permlLen
e[ecuLar dlferenLes acclones cuando esLe cambla alguna caracLerlsLlca conflgurable.

Cmo crear una panta||a de conf|gurac|n
or comodldad, en esLe LuLorlal hablaremos de pootollos Je cooflqotoclo para
referlrnos a las acLlvldades de conflguracln, y de cotoctetlstlcos o ptefeteoclos de
usuarlo para referlrnos a cada uno de los valores que esLe puede conflgurar.
Como hemos lndlcado anLes, |as panta||as de conf|gurac|n son ventanas, sl blen en
esLe caso la superclase se denomlna ltefeteoceActlvlty y anade clerLas funclones y
procedlmlenLos que permlLen LraLar correcLamenLe las acLlvldades de esLe Llpo
aunque, en general, podemos asumlr que son slmplemenLe venLanas.
ara crear una nueva panLalla de conflguracln deberemos segulr los pasos
especlflcados en el LuLorlal anLerlor para la creacln de una acLlvldad generlca, pero
Lenlendo en cuenLa que, en esLe caso, la superclase se denomlna
ooJtolJ.ptefeteoce.ltefeteoceActlvlty.

24
no debemos olvldar que es necesarlo publlcar una referencla a la nueva acLlvldad en el
manlflesLo de nuesLra apllcacln, ya que en caso que no lo hagamos nuesLro programa
fallar cuando lnLenLemos acceder a la menclonada panLalla.
Como descr|b|r |as opc|ones de conf|gurac|n
Las dlferenLes opclones de conflguracln de nuesLra apllcacln se descrlben en un
archlvo xML que se slLua en el dlrecLorlo tes/xml de esLa, slendo poslble edlLarlo
manualmenLe o medlanLe la lnLerfaz de Lcllpse.

La creacln medlanLe Lcllpse se reallza medlanLe un aslsLenLe (ver lmagen ms arrlba
para ver cmo acceder a esLe) en el que selecclonaremos los slgulenLes valores:
kesource 1ype: reference,
I||e: Ll nombre del archlvo. ComunmenLe preferences.xml,
koot L|ement: Selecclonar referenceScreen.
una vez creado el archlvo, esLe se abrlr en el aslsLenLe, a Lraves del cual podremos
crear los dlferenLes elemenLos que lo formen.
Ln la panLalla de edlcln deberemos Lener en cuenLa que en la parLe lzqulerda nos
aparecern los dlferenLes elemenLos, esLrucLurados en forma de rbol, mlenLras que
en la parLe derecha nos aparecern las caracLerlsLlcas del elemenLo concreLo
selecclonado.


23
1amblen podremos el boLn oJJ para anadlr un nuevo elemenLo, y los boLones
temove, op y Jowo para ellmlnar, mover hacla arrlba o mover hacla aba[o el elemenLo
selecclonado, respecLlvamenLe.
uebe Lenerse en cuenLa que, Lal como se muesLra en el cdlgo de e[emplo, es
convenlenLe lnlclallzar las caracLerlsLlcas de los dlferenLes elemenLos usando
referenclas en lugar de cadenas de LexLo concreLas, ya que asl faclllLamos las
modlflcaclones posLerlores, asl como la fuLura lnclusln de Lraducclones.
Cmo detectar cuando |a panta||a de conf|gurac|n se c|erra
Lo normal es que las acLlvldades de conflguracln sean lanzadas desde oLra acLlvldad,
blen por la pulsacln de un boLn en dlcha acLlvldad, blen por la seleccln de la opcln
correspondlenLe en el menu de la mlsma.
Cuando una acLlvldad desea ser lnformada de que una acLlvldad que dependa de ella
ha flnallzado debe lnlclarla usando el procedlmlenLo stottActlvltylotkesolt, que ya os
comenLamos en la sesln anLerlor.
Cuando una acLlvldad lnlclada medlanLe esLe procedlmlenLo acabe, el slsLema se
encargar de acLlvar un evenLo (ooActlvltykesolt) en la acLlvldad orlglnadora que le
permlLlr saber que aquella ha acabado, asl como recuperar los evenLuales resulLados
de la e[ecucln.


26
Cmo detectar cuando una caracter|st|ca de conf|gurac|n camb|a
Los servlclos, que abordaremos en los slgulenLes caplLulos, se e[ecuLan sln la
lnLervencln del usuarlo, blen por la acLlvacln de un evenLo en el dlsposlLlvo, como
por e[emplo la recepcln de un mensa[e de LexLo, blen porque lmplemenLan acclones
que se e[ecuLan en segundo plano y que no requleren la lnLervencln del usuarlo.
Ls poslble que un servlclo, o cualquler oLra parLe de nuesLra apllcacln, neceslLe reclblr
una noLlflcacln (evenLo) cuando el usuarlo camble alguna de las preferenclas de esLa,
para lo cual deber e[ecuLar el meLodo teqlstetOo5boteJltefeteocecbooqellsteoet en
una lnsLancla de la clase 5boteJltefeteoces.
Ll programador debe Lener en cuenLa que es obllgaLorlo llamar al procedlmlenLo
ooteqlstetOo5boteJltefeteocecbooqellsteoet cuando la necesldad de reclblr el evenLo
acabe o, en ulLlmo Lermlno, cuando el ob[eLo que reclbe el evenLo se desLruya, ya que
en caso conLrarlo la apllcacln fallar.
Cmo acceder a un va|or de una caracter|st|ca concreta
Ls poslble acceder a las preferenclas de usuarlo en cualquler momenLo duranLe la
e[ecucln de nuesLras apllcaclones, para lo cual deberemos crear una lnsLancla de un
ob[eLo de Llpo 5boteJltefeteoces, sobre la que usaremos los meLodos qet8ooleoo,
qetlot, qetlooq, qetlloot o qet5ttloq segun corresponda.


27
Cmo mod|f|car manua|mente e| va|or de una caracter|st|ca concreta
Aunque no es usual, es poslble que en una apllcacln debls modlflcar manualmenLe
una preferencla de usuarlo, por e[emplo para refle[ar la desacLlvacln de una
propledad porque la apllcacln no ha sldo reglsLrada.
Ll cdlgo que os mosLramos a conLlnuacln permlLe reallzar dlcha modlflcacln.
publlc vold seLreference (ConLexL conLexL, SLrlng key, SLrlng value)
[
Sharedreferences.LdlLor preferences_edlLor =
referenceManager.geLuefaulLSharedreferences(conLexL).edlL(),
preferences_edlLor.puLSLrlng(key, value),
preferences_edlLor.commlL(),
}
u es e| contexto de una ap||cac|n
Ln el cdlgo anLerlor hemos lnLroducldo una varlable de nombre cootext, de la cual no
hablamos hablado con anLerlorldad, y que es de Llpo cootext.
Ll Llpo cootext represenLa una lnLerfase de lnformacln global acerca de la apllcacln,
y es usado slempre que se neceslLa acceder al slsLema o a daLos concreLos de esLa.
Muy a ba[o nlvel, las venLanas son de Llpo cootext, por lo que heredan Lodas sus
propledades.
Asl, cuando llamemos a la funcln anLerlor desde una acLlvldad, podremos reallzar la
llamada de la forma
seLreference(Lhls, key, value),
Ln e| prx|mo cap|tu|o os hab|aremos de |os threads, que permlLen e[ecuLar varlas
parLes de cdlgo de forma concurrenLe (slmulLnea), y os expllcaremos las
resLrlcclones que les afecLan.
Cs recomendamos que os descargu|s |a nueva vers|n de |a ap||cac|n de prueba
que esLamos desarrollando.

28

CAI1ULC S
1hreads

Algo que no hemos vlsLo hasLa el momenLo en nuesLro Curso Androld es la capacldad
de Lener hllos paralelos de procesamlenLo.
lnlclalmenLe, los slsLemas operaLlvos slo eran capaces de reallzar una unlca Larea de
forma slmulLnea, lo que bloqueaba el proceso, y hasLa el ordenador, cuando esLe
Lenla que reallzar clculos lmporLanLes o una operacln de enLrada/sallda.
Ms adelanLe, los slsLemas fueron capaces de e[ecuLar varlos procesos dlferenLes a la
vez, de forma concurrenLe, lo que permlLla opLlmlzar el uso de la Cu, aprovechando
los Llempos en que esLa esLaba desocupada para e[ecuLar oLras Lareas.

Andro|d es un s|stema mu|t|-proceso, lo que qulere declr que es capaz de e[ecuLar
varlos procesos (Lareas) de forma slmulLnea, y mu|t|-f|u[o, que slgnlflca que puede
e[ecuLar de forma slmulLnea dos o ms porclones de cdlgo del mlsmo proceso.
kecotJemos poe los ptocesos se ejecotoo eo cootextos sepotoJos, pot lo poe oo
compotteo Jotos, mleottos poe los flojos o bllos Je oo mlsmo ptoceso se ejecotoo eo el
mlsmo cootexto, pot lo poe compotteo el mlsmo espoclo Je memotlo y poeJeo
lotetfetlt eotte ellos, lo poe Jebe set teolJo eo coeoto pot el ptoqtomoJot.
Andro|d es un s|stema fuertemente or|entado a| usuar|o, y a la lnLeraccln de esLe
con el slsLema, que se hace efecLlva por medlo de cllcs, pulsaclones en la panLalla o en
los boLones, eLc.
Cuando e| usuar|o |nteracc|ona con una ap||cac|n y sta est ocupada en otros
quehaceres, e| s|stema |e as|gna un !"#$%& (# )*+,"+ para que f|na||ce |o que est
hac|endo y at|enda a| usuar|o, asumlendo el slsLema que la apllcacln ha de[ado de
funclona en caso que no lo haga, lo que provoca que el slsLema la flnallce

29
auLomLlcamenLe, lo que se conoce con el nombre de ANk y que, [unLo con el de
sobras conocldo lc, es el mensa[e de error ms hablLual en Androld.
Ll programador deber Lener en cuenLa esLe hecho y no reallzar en el hllo prlnclpal
operaclones que puedan bloquear el proceso, Lales como bucles con un alLo numero
de lLeraclones, operaclones de enLrada/sallda, accesos a lnLerneL, eLc.

Convert|r una ap||cac|n s|ng|e-thread en mu|t|-thread
Andro|d d|st|ngue entre h||o pr|nc|pa| de un proceso y todos sus h||os secundar|os,
perm|t|ndose n|camente a| h||o pr|nc|pa| acceder a |a |nterfase grf|ca.
Asl, aunque podemos usar un hllo separado para calcular los dlferenLes elemenLos de
una llsLa (llstvlew), deberemos usar el hllo prlnclpal para anadlr los dlferenLes
elemenLos a la vlsLa y para redlbu[arla, sl es el caso.
Ln realldad, converLlr una apllcacln que se e[ecuLa en un unlco hllo en mulLl-hllo es
ms senclllo de lo que parece.
La c|ase -.*#+(
Androld lmplemenLa los dlferenLes Lhreads que se e[ecuLan en un deLermlnado
momenLo usando la superclase 1bteoJ, que deflne un procedlmlenLo denomlnado too
que conLlene Lodo el cdlgo que e[ecuLar un hllo concreLo.
Asl, para lnlclar un nuevo hllo, Lan slo es necesarlo lnsLanclar una varlable de Llpo
1bteoJ, en la que habremos lmplemenLado convenlenLemenLe el procedlmlenLo
menclonado en el aparLado anLerlor, y e[ecuLar la funcln stott, Lal como se muesLra
ms aba[o.

class My1hread exLends 1hread
[
publlc vold run ()
[
...

30
}
}
1hread my1hread = new My1hread(),
my1hread.sLarL(),
Ll programador debe Lener en cuenLa que Lras la llamada al procedlmlenLo stott, el
proceso prlnclpal (el que ha hecho la llamada) conLlnuar su e[ecucln, que se reallzar
de forma paralela a la del nuevo hllo.
Aslmlsmo, debe Lener en cuenLa que e| s|stema no |e not|f|car cuando e| h||o f|na||ce
(al acabar la funcln too), por lo que deber ser el proplo hllo el que envle la
noLlflcacln, sl es el caso.

La c|ase /+0(1#*
LxlsLen dlferenLes maneras de envlar mensa[es enLre los dlferenLes hllos que
lmplemenLan un proceso, slendo la ms eleganLe, y comunmenLe uLlllzada, la que se
lmplemenLa usando lnsLanclas de la clase nooJlet.
un nooJlet es un ob[eLo de slsLema capaz de procesar los dlferenLes mensa[es que
reclbe, segun el Llpo de esLos y los parmeLros adlclonales que se reclban.
Ls el proplo slsLema el que se encarga de envlar, de forma aslncrona, los mensa[es al
nooJlet adecuado, que lo procesa en el conLexLo del flu[o que lo ha creado, lo que
permlLe conLexLuallzacln.
kecotJemos poe ooo llomoJo o oo ptoceJlmleoto es osloctooo coooJo oo teoemos
qotootlos Je poe el cJlqo llomoJo se ejecote ootes Je poe lo llomoJo floollce.

31

class MyPandler exLends Pandler
[
publlc vold processMessage (Message message)
[
swlLch message.whaL
[
...
}
}
}
Pandler myPandler = new MyPandler(),
.
Message message = new Message(),
message.whaL = 1,
myPandler.sendMessage(message),
Cmo v|sua||zar datos en una ap||cac|n mu|t|-f|u[o
Como hemos lndlcado, s|o e| h||o pr|nc|pa| puede acceder a |a UI, por lo que ser
esLe el unlco que podr lnLeracLuar con los dlferenLes elemenLos que conformen las
dlferenLes venLanas de nuesLra apllcacln.

ue hecho, es una buena prcLlca que el hllo prlnclpal se encargue solamenLe de
procesar los dlferenLes evenLos que genere el usuarlo y/o la propla apllcacln,
lnlclando hllos nuevos para lmplemenLar las operaclones de enLrada/sallda y/o

32
aquellas operaclones de proceso de daLos que no sean Lrlvlales, Lenlendo en cuenLa
que el cosLe (en Llempo) de crear un nuevo hllo, aunque no es elevado, no es
despreclable.
ara ello deflnlremos una lnsLancla de la clase nooJlet en el hllo prlnclpal que se
encargar de procesar (aslncronamenLe) los mensa[es que le envlan los dlferenLes
hllos lndlcando que han flnallzado sus Lareas, procedlendo a redlbu[ar vlsLas, anadlr o
ellmlnar elemenLos grflcos, eLc en el hllo prlnclpal.
La c|ase kunnab|e
Ln !ava no exlsLe la herencla mulLlple, por lo que cuando exLendemos una clase de Llpo
1hread perdemos la poslbllldad de hacer que exLlenda oLra, de ahl que los Lhreads se
usen slo para lmplemenLar operaclones que emplezan y acaban, ya que cuando la
funcln too flnallza Lamblen se acaba el ob[eLo que la deflne.
ara evlLar esLo, se cre la clase kooooble, que no exLlende una clase, slno que
permlLe lmplemenLar meLodos de acceso a la mlsma, lo que permlLe una mayor
versaLllldad.
Asl, la clase 1bteoJ se ocupa hablLualmenLe de lmplemenLar operaclones comple[as en
Lareas, mlenLras que la clase kooooble lmplemenLa Lareas compleLas. Ls declsln del
programador eleglr cundo uLlllzar una u oLra.
Ln el prxlmo caplLulo veremos cmo capLurar los evenLos (de usuarlo y de slsLema),
algunos de los cuales ya hemos lnLroducldo brevemenLe en seslones anLerlores.
M|entras tanto, puedes descargar |a vers|n nmero 3 de |a ap||cac|n que estamos
desarro||ando, en la que comprobars cmo obLenemos la llsLa de archlvos de un
dlrecLorlo en un hllo separado y cmo envlamos un mensa[e al hllo prlnclpal cuando
esLa llsLa ya esL compleLa, procedlendo esLe a acLuallzar la llsLa que se muesLra al
usuarlo.





33

CAI1ULC 6
Captura de eventos

Ln seslones anLerlores de nuesLro curso Androld Le hemos expllcado cmo crear Lu
prlmera apllcacln, asl como la manera de opLlmlzarla usando mulLlples hllos de
procesamlenLo, en esLa ocasln Le ensenaremos a reclblr evenLos del slsLema y/o de
oLras apllcaclones.
Ln Androld dlsLlngulmos dos Llpos de evenLos:
Los relaclonados con la lnLerfaz grflca, como por e[emplo los relaclonados con el clclo
de vlda de una acLlvldad y/o los cllcs en los dlferenLes elemenLos que conforman una
venLana, y que son programables medlanLe el proplo lengua[e !ava.
Ll resLo de evenLos, que no se refleren a la lnLerfaz grflca, y que no son dlrecLamenLe
LraLables medlanLe las funclones y procedlmlenLos esLndar de !ava, como por
e[emplo la deLeccln de la llegada de un nuevo mensa[e de LexLo o del apagado de la
panLalla.

Lventos de |a ap||cac|n
Como lndlcamos en el caplLulo anLerlor, el lengua[e de programacln !ava permlLe a
una clase lncorporar las funclones y procedlmlenLos de oLra medlanLe la uLlllzacln de
las dlrecLlvas exteoJs (exLlende, hereda) o lmplemeots (lmplemenLa).
Las "0!#*2+,#3 son c|ases abstractas que se usan para def|n|r mtodos de enLrada
(callbacks) que se cod|f|can en |a c|ase que |os |mp|ementa.
Las lnLerfaces son uLlllzadas por el slsLema para lmplemenLar los evenLos
(generalmenLe los cllcs en boLones, evenLos de los Lemporlzadores, eLc), y pueden

34
lmplemenLarse a Lraves de una clase o de forma annlma, Lal como se lndlca en los
e[emplos que slguen.
Imp|ementac|n a travs de una c|ase
class MyClass lmplemenLs CnCllckLlsLener [ MyClass() [ 8uLLon buLLon, ...
buLLon.seLCnCllckLlsLener(Lhls), } publlc vold onCllck(vlew vlew) [ ... } }
Imp|ementac|n ann|ma
class MyClass lmplemenLs CnCllckLlsLener [ MyClass() [ 8uLLon buLLon, ...
buLLon.seLCnCllckLlsLener(new CnCllckLlsLener() [ publlc vold onCllck(vlew vlew)
[ ... } }), } }
Ctros eventos
Los evenLos exLernos a la propla apllcacln se lmplemenLan a Lraves de una clase
denomlnada 8tooJcostkecelvet, la cual lmplemenLa el meLodo ookecelve, que es el
punLo de acceso a los ob[eLos de dlcha clase.
S| e| programador desea que un evento concreto, por e[emplo el que se acLlva cuando
el slsLema acaba de lnlclarse y esL preparado para e[ecuLar programas, se act|ve
|nc|uso s| |a ap||cac|n que |o rec|be no se est e[ecutando, debe dec|arar|o en e|
man|f|esto, lo que lndlcar al slsLema esLe hecho y lo preparar para e[ecuLarlo cuando
sea necesarlo.
<manlfesL ...> <appllcaLlon ...> <recelver
androld:name=".8ooLCompleLed8roadcasL8ecelver"> <lnLenL-fllLer> <acLlon
androld:name="androld.lnLenL.acLlon.8CC1_CCMLL1Lu" /> </lnLenL-fllLer>
</recelver> </appllcaLlon> </manlfesL>
Ll programador es el encargado de lncorporar a su proyecLo las clases que
lmplemenLan cada uno de los 8roadcasL8ecelver que declare (en el e[emplo anLerlor
habrla que deflnlr la clase 8ootcompleteJ8tooJcostkecelvet, que exLenderla las
propledades de la clase 8tooJcostkecelvet).
AdlclonalmenLe, debe Lenerse en cuenLa que a|gunos eventos son de acceso
pr|v||eg|ado, por |o que neces|tan que el usuarlo sumlnlsLre a la apllcacln una ser|e
de perm|sos cuando esLa se lnsLala, y que Lamblen deben enumerarse en el
manlflesLo.
<manlfesL ...> <uses-permlsslon androld:name="androld.permlsslon.8LCLlvL_SMS"
/> </manlfesL>
no obsLanLe, Lamblen es poslble deflnlr un tecelvet que monlLorlce evenLos slo
cuando la apllcacln, o un deLermlnado servlclo o acLlvldad, se encuenLran en

33
e[ecucln, para lo cual debe lmplemenLarse la correspondlenLe lnsLancla de la clase
8tooJcostkecelvet e lnsLanclarse Lal como se lndlca en el e[emplo.
class MyAcLlvlLy exLends AcLlvlLy [ class MyAcLlvlLy8roadcasL8ecelver exLends
8roadcasL8ecelver [ publlc vold on8ecelve(ConLexL conLexL, lnLenL lnLenL) [ ...
} } prlvaLe 8roadcasL8ecelver l8roadcasL8ecelver = new
MyAcLlvlLy8roadcasL8ecelver(), publlc vold on8esume() [ super.on8esume(),
reglsLer8ecelver(l8roadcasL8ecelver, new lnLenLlllLer(lnLenL.AC1lCn_SC8LLn_Cll)),
} publlc vold onause() [ unreglsLer8ecelver(l8roadcasL8ecelver),
super.onause(), } }
nLese que los evenLos empezarn a monlLorlzarse a parLlr de la llamada al
procedlmlenLo teqlstetkecelvet (presenLe en las clases Actlvlty y 5etvlce) y de[arn de
monlLorlzarse Lras la llamada a ooteqlstetkecelvet (que debe reallzarse forzosamenLe
anLes de que el ob[eLo sea desLruldo, para evlLar errores posLerlores).
kecepc|n de parmetros
Ll procedlmlenLo ookecelve de la clase 8tooJcostkecelvet se e[ecuLa cuando se acLlva
el evenLo para el cual ha sldo programado, reclblendo como parmeLros el cootexto de
la apllcacln en el que se e[ecuLa y un loteot que conLlene el Llpo de evenLo acLlvado
(loteot.qetActloo), asl como el resLo de parmeLros asoclados al mlsmo (acceslbles
usando las funclones loteot.qet8ooleooxtto, loteot.qetlotxtto, eLc).

Ln cuanLo a la apllcacln de esLos a nuesLro programa de e[emplo, no hemos
enconLrado la poslbllldad de apllcarlos, por |o que hemos creado un proyecto nuevo,
en e| que detectaremos cundo se enc|ende o apaga |a panta||a de nuestro
d|spos|t|vo. Cs recomendamos que hagls un segulmlenLo del archlvo de loq, para |o
cua| pod|s usar e| comando "oJb loqcot".

36

CAI1ULC 7
Comun|cac|n con otras Apps

Ln el caplLulo anLerlor de nuesLro curso Androld vlmos cmo hacer que nuesLra
apllcacln lnLeracLue con los evenLos del slsLema para, por e[emplo, e[ecuLar una
accln cuando la panLalla se apaga, o se enclende.
Ln esLa ocasln, usaremos el mlsmo prlnclplo para consegulr que dos apllcaclones
dlferenLes se envlen mensa[es a Lraves del slsLema.
Ln Androld, y en la mayorla de los slsLemas operaLlvos modernos, |as ap||cac|ones se
e[ecutan en espac|os de memor|a separados, lo que aumenLa la segurldad de esLe al
lmpedlr que una apllcacln mallnLenclonada, o no, afecLe al funclonamlenLo de oLra.
ara las conLadas ocaslones en las que neceslLemos envlar mensa[es enLre
apllcaclones, el slsLema provee de una lnLerfaz que permlLe LanLo la Lransmlsln como
la recepcln auLomLlca de los mlsmos, slempre y cuando la apllcacln que reclbe el
mensa[e esLe preparada para ello.
Lnv|ar un mensa[e
ara la Lransmlsln del mensa[e uLlllzaremos un ob[eLo que los seguldores de esLe
curso ya conocen, el loteot, que permlLe el paso de lnformacln a Lraves de la colo Je
eveotos Je AoJtolJ.
Al lnlclallzar el ob[eLo slmplemenLe deberemos Lener en cuenLa que deberemos lndlcar
el nombre del paqueLe y la clase que debe reclblr el mensa[e, asl como la accln
concreLa que lmplemenLa el mensa[e, que permlLlr al recepLor obLener
correcLamenLe los parmeLros que lncluyamos.
lnLenL lnLenL = new lnLenL(), lnLenL.seLClassname(nCM88L_uLL_ACuL1L",
nCM88L_uL_LA_CLASL"), lnLenL.seLAcLlon(nCM88L_uL_LA_ACClCn"),
lnLenL.puLLxLra(nCM88L_uLL_A8ML18C_1", vALC8_uLL_A8ML18C_1"), .
lnLenL.puLLxLra(nCM88L_uLL_A8ML18C_n", vALC8_uLL_A8ML18C_n"),
llnalmenLe, envlaremos el mensa[e usando el procedlmlenLo aslncrono
seoJ8tooJcost, que lncorpora la superclase cootext, y por ende Lamblen las clases
Actlvlty y 5etvlce, que son las que hablLualmenLe LraLan esLos Lemas
conLexL.send8roadcasL(lnLenL),


37
kec|b|r un mensa[e
ara la recepcln del mensa[e deberemos usar el mecanlsmo lndlcado en la sesln
anLerlor para la recepcln de evenLos del slsLema, es declr, deflnlr la accln en el
manlflesLo de nuesLra apllcacln, asoclndolo a la mlsma clase que se usa al envlarlo,
Lal como se lndlca a conLlnuacln.
<recelver androld:name="nCM88L_uL_LA_CLASL" androld:exporLed="Lrue">
<acLlon androld:name="nCM88L_uL_LA_ACClCn" /> </recelver>
1al como se lndlca en el e[emplo anLerlor, no deberemos olvldar anadlr el aLrlbuLo
expotteJ que lndlca que la clase puede ser acLlvada desde oLras apllcaclones, Lal como
es el caso.




38
Devo|uc|n de resu|tados
Ln caso que la apllcacln que reclbe el mensa[e deba devolver algun Llpo de resulLado,
deberemos uLlllzar el mlsmo mecanlsmo descrlLo anLerlormenLe (creacln de un nuevo
loteot y envlo a la prlmera apllcacln, en la cual habremos deflnldo un
8tooJcostkecelvet que se encargar de procesar el resulLado, de forma aslncrona).
Act|var otras ap||cac|ones
Ln ocaslones puede resulLar uLll que vuesLra apllcacln acLlve oLras apllcaclones, blen
se LraLe de apllcaclones de slsLema o de apllcaclones que hayls descargado de la lloy
5tote, o de alguna oLra Llenda oflclal.
Ln general Androld no ofrece una lnLerfaz de acLlvacln para las apllcaclones de
slsLema, por lo que un meLodo que funclona correcLamenLe en una versln puede no
funclonar en la slgulenLe acLuallzacln del slsLema, no obsLanLe, los e[emplos que os
proporclonamos a conLlnuacln se han mosLrado funclonales.
Act|var |a bande[a de entrada de mensa[es de texto
lnLenL lnLenL = new lnLenL(), lnLenL.seLClassname("com.androld.mms",
"com.androld.mms.ul.ConversaLlonLlsL"), lnLenL.seLAcLlon(lnLenL.AC1lCn_MAln),
lnLenL.addCaLegory(lnLenL.CA1LCC8?_uLlAuL1),
lnLenL.seLllags(lnLenL.lLAC_AC1lvl1?_nLW_1ASk |
lnLenL.lLAC_AC1lvl1?_SlnCLL_1C | lnLenL.lLAC_AC1lvl1?_CLLA8_1C |
lnLenL.lLAC_AC1lvl1?_nC_PlS1C8? |
lnLenL.lLAC_AC1lvl1?_CLLA8_WPLn_1ASk_8LSL1),
Act|var e| reg|stro de ||amadas
lnLenL lnLenL = new lnLenL(), lnLenL.seLAcLlon(lnLenL.AC1lCn_vlLW),
lnLenL.seL1ype(CallLog.Calls.CCn1Ln1_1?L),
lnLenL.seLllags(lnLenL.lLAC_AC1lvl1?_nLW_1ASk |
lnLenL.lLAC_AC1lvl1?_SlnCLL_1C | lnLenL.lLAC_AC1lvl1?_CLLA8_1C |
lnLenL.lLAC_AC1lvl1?_nC_PlS1C8? |
lnLenL.lLAC_AC1lvl1?_CLLA8_WPLn_1ASk_8LSL1),
odels enconLrar lnformacln sobre la acLlvacln de oLras apllcaclones de slsLema en
Cooqle, para lo que os recomendamos la slgulenLe busqueda: opeo
NOM8k_AlllcAclN -loteot" o en el foro de desarro||adores stackoverf|ow.com
Ln cuanLo a las apllcaclones de usuarlo, y pese a que las lnLerfases de acceso Lamblen
pueden varlar, el mecanlsmo es el slgulenLe:
1. uecompllar la apllcacln para acceder al manlflesLo de la mlsma.
2. Abrlr el manlflesLo con un edlLor de LexLo.

39
3. Los poslbles punLos de enLrada a la mlsma son aquellos que Lengan
aslgnado el aLrlbuLo exporLed, Lal como hemos lndlcado anLerlormenLe.
LglcamenLe, habr que perder algun Llempo en comprobar los efecLos que Llene la
acLlvacln de cada uno de ellos, hasLa enconLrar el que hace lo que queremos que
haga, sl es que lo hay.
Algunas apllcaclones, como por e[emplo el calendarlo, generan mensa[es que pueden
ser capLurados por oLras apllcaclones, lo que permlLe no slo su monlLorlzacln, slno
Lamblen su susLlLucln, segun el caso.
uado que esLos mensa[es no son parLe del nucleo de Androld, no es poslble obLener
documenLacln de Coogle sobre esLe Lema, por lo que su deLeccln no es fcll y se
reallza medlanLe la mon|tor|zac|n de |os |ogs de s|stema y el segulmlenLo del cdlgo
fuenLe de las proplas apllcaclones, que es poslble obLener en d|versos repos|tor|os,
como e| de CyanogenMCD.

40


CAI1ULC 8
W|dgets

Ln los dos ulLlmos caplLulos de nuesLro curso Androld hemos expllcado como el
programador puede hacer que las apllcaclones capLuren los evenLos que genera el
slsLema, u oLras apllcaclones, asl como la manera en que deben generarse los evenLos
para que puedan ser capLurados por oLras apllcaclones, lo que se aparLaba un poco del
Lema prlnclpal del curso pero que conslderbamos lnLeresanLe para enLender el
funclonamlenLo de Androld.
nos dlsponemos ahora a conLlnuar desarrollando nuesLro exp|orador de arch|vos, a|
que en este cap|tu|o proveeremos de un w|dget que permlLlr al usuarlo crear
accesos dlrecLos a un dlrecLorlo concreLo, lo que nos permlLlr no slo expllcaros cmo
se crea y dlbu[a el wldgeL, slno Lamblen cmo se vlsuallza la pglna de conflguracln
del mlsmo.
Ln Androld, un w|dget es un cuadro grf|co que se pos|c|ona en e| escr|tor|o, y en
algunos casos Lamblen en la panLalla de bloqueo, y que perm|te a |as ap||cac|ones
mostrar |nformac|n, a menudo d|nm|ca, y a |os usuar|os acceder a func|ones
espec|f|cas de sta.


41
ara poder dlsenar un wldgeL es necesarlo responder prlmero a las slgulenLes
pregunLas:
Cue queremos mosLrar en el wldgeL,
Se puede conflgurar la lnformacln que aparece en el wldgeL,
Cuando se refrescar la lnformacln del wldgeL,
Cmo lnLeracLuar el usuarlo con el wldgeL, sl es que eso es poslble,
Adems, y como veremos a conLlnuacln, ser necesarlo Lener en cuenLa al lnlclar el
proceso de acLuallzacln que e| usuar|o puede haber aad|do ms de un w|dget.
u queremos mostrar en e| w|dget
L| conten|do de| w|dget se def|ne de lgual manera que el conLenldo de una acLlvldad
(venLana), es declr, med|ante un |ayout que conLendr los dlferenLes elemenLos de
esLe.
Aslmlsmo, Lamblen deberemos deflnlr el wldgeL en el manlflesLo de la apllcacln, Lal
como se lndlca a conLlnuacln.
La accln capLurada (ooJtolJ.oppwlJqet.octloo.AllwluC1_uluA1) slrve para
lndlcar al slsLema que la clase debe reclblr los evenLos de acLuallzacln del wldgeL, Lal y
como ya lndlcamos en clases anLerlores.
AdlclonalmenLe, deberemos lndlcar las caracLerlsLlcas bslcas del wldgeL, Lales como el
Lamano, el Llempo Lras el cual debe acLuallzarse el wldgeL y el layouL lnlclal en el
archlvo tes/xml/wlJqet.xml (o el nombre que hayamos lndlcado en el manlflesLo).
Se puede conf|gurar |a |nformac|n que aparece en e| w|dget
Ln caso que nuesLro wldgeL sea conflgurable, deberemos lndlcarlo en el archlvo
tes/xml/wlJqet.xml, lo cual forzar la creacln de una acLlvldad lnlclal en la que el
usuarlo lnLroduzca los parmeLros de conflguracln de aquel.
Aunque podemos usar cualquler mecanlsmo para almacenar los parmeLros de
conflguracln del wldgeL, lo ms convenlenLe es uLlllzar la clase Sharedreferences,
cuyo funclonamlenLo ya conocels.
AdlclonalmenLe, deberemos Lener en cuenLa que lnLernamenLe Androld lmplemenLa la
llamada a la acLlvldad de conflguracln medlanLe la e[ecucln del procedlmlenLo
ooActlvltykesolt, por lo que sl la acLlvldad de conflguracln acaba con un cdlgo de
e[ecucln (tesoltcoJe) dlferenLe de Actlvlty.k5ul1_Ok, la adlcln del wldgeL se
cancelar.



42
Cundo se refrescar |a |nformac|n de| w|dget
Ll wldgeL se refresca cuando se acLlva el evenLo
ooJtolJ.oppwlJqet.octloo.AllwluC1_uluA1, que deberemos capLurar
convenlenLemenLe en el cdlgo que lmplemenLe nuesLro wldgeL (ver procedlmlenLo
ooupJote de la clase wlJqet en el e[emplo).
Ls poslble forzar la acLlvacln de dlcho evenLo medlanLe el broadcasL correspondlenLe,
Lal y como se muesLra en el cdlgo de e[emplo.
Cmo |nteractuar e| usuar|o con e| w|dget, s| es que eso es pos|b|e
Los wldgeLs son ob[eLos dlnmlcos en el senLldo que su conLenldo puede ser
modlflcado dlnmlcamenLe por la apllcacln, medlanLe la capLura del evenLo
AllwluC1_uluA1 enunclado en los prrafos anLerlores.

no obsLanLe, lo ms probable es que nos lnLerese la lnLeraccln con el usuarlo,
hablLualmenLe medlanLe el evenLo ONcllck sobre la vlsLa que conLlene a nuesLro
wldgeL, para lo cual deberemos usar el procedlmlenLo setOocllckleoJloqloteot, que
usaremos para que al cllcar el wldgeL se genere un broadcasL, se acLlve una venLana,
eLc.

43

CAI1ULC 9
Serv|c|os

Un serv|c|o es una sub-ap||cac|n que se e[ecuta en segundo p|ano, norma|mente s|n
|nteracc|n con e| usuar|o, y que rea||za una ser|e de tareas depend|endo de |a
act|vac|n de determ|nados eventos externos (aquellos para cuya aLencln ha sldo
programado), Lales como la recepcln de un correo elecLrnlco, la acLlvacln de un
Lemporlzador, eLc.
Ln Andro|d |os serv|c|os se e[ecutan en e| contexto de| proceso a| que pertenecen,
que no es ms que aquel que los ha creado, por lo que pueden acceder a cualqulera de
los ob[eLos creados por esLe, a excepcln de los relaclonados con la lnLerfase grflca,
que Lal como sucedla con los 1hreads, son acceslbles unlcamenLe desde el flu[o
prlnclpal.
1al y como se aprecla en la lmagen lnferlor, el clclo de vlda de un servlclo se slLua enLre
la acLlvacln de los evenLos onCreaLe y onuesLroy, garanLlzando el slsLema que una
acLlvacln del evenLo onCreaLe asoclado a un servlclo se complemenLar medlanLe la
acLlvacln del evenLo onuesLroy correspondlenLe.


44
Aunque no es obllgaLorlo, lo hablLual es que el evenLo oocteote asoclado a un servlclo
se encargue de la lnlclallzacln de un ob[eLo de Llpo 8tooJcostkecelvet que se
encargar de monlLorlzar los evenLos (exLernos o lnLernos) que acLlven o desacLlven el
servlclo, mlenLras que el evenLo oouesttoy se encargar de desLrulr el menclonado
ob[eLo.
Def|n|c|n de un serv|c|o
Al lgual que ocurre con las acLlvldades, los servlclos deben deflnlrse en el moolflesto de
nuesLra apllcacln, Lal como se lndlca a conLlnuacln, Lenlendo en cuenLa que la clase
que lmplemenLe el servlclo deber heredar de la superclase 5etvlce.
<servlce androld:name=".ServlceClassname" />
Instanc|ac|n de un serv|c|o
Al lgual que ocurre con las acLlvldades, no pueden cohex|st|r en e| s|stema dos
serv|c|os de |a m|sma c|ase, por lo que anLes de lnsLanclar un servlclo deberemos
comprobar sl esLe ya se esL e[ecuLando, procedlendo a acLlvarlo medlanLe un evenLo
o a lnsLanclarlo segun sea el caso, Lal como se muesLra en el e[emplo.
boolean ls_runnlng = servlce8unnlng(), lnLenL lnLenL = ls_runnlng ? new lnLenL() : new
lnLenL(conLexL, servlce_class), lnLenL.seLAcLlon(acLlon), lf (ls_runnlng)
conLexL.send8roadcasL(lnLenL), else conLexL.sLarLServlce(lnLenL),
Destrucc|n de un serv|c|o
La acLlvacln de un evenLo provoca que una porcln de cdlgo asoclada a un servlclo
se e[ecuLe, pero esLe permanece resldenLe en memorla, a la espera de que el mlsmo u
oLro evenLo se acLlve, hasLa que el servlclo es expllclLamenLe desLruldo, lo cual puede
hacerse medlanLe la llamada stop5etvlce (a la que se le pasa como parmeLro el Llpo
de servlclo a deLerner) o medlanLe la llamada al procedlmlenLo stop5elf asoclada al
servlclo.
proLecLed synchronlzed sLaLlc vold sLopServlce(SLrlng servlce_name, Servlce servlce) [
uebug.d(servlce_name, "SLopplng servlce"), servlce.sLopSelf(), } proLecLed
synchronlzed sLaLlc vold sLopServlce(ConLexL conLexL, SLrlng servlce_name,
Classservlce_class) [ uebug.d(servlce_name, "SLopplng servlce"),
conLexL.sLopServlce(new lnLenL(conLexL, servlce_class)), }
Act|vando un evento en un serv|c|o
1al como hemos lndlcado con anLerlorldad, lo hablLual es que Lodo servlclo lleve
asoclado un ob[eLo 8tooJcostkecelvet que slrve como punLo de enLrada al servlclo.
LsLa lnsLancla de la clase 8tooJcostkecelvet lmplemenLa el cdlgo asoclado al
procesamlenLo de los evenLos exLernos (del slsLema) que aLlende el servlclo, asl como

43
el cdlgo asoclado a los evenLos de la propla apllcacln que pueden modlflcar el
comporLamlenLo del servlclo, que suelen asoclarse a evenLos exLernos que se procesan
parclalmenLe en oLros conLexLos o a camblos en los parmeLros de conflguracln de la
apllcacln.
Aunque no es obllgaLorlo, es una buena prcLlca deflnlr una operacln esLLlca
asoclada al servlclo para cada uno de los punLos de enLrada al mlsmo, de forma que
sea en ese procedlmlenLo en el que se compruebe sl esLe se encuenLra o no en
e[ecucln y se proceda a su creacln o acLlvacln, segun el caso.
publlc sLaLlc synchronlzed vold screenlsCff(ConLexL conLexL) [ boolean ls_runnlng =
ls8unnlng(), lnLenL lnLenL = ls_runnlng ? new lnLenL() : new lnLenL(conLexL,
ScreenSLaLeServlce.class), lnLenL.seLAcLlon(ln1L8nAL_AC1lCn_SC8LLn_Cll), lf
(ls_runnlng) conLexL.send8roadcasL(lnLenL), else conLexL.sLarLServlce(lnLenL), }
Ln el e[emplo anLerlor, el 8tooJcostkecelvet asoclado al servlclo capLura los evenLos
de Llpo lN1kNAl_Ac1lON_5ckN_Oll, lo que provoca la e[ecucln de la lnsLancla
del servlclo, mlenLras que sl el servlclo no exlsLe se procede a crearlo medlanLe el
procedlmlenLo stott5etvlce.
nLese que el procedlmlenLo scteeolsOff se deflne como stotlc, lo que permlLe que sea
e[ecuLado fuera del conLexLo de un servlclo, y como syocbtoolzeJ, lo que lmplde que
oLro 1bteoJ e[ecuLe cualquler oLro procedlmlenLo de la clase marcado como
syocbtoolzeJ hasLa que la e[ecucln de esLe acabe, lo que garanLlza acceso excluslvo a
la clase mlenLras el servlclo se crea.


46
r|mera act|vac|n de un serv|c|o tras su |nstanc|ac|n
Al lnsLanclar un servlclo, y [usLo despues de acLlvarse el evenLo oocteote, se produce la
acLlvacln del evenLo oo5tottcommooJ, que reclbe como parmeLro un loteot que
puede procesarse usando el 8tooJcostkecelvet que asoclemos al servlclo.
publlc lnL onSLarLCommand(lnLenL lnLenL, lnL flags, lnL sLarL_ld) [
l8roadcasL8ecelver.on8ecelve(Lhls, lnLenL), reLurn super.onSLarLCommand(lnLenL,
flags, sLarL_ld), }
? hasLa aqul las caracLerlsLlcas prlnclpales de los servlclos, que podrs ver en deta||e
en nuestro programa de e[emp|o, que hemos adapLado para que el replnLado del
wldgeL se asocle a uno, lo que en condlclones reales permlLlrla e[ecuLar
procedlmlenLos y clculos comple[os ya que, como recordars, e| t|empo de proceso
mx|mo asoc|ado a |os eventos de| s|stema es de c|nco segundos.

47
CAI1ULC 10
Cbtener perm|so de superusuar|o (root)

Ln el curso Androld que acabamos en esLe caplLulo hemos expllcado las esLrucLuras
bslcas que os permlLlrn lmplemenLar vuesLras apllcaclones, pasando por las
acLlvldades y los Lhreads, y sln olvldar los servlclos, los permlsos y el paso de mensa[es
enLre apllcaclones.
Ln esLe bloque, y pese a que probablemenLe no os ser de uLllldad ms que en unos
pocos casos, queremos expllcaros cmo consegulr prlvlleglos de admlnlsLrador en
vuesLras apllcaclones, lo que os permlLlr desarrollar apllcaclones que se e[ecuLen sln
las resLrlcclones lmpuesLas por el slsLema.
Como hemos lndlcado en muchas ocaslones en nuesLros posLs de lndole general,
Andro|d es un s|stema estructurado en capas, cada una de |as cua|es |nteracc|ona con
|as capas super|or e |nfer|or e |ncorpora un n|ve| de abstracc|n d|ferente.
Ln concreLo, |as ap||cac|ones se e[ecutan sobre Da|v|k, |a mqu|na v|rtua| que
|ncorpora Andro|d y que se encarga de la e[ecucln de las apllcaclones, lncluyendo
LanLo las que perLenecen al slsLema como al usuarlo, y delegando en el slsLema la
gesLln de procesos y memorla.
Da|v|k e[ecuta |as ap||cac|ones en e| contexto de| usuar|o a| que pertenecen, que se
crea en el momenLo en que esLas se lnsLalan y esLo no puede camblarse, |o que
|mpos|b|||ta |a |nc|us|n de cd|go pr|v||eg|ado d|rectamente en |as ap||cac|ones y
ob||ga a |a creac|n de un proceso separado, como veremos ms adelanLe.


48
Cmo func|ona e| root
La adqulslcln del rooL en Lermlnales Androld es realmenLe lngenlosa, y se dlvlde en
dos parLes claramenLe dlferencladas.
or un |ado un programa que pertenece a| usuar|o root y que t|ene act|vo e|
b|t SUID, lo cual permlLe que su e[ecucln se reallce usando el cdlgo de
usuarlo al que perLenece el programa (rooL en esLe caso) y no el cdlgo de
usuarlo que reallza la llamada (el aslgnado a nuesLra apllcacln), y que lo unlco
que hace es e[ecuLar el programa que reclbe como parmeLro, hablLualmenLe
un shell, una vez comprobado que el usuarlo ha decldldo permlLlrlo,
or otro |ado una ap||cac|n, con |nterfaz grf|ca, y que no d|spone de n|ngn
pr|v||eg|o espec|a|, que se encarga de mosLrar un dllogo al usuarlo cada vez
que una apllcacln desea obLener prlvlleglos de superusuarlo y que slmpllflca la
gesLln de dlchos permlsos, la vlsuallzacln de logs, eLc.
Ap||cac|ones como SuperUser y SuperSU |mp|ementan esta |nterfaz grf|ca, Lodo y
que, ba[o deLermlnadas slLuaclones, son capaces de acLuallzar y/o descargar Lamblen
el archlvo blnarlo asoclado.
Cbtenc|n de| root en una ap||cac|n
Como hemos lndlcado anLerlormenLe, |a obtenc|n de |os perm|sos de superusuar|o
no puede hacerse en e| contexto de| proceso que se est e[ecutando, slno que
deberemos e[ecuLar un proceso exLerno, que ser el que e[ecuLe el cdlgo prlvlleglado
y del que deberemos capLurar la sallda para comprobar sl la e[ecucln ha sldo correcLa
o no.
ese a que podemos e[ecuLar un comando cada vez, |o ms hab|tua| es que e|
comando que se e[ecute sea una she||, |o que perm|t|r |a e[ecuc|n de var|os
comandos de forma secuenc|a|, pudlendo capLurar la sallda de cada uno de ellos de
forma separada.
LsLa forma de acLuar permlLe, adems, que |a so||c|tud de |os perm|sos de
superusuar|o (por medlo de la apllcacln SuperUser o SuperSU) se rea||ce una unlca
vez, cuando se |n|c|a e| she||, y no cada vez que se e[ecuLa un comando.
lrocess = 8unLlme.geL8unLlme().exec(su -c sh"),
Capturando |a sa||da de| proceso pr|v||eg|ado
1odo proceso Un|x estndar d|spone de dos cana|es por |os que expu|sa e| resu|tado
de |as operac|ones que e[ecuta: e| cana| de sa||da, que es aquel en el que se lmprlmen
el resulLado de las operaclones prlnL, wrlLe y, en general, aquellas funclones y
procedlmlenLos que lmprlmen resulLados y, e| cana| de errores, en el que se escrlben
los cdlgos y mensa[es de error y adverLenclas.

49
Ad|c|ona|mente, es necesarlo abrlr un canal que permlLa envlar los comandos al
proceso prlvlleglado que acabamos de crear, y que en unlx se conoce como cana| de
entrada de| proceso.
luaLaCuLpuLSLream = new uaLaCuLpuLSLream(lrocess.geLCuLpuLSLream()),
luaLalnpuLSLream = new uaLalnpuLSLream(lrocess.geLlnpuLSLream()),
luaLaLrrorSLream = new uaLalnpuLSLream(lrocess.geLLrrorSLream()),
Lnv|ando comandos a| proceso pr|v||eg|ado
una vez ablerLo el canal de enLrada esLndar del proceso prlvlleglado, la e[ecucln de
comandos se reallza cada vez que envlamos una llnea de LexLo por dlcho canal.
publlc boolean execuLe(SLrlng command) [ luaLaCuLpuLSLream.wrlLe8yLes(command
n"), luaLaCuLpuLSLream.flush(), }
kec|b|endo resu|tados de| proceso pr|v||eg|ado
uel mlsmo modo, la recepcln de resulLados se reallza leyendo de los canales de sallda
y errores, Lal como se muesLra ms aba[o.
publlc LlsL geLSLandardCuLpuL() [ LlsL resulLs = new ArrayLlsL(), SLrlng llne, whlle
(Lrue) [ llne = luaLalnpuLSLream.readllne(), lf (llne == null) break,
resulLs.add(llne), } reLurn resulLs, } publlc LlsL geLSLandardLrrorsCuLpuL() [ LlsL
resulLs = new ArrayLlsL(), SLrlng llne, whlle (Lrue) [ llne =
luaLaLrrorSLream.readllne(), lf (llne == null) break, resulLs.add(llne), } reLurn
resulLs, }
Comprobac|n de |os perm|sos
Ll meLodo ms senclllo para comprobar sl la obLencln de los permlsos de
superusuarlo ha sldo exlLosa es la e[ecucln del comando lJ, que nos proporclonar
lnformacln sobre el usuarlo que esL e[ecuLando la apllcacln y que deberla ser 0 en
caso aflrmaLlvo.
execuLe(ld"), LlsL ouLpuL = geLSLandardCuLpuL(), lf ((ouLpuL == null) ||
(ouLpuL.lsLmpLy())) Lhrow new LxcepLlon("CanL geL rooL access or denled by user"),
lf ( ouLpuL.LoSLrlng().conLalns("uld=0")) Lhrow new LxcepLlon("8ooL access re[ecLed
by user or devlce lsnL rooLed"),
Acabar |a ses|n
una vez que se han e[ecuLado Lodos los comandos necesarlos, ser convenlenLe
flnallzar la sesln de shell, medlanLe la e[ecucln del comando exlt, que provocar la
flnallzacln del proceso asoclado y el clerre de los canales de comunlcaclones
asoclados al mlsmo.

30

Con esLo damos por flnallzado nuesLro curso Androld, no sln anLes agradeceros
vuesLra aLencln y anlmaros a descargaros |a |t|ma vers|n de| m|smo, que lncluye el
cdlgo compleLo necesarlo para consegulr permlsos de superusuarlo en vuesLras
apllcaclones.

31


Ll CUkSC DL kCGkAMACICN LN ANDkCID AkA kINCIIAN1LS ha sldo
desarrollado por 8oberL . para IaqsAndro|d.com del Grupo bemoob.



LsLe obra esL ba[o una L|cenc|a Creat|ve Commons Atr|buc|n-NoComerc|a|-
S|nDer|vadas 3.0 Unported.

by

También podría gustarte