7/23/2019 Consumir Un Servicio Web REST Desde Android http://slidepdf.com/reader/full/consumir-un-servicio-web-rest-desde-android 1/113 Consumir Un Servicio Web REST Desde Android diciembre 28, 2015 James Revelo En este artículo te mostraré como consumir un servicio web RESTful basado en el artículo asado ! "a idea es mostrar con un e#emlo en $ndroid Studio, una sincroni%aci&n comleta ara una a $ndroid de contactos! "o rimero 'ue (aremos ser) definir el alcance de la alicaci&n $ndroid, ara determinar el uso de sus funciones! "ue*o estableceremos unos re'uerimientos (iotéticos necesarios ara mane#ar el +R- del servicio web! También te mostraré un dise.o de la base de datos / la forma en 'ue la imlementé en /s'l ara 'ue la sincroni%aci&n sea efectiva! $dem)s esbo%aré los elementos visuales de la a a través de un dia*rama con wireframin*! inalmente veremos c&mo crear la alicaci&n comleta en $ndroid Studio ara llevar a cabo oeraciones locales / remotas sobre las bases de datos en S"ite / /s'l! $ continuaci&n te muestro el resultado final de la alicaci&n “PeopleApp”! Recuerda 'ue uedes descar*ar el ro/ecto comleto en $ndroid Studio comartiendo este artículo con tu red social favorita! -ES+$R3$R +4-36 Desarrollar Aplicación Android De Contactos +omo /a sabes, la alicaci&n $ndroid mane#ar) un +R- de contactos ersonales ara los usuarios 'ue usen la a! 7o ser) una a corta, or lo 'ue i*noraré en el desarrollo la creaci&n de la versi&n ara tabletas o ara la osici&n landscae, con el fin de reducir el artículo a un material comresible! El lo*in de la a no lo tocaremos en este artículo, ero de se*uro ser) el r&imo un r&imo tema ara el blo*!
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
7/23/2019 Consumir Un Servicio Web REST Desde Android
En este artículo te mostraré como consumir un servicio web RESTful basado en el artículo asado! "a idea es mostrar con un e#emloen $ndroid Studio, una sincroni%aci&n comleta ara una a $ndroid de contactos!
"o rimero 'ue (aremos ser) definir el alcance de la alicaci&n $ndroid, ara determinar el uso de sus funciones! "ue*oestableceremos unos re'uerimientos (iotéticos necesarios ara mane#ar el +R- del servicio web!
También te mostraré un dise.o de la base de datos / la forma en 'ue la imlementé en /s'l ara 'ue la sincroni%aci&n sea efectiva!
$dem)s esbo%aré los elementos visuales de la a a través de un dia*rama con wireframin*!inalmente veremos c&mo crear la alicaci&n comleta en $ndroid Studio ara llevar a cabo oeraciones locales / remotas sobre las bases de datos en S"ite / /s'l!
$ continuaci&n te muestro el resultado final de la alicaci&n “PeopleApp”! Recuerda 'ue uedes descar*ar el ro/ecto comleto en$ndroid Studio comartiendo este artículo con tu red social favorita!
-ES+$R3$R +4-36
Desarrollar Aplicación Android De Contactos
+omo /a sabes, la alicaci&n $ndroid mane#ar) un +R- de contactos ersonales ara los usuarios 'ue usen la a! 7o ser) una acorta, or lo 'ue i*noraré en el desarrollo la creaci&n de la versi&n ara tabletas o ara la osici&n landscae, con el fin de reducir elartículo a un material comresible!
El lo*in de la a no lo tocaremos en este artículo, ero de se*uro ser) el r&imo un r&imo tema ara el blo*!
"as características de la a /a las (abía mencionado arriba de forma *eneral, sin embar*o anotarlas nos vendría bien!
"a a de contactos debe tener las si*uientes eticiones del usuario (iotético9
• Como Usuario hipotético, deseo guardar el primer nombre, primer apellido, teléfono y correo de mis contactos personales y
verlos en una lista.
• Como Usuario hipotético, deseo modificar los datos de un contacto existente.
• Como Usuario hipotético, deseo eliminar contactos.
• Como Usuario hipotético, quiero que los cambios que haga en mi app Android se vean reflejados en mi cuenta web y
viceversa.
"os tres rimeros re'uerimientos odríamos a*ruarlos en “Administrar los contactos”, sin embar*o or racticidad / orden refiero'ue los entiendas de esa forma!
Selección de estrateia para sincroni$ación
Es etremadamente imortante 'ue en esta secci&n aclares la estrateia de sincroni$ación 'ue usar)s en tu alicaci&n! na de la
forma m)s sencilla de (acerlo es esecificando 'ue arte ser) la m)s reonderante a la (ora de relicar la informaci&n!
En mi caso tanto el servidor como el cliente tendr)n el mismo eso! "o 'ue 'uiere decir, 'ue los re*istros locales / remotos debenconservarse en las mismas condiciones! Sum)ndole 'ue el roceso de sincroni%aci&n ser) or demanda!
Su&n 'ue la alicaci&n $ndroid no osee nin*?n contacto or el momento! -el otro lado tenemos al servidor <( con un contacto /acreado desde la alicaci&n web!
" #$ué pasar%a si se iniciara una sincroni&aci'n en ese preciso instante seg(n lo que mencioné)
El re*istro del cliente se coiaría en la base de datos S"ite de la alicaci&n $ndroid!
@ Ahora, #$ué suceder%a en caso contrario)
Es decir, 'ue el cliente ten*a un contacto local creado, ero 'ue el servidor a?n no osea re*istros!
Respuesta% el re*istro se coiaría en la base de datos /s'l, /a 'ue el re*istro es tratado como rioritario!
Este comortamiento se uede resumir en la si*uiente ilustraci&n9
7/23/2019 Consumir Un Servicio Web REST Desde Android
+uando se trata de las oeraciones sencillas de forma aislada no eisten roblemas, ero las cosas se onen comle#as cuando unmismo re*istro es editado tanto en el cliente como en el servidor antes de la sincroni%aci&n!
Este tio de conflictos ueden ser solucionados de muc(as formas osibles, ero or suuesto todo deende!<ara <eole$ decidí usar una estrateia de marcas de tiempo ×tamps' ara comarar las fec(as de modificaci&n / ele*ir alm)s reciente!
*jemplo!
El contacto C( fue editado desde el cliente el +-+-+/ a las /pm! "ue*o se edit& en el servidor ese mismo día a las 0pm! $ las 1pm se reali%& una sincroni%aci&n entre ambas artes!
" #$ué versi'n crees que sobrevivi')
"a del servidor! 6bviamente or'ue es el dato m)s reciente como lo (abía mencionado! $sí 'ue se reali%a una rélica en el re*istrolocal!
)*s estrateias de sincroni$ación
+ada a es distinta, en consecuencia no todas las estrate*ias ser)n las correctas ara tu caso articular!
n buen caso sería en donde tu aplicación Android actua como un receptor de las +ltimas noticias de tu ,eb! Si me re*untas 'ue
arte es m)s reonderante, /o diría 'ue el servidor! Aa 'ue el ori*en de los datos est) basado en tu web, or lo 'ue la a m&vil nocontribu/e en nada a la creaci&n de contenido!
$'uí el servidor sería maestro / el cliente un esclavo! -onde sí los re*istros son borrados del servidor, el cliente también tendr) 'uerelicar estas eliminaciones!
-e la misma forma uede ocurrir 'ue la alicaci&n $ndroid sea el lado maestro / el servidor el esclavo! -onde todo cambio en la atendría ma/or eso 'ue el servidor!
$dicionalmente, en la resoluci&n de conflictos odríamos ele*ir la versi&n m)s anti*ua en ve% de la actual! 6 incluso ele*ir la versi&ndel cliente o servidor se*?n la conveniencia!
$un'ue también eiste la alternativa de roorcionar un control de versiones del re*istro ara 'ue el usuario eli#a el cambio 'ue m)s leconviene!
<iénsatelo mu/ bien / act?a se*?n las olíticas ara rote*er los datos del usuario!
#-! Crear Wire.ramin De /a App
eopleApp es una alicaci&n +R- realmente sencilla / no re'uiere muc(o esfuer%o maear las relaciones de las antallas!
-e los re'uerimientos sabemos 'ue la lista de antallas 'ue tendremos se comone de9
• "ista de contactos
• ormulario de creaci&n de contactos
• ormulario ara edici&n de contactos
Esto reduce nuestra laneaci&n de al si*uiente wireframin*9
7/23/2019 Consumir Un Servicio Web REST Desde Android
El si*uiente movimiento es a*re*ar el soorte de versiones ara los re*istros de la tabla 'contacto'!
Esto si*nifica a.adir una nueva columna llamada 3version4 del tio DATETIME! Si en tu caso necesitas la recisi&n de centésimos dese*undo, entonces usa el tio TIMESTAMP!
$l crear este camo le a.adí el activador ON UPDATE CURRENT_TIMESTAMP ara 'ue /s'l actualice autom)ticamente la fec(a! Estome evita crear un tri**er ara asi*nar la fec(a actual!
En c&di*o, la eortaci&n de /s'l me arro#a al si*uiente comando CREATE 9
--
-- Estructura de tabla para la tabla `contacto`--
CREATE TA!E I" NOT E#ISTS `contacto` $ `%dContacto` &arcar$())* NOT NU!!+ `pr%,erNo,bre` &arcar$.* NOT NU!!+ `pr%,erApell%do` &arcar$.* DE"AU!T NU!!+ `tele/ono` &arcar$0.* DE"AU!T NU!!+ `correo` &arcar$()* DE"AU!T NU!!+ `%dUsuar%o` %nt$00* NOT NU!!+ `&ers%on` datet%,e NOT NU!! DE"AU!T CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP* EN1INE2InnoD DE"AU!T C3ARSET2lat%n04
Si deseas reali%arlo a través de php2yAdmin, entonces solo vas a la esta.a “Estructura” / lue*o resionas “Continuar” en lasecci&n de “Arear”!
7/23/2019 Consumir Un Servicio Web REST Desde Android
#5! Crear 6peraciones En 1atc7 Para El Servicio REST
-e la forma en 'ue ten*o el servicio web REST (asta el momento tendría 'ue enviar *ran cantidad de eticiones ara insertar,
modificar / eliminar contactos!
<onte a ensar! Si tuviésemos 100 contactos a.adidos en la alicaci&n $ndroid, entonces re'ueriré 100 eticiones <6ST (acia elservidor ara relicar la informaci&n!
$un'ue arece 'ue no (a/ roblema, en realidad los disositivos m&viles consumen batería or cada ciclo de envío de eticionesBTT<! +on unas cuantas no (abr) roblema, ero si necesitamos actuali%ar un *ran n?mero de re*istros, entonces debes ens)rtelo dosveces!
<ara solucionar este inconveniente imlementaré oeraciones batc( en el servicio web! Estas no son mas 'ue oeraciones 'ue se
reali%an en blo'ue o lotes de datos ara otimi%ar tratar una sola car*a de datos!
Esto te ermitir) reali%ar las tres oeraciones b)sicas con una sola etici&n de uno o m)s recursos, es decir, insertar, actuali%ar /eliminar con una solo método!
Aplicar batc7 en )2s"l a trav8s de P7p
<ara formar la R 'ue controle el batc( crearé un nuevo arc(ivo llamado s2nc!p7p dentro del directorio controladores!
Su ob#etivo es comortarse como un recurso 'ue reresente a todos los recursos eistentes de la base de datos! $sí 'ue loconsultaremos ara enviarle una etici&n con los cambios me%clados u obtener datos!
"a referencia de acciones 'uedaría de la si*uiente forma9
UR9 Descripción
1ET ap%6peopleapp6co,7&07s8nc 6btiene todos los re*istros de la tabla contactosPOST ap%6peopleapp6co,7&07s8nc Envía las inserciones, modificaciones / eliminaciones de re*istros de contactos!
Este recurso adicional mostraría un *ran otencial si tuviésemos m)s de dos tablas! Sin embar*o, con el e#emlo de contactos /atendr)s una l&*ica ara eandir tus as!
6btención de datos en 1atc7
a'! "o rimero 'ue (aré ser) a*re*ar el recurso s2nc a la lista de recursos en el arc(ivo inde:!p7p! Recuerda 'ue esto ermitereconocer las oeraciones!
b'! -ebido a 'ue enviaremos los datos de todas las tablas Cmenos 3usuario4 /a 'ue no necesita sincroni%aci&nD, entonces crearé unalista con los nombres de cada una!
El ro&sito es la lectura con un ciclo /oreac de todos sus elementos ara construir un ob#eto JS67 con los datos de cada una!
sync.php
7/23/2019 Consumir Un Servicio Web REST Desde Android
7? A@ade todas los recursos ;ue deseas en&%ar separados por co,a '+' ? ee,ploB arra8$'cl%ente'+ '/actura'+ 'producto'* ?7 publ%c stat%c <tablas 2 arra8$contactosBBTA!A_CONTACTO*4
c'! $(ora escribiré el método *eneral et$* ara rocesar la etici&n 1ET enviada desde el cliente! En esencia, solo debes autori%ar elusuario / lue*o comen%ar a etraer todos los datos!
"a autori%aci&n /a la (abías visto en el artículo anterior con el método autor%ar$*! <ara la consulta a la base de datos usaré unnuevo método llamado obtenerRecursos$*, el cual recibe el filtro de la etici&n / el id del usuario!
d'! El método obtenerRecursos$* debe recorrer el arra/ tablas ara consultar todo el contenido de cada una! $ medida 'ue se vanencontrando los re*istros, se van a.adiendo a un arra/ de resuesta, donde la clave de cada tabla ser) su mismo nombre!
+omo ves, (a/ solo un arra/ llamado 3contacto4 con un re*istro de e#emlo! Si (ubiésen mas tablas, entonces aarecerían de la mismaforma con sus resectivos contenidos, ara 'ue los roceses desde la a $ndroid!
Actuali$ación De Datos En 1atc7
Esta tarea es un oco m)s comle#a debido a 'ue /a no enviar)s eticiones individuales or cada oeraci&n, si no 'ue usar)s un solocanal ara todo!
#$ué debes tener en cuenta)
• El método BTT< a usar ara la etici&n batc(!
• "a cantidad de tablas 'ue contribuir)n a la actuali%aci&n masiva!
• El tio de oeraciones 'ue enviar)s or cada tabla!
• "a estructura JS67 o F" del cuero de la etici&n
7/23/2019 Consumir Un Servicio Web REST Desde Android
+uando evalué estas características decidí lo si*uiente9
• El método a usar ser) POST, /a 'ue ermite enviar un cuero en la etici&n de forma fleible / multivariada!
• "a ?nica tabla 'ue (a/ ara sincroni%ar es contacto!
• Enviaré las inserciones, modificaciones / eliminaciones!
• saré un ob#eto JS67 con G arre*los 'ue reresenten las oeraciones mencionadas arriba! $l*o como9
• >
• 5%nserc%ones5BJ
• 66
• K+
• 5,od%/%cac%ones5BJ
• 66
• K+
• 5el%,%nac%ones5BJ
• 66
• K
Eisten muc(as maneras de reali%ar un batc( en una etici&n, / de se*uro ver)s unas mu/ in*eniosas 'ue usan los ar)metros de lasR"s o incluso las cabeceras BTT<! ncluso la combinaci&n de varias eticiones BTT< en una sola!
<ero como siemre di*o, las r)cticas variar)n se*?n tus necesidades / estilo de ro*ramaci&n!
Heamos como formar el scrit <(!
a'! En rimer lu*ar crea un método llamado post$* ara tratar la etici&n! $(ora iensa un oco en el al*oritmo a se*uir ara traducirla a/load!
7/23/2019 Consumir Un Servicio Web REST Desde Android
1! $utori%ar el usuario2! Etraer el cuero JS67 del contenido de la etici&n <6STG! -ecodificar el ob#eto en un arra/ asociativoI! $licar oeraciones en batc( descritas en el arra/
+omo ves, lo ?nico 'ue no (e elicado antes es reali%ar las oeraciones en batc(, ero las rimeras acciones /a sabes alicarlas! El batc( lo imlementaremos en un método or searada llamado apl%caratc$*, el cual recibe el mensa#e decodificado / el id delusuario!
b'! El método apl%caratc$* abre una transacci&n de bases de datos ara comen%ar a alicar inserciones, modificaciones /eliminaciones de los contactos! na ve% todo se (a llevado a cambio, la transacci&n termina / se confirman los cambios remotos!
"a alicaci&n de cada oeraci&n se lleva a cabo con unos nuevos métodos de la clase contactos 'ue veremos en el si*uiente aso9
catc $PDOE=cept%on <e* > tro ne E=cepc%onAp%$<pdo-FerrorCode$*+ <e-FetMessae$*+ ((*4
6bserva 'ue /o comien%o a llamar los ob#etos '%nserc%ones', ',od%/%cac%ones' e '%nserc%ones' directamente desde pa8load!Esto lo (a*o or'ue ten*o solo la tabla contactos! <ero si (a/ m)s de una, debes crear un ciclo /or o /oreac ara rocesar la lista detablas!
-onde el cuero de la etici&n vendría con la si*uiente sintais9
> 5tabla05B> 5%nserc%ones5BJ
K+ 5,od%/%cac%ones5BJ
K+ 5el%,%nac%ones5BJ
K + 5tabla(5B> 5%nserc%ones5BJ
K+ 5,od%/%cac%ones5BJ
K+ 5el%,%nac%ones5BJ
K + 666+ 5tablan5B>
7/23/2019 Consumir Un Servicio Web REST Desde Android
+ada recurso a tratar en batc( debe tener sus resectivos métodos %nsertarEnatc$*, ,od%/%carEnatc$* /el%,%narEnatc$*! $sí odr)s *enerali%ar la llamada de los métodos dentro del /or, ara evitar (acer referencia a cada nombredentro del ciclo!
c'! El si*uiente aso es escribir el método %nsertarEnatc$* en contactos!p7p! Este tio de métodos se caracteri%a or usar un bucle ara rocesar cada comando de la base de datos! En este caso la sentencia INSERT en /s'l!
"a idea es leer todos los elementos del arra/ '%nserc%ones' / e#ecutar una sentencia rearada con los datos de cada ítem!
"as inserciones de contactos tienen la si*uiente forma en el cuero JS679
En cada iteraci&n del ciclo 'ue rocesa las inserciones maearemos la sentencia S" con los nombres 'ue vemos en el re*istro dee#emlo anterior de la si*uiente forma9
e'! En cuanto a las eliminaciones el asunto es muc(o m)s sencillo! Solo recibir)s los identificadores de a'uellos contactos a eliminar, or lo 'ue tendremos un arre*lo sencillo de strin*s como el si*uiente9
5el%,%nac%ones5BJ 5C-)bX.dc-X..-Q.-Qb-Q(d0QcaX5+
7/23/2019 Consumir Un Servicio Web REST Desde Android
Esto solo nos de#a iterar sobre una sentencia rearada basada en un DE!ETE con dos lace(olders! no ara el identificador delcontacto / otro ara el del usuario!
77 Preparar sentenc%a en el contenedor <sentenc%a 2 <pdo-Fprepare$<co,ando*4
77 Procesar todas las %ds /oreac $<arra8Ids as <%d* > <sentenc%a-Fe=ecute$arra8$<%d+ <%dUsuar%o**4
+on todas las modificaciones anteriores el servicio web REST 'ueda rearado ara obtener todos los datos a sincroni%ar / aramodificar con un solo envi&n!
$(ora solo 'ueda crear la a $ndroid ara robar estas características!
#;! Desarollo De /a Aplicación Android
;! Crear nuevo pro2ecto en Android Studio
7/23/2019 Consumir Un Servicio Web REST Desde Android
Paso #! $bre $ndroid Studio, ve a <ile =e, =e, Pro>ect? / así*nale el nombre de 4eopleApp5! +onfirma las características /al final a.ade una actividad en blanco C1lan@ Activit2D ara tener un avance de la lista de contactos!
7/23/2019 Consumir Un Servicio Web REST Desde Android
Paso #-! Eli*e los es'uemas de colores ara el aterial -esi*n! En el wireframin* vimos 'ue tendremos como aleta rincial con unde*radado de a%ul / una aleta secundaria con rosa ara los acentos!
<ara obtener estos colores 'uiero mostrarte una utilidad web 'ue me (a arecido s?er interesante! Su nombre es aterial -esi*n+olors! Esta (erramienta te ermite ele*ir los de*radados de los colores 'ue deseas usar en tu a! ncluso te de#a ver la revisuali%aci&n de sus combinaciones!
9-- Cuenta S8nc Adapter --F 9str%n na,e25t%po_cuenta5Fco,6erprora,ac%on6peopleapp6cuenta97str%nF
9-- Autor%dad del pro&%der --F 9str%n na,e25autor%dad_pro&%der5Fco,6erprora,ac%on6peopleapp97str%nF
97resourcesF
$l inicio tenemos el nombre de todas las antallas 'ue usaremos ara tratar los contactos! "ue*o los tetos emer*entes ara lasacciones de la toolbar!
$l final del arc(ivo también tenemos el tio de cuenta 'ue usaremos en el s/nc adater ara la sincroni%aci&n / la autoridad delcontent rovider!
Paso #5! $*re*a los colores al tema central! $(ora es turno de modificar los estilos 'ue $ndroid Studio nos (a creado or defecto! Eneste caso asi*naremos los colores 'ue creamos en el tema base de la si*uiente forma9
Paso #;! $*re*a todas las librerías necesarias ara la interfa%, las coneiones de Red / arsin* JS67! "a confi*uraci&n arcial del ro/ecto la termino a.adiendo al arc(ivo build!radle las librerías necesarias ara desarrollar la a!
Entre estas tenemos la librería de dise.o ara usar .abs buttons, snac@ bars, app bars, etc! También el rec2cler vie, ara la lista decontactos! "a versi&n no oficial de volle2 ara eticiones BTT< / Bson ara el arsin* JS67!
"a creaci&n de la lista de contactos imlica varios comonentes 'ue relacionan la vista con el modelo de datos / a su ve% entre*an elmane#o al usuario!
<ara simlificar las tareas de desarrollo 'ue reali%aré a.adiré el si*uiente dia*rama con los elementos 'ue necesitaré! "os comonentesdel tono amarillo ertenecen al modelo, los de tono naran#a a la vista / los de tono ro#o nos roorcionan controladores de eventos9
7/23/2019 Consumir Un Servicio Web REST Desde Android
+omo ves, detr)s del refle#o de la lista se encuentran una *ran cantidad de comonentes 'ue soortan su funcionamiento! El lado bueno es 'ue cada uno de estos /a los (emos estudiado en varios de los artículos asados, así 'ue no (a/ nada de 'ué reocuarse!
Teniendo en cuenta esta ar'uitectura, comen%aremos or desarrollar los comonentes del modelo!
Paso #! +rea el contrato ara la base de datos! $.ade una nueva clase Java llamada +ontrato / a.ade el si*uiente c&di*o9
En rimera instancia tenemos dos interfaces con los nombres de las columnas 'ue eistir)n en la tabla contacto!Colu,nasS%ncron%ac%on contiene tres banderas ara determinar si los re*istros locales (an sido insertados, modificados oeliminados! -onde el valor 0 determina el al%a de la bandera / . la ausencia de cambio!
$ su ve% defino la autoridad del content rovider con mi a'uete #ava / de una ve% la uri de contenido *eneral!
$l final tendremos una clase controladora ara el recurso “contactos”! Su ob#etivo es roorcionar informaci&n sobre la uri de
contenido, los tios mime / la construcci&n de uris ara soortar identificadores!
$dicionalmente tiene un método llamado enerarIdContacto$*, el cual se encar*a de crear una nueva id ara los nuevos contactoslocales, basada en la sintais 3C(UU9D4! -onde - es un identificador ?nico de 1L b/tes obtenido con la clase UUID!
2uestra6 4C7/8fbab17fe078edf790a87e/ff/0faf5
Si est)s erdido en este unto, entonces te recomiendo leer mi artículo ara crear un content rovider ersonali%ado!
Paso #-! +rea la clase auiliar ara el acceso a bases de datos! En este aso debes crear una nueva clase 'ue etienda deS\!%teOpen3elper / sobrescribir los controladores onCreate$* / onUprade$* ara determinar las acciones al crear la base de datos/ al actuali%ar su versi&n!
HelperContactos.java
publ%c class 3elperContactos e=tends S\!%teOpen3elper >
catc $S\!%teE=cept%on e* > 77 Maneo de e=cepc%ones onCreate$db*4
Recuerda incluir siemre la columna 5_%d5 manualmente o su e'uivalente en aseColu,ns6_ID! El frameworM de $ndroid lo necesitaen varios comonentes ara un correcto funcionamiento!
Es imortante 'ue a.adas un índice UNI\UE a la columna %dContacto ara establecer restricciones de unicidad entre los contactos con
base a la base de datos /s'l!
En cuanto a las columnas de sincroni%aci&n, declara valores or defecto con DE"AU!T ara de#arlas inactivas al crear un nuevo re*istro!5%nsertado5 uedes de#arla levantada or defecto, /a 'ue una inserci&n local rovoca este estado! Sin embar*o, cuando la inserci&nven*a or roducto de la sincroni%aci&n, cambia el valor a . en la sentencia INSERT!
Si tienes dudas sobre la creaci&n de bases de datos S"ite, entonces lee mi artículo Tutorial -e ;ases -e -atos S"ite En $ndroid!
Paso #0! +rea un +ontent <rovider ersonali%ado ara oerar los datos a través de Rs!
<ara la tabla contactos tenemos dos formas de R a la cual referimos deendiendo si nos referimos a todos los re*istros Ccolecci&nD oa un contacto esecífico CrecursoD!
<ara diferenciar estas dos estructuras recuerda 'ue la clase Ur%Matcer rovee la asociaci&n de c&di*os ?nicos con atrones de uris!$sí 'ue si te basas en este comonente, la sobrescritura de los métodos ;uer8$*, %nsert$*, update$*, delete$*, bulZInsert$* oappl8atc$*!
Teniendo en cuenta estas recomendaciones, /a uedes crear el content rovider!
na de las formas de (acerlo es a través de la lantilla de $ndroid Studio al resionar clicM derec(o en el a'uete / ele*ir =e, 6t7er Content Provider! +on ello no tendr)s 'ue a.adir la declaraci&n del comonente en el Android)ani.est!:ml!
7/23/2019 Consumir Un Servicio Web REST Desde Android
de/aultB tro ne IllealAru,entE=cept%on$5T%po desconoc%doB 5 [ ur%*4
O&err%de publ%c Cursor ;uer8$Ur% ur%+ Str%nJK proect%on+ Str%n select%on+ Str%nJK select%onArs+ Str%n sortOrder* > 77 Obtener base de datos S\!%teDatabase db 2 ,aneadorD6etr%tableDatabase$*4 77 Co,parar Ur% %nt ,atc 2 ur%Matcer6,atc$ur%*4
Cursor c4
s%tc $,atc* > case CONTACTOSB
77 Consultando todos los re%stros c 2 db6;uer8$Tablas6CONTACTO+ proect%on+ select%on+ select%onArs+ null+ null+ sortOrder*4 c6setNot%/%cat%onUr%$resol&er+ Contactos6URI_CONTENIDO*4 breaZ4 case CONTACTOS_IDB 77 Consultando un solo re%stro basado en el Id del Ur% Str%n %dContacto 2 Contactos6obtenerIdContacto$ur%*4 c 2 db6;uer8$Tablas6CONTACTO+ proect%on+ Contactos6ID_CONTACTO [ 525 [ 5^'5 [ %dContacto [ 5^'5 [ $Te=tUt%ls6%sE,pt8$select%on* :
5 AND $5 [ select%on [ '*' B 55*+ select%onArs+ null+ null+ sortOrder*4 c6setNot%/%cat%onUr%$resol&er+ ur%*4 breaZ4 de/aultB tro ne IllealAru,entE=cept%on$5URI no soportadaB 5 [ ur%*4 return c4
7/23/2019 Consumir Un Servicio Web REST Desde Android
"a eti'ueta 9%ncludeF la est) *enerando $ndroid Studio ara etraer el contenido rincial de la actividad en otro la/outcomlementario, 'ue ermite me#orar la visuali%aci&n / el orden!
El la/out *eneral lo de#aremos 'uieto! Solo modifica el icono del fab button con un icono de a.adir contacto! <ara descar*arlo uedesir a la (erramienta aterial -esi*n cons / resionar 9con Pac@ae Android ;!:!
Paso #;! $.adir adatador ersonali%ado con soorte de cursor! El rec/cler ser) oblado or los datos 'ue ten*amos en la tablacontacto, or ende es necesario usar un cursor al adatador 'ue creemos!
El adatador debes construirlo de la misma en 'ue (aces siemre, es decir, sobrescribiendo los métodos etIte,Count$*,
onCreateV%e3older$* / on%ndV%e3older$*! Solo 'ue esta ve% el contenido ser) una instancia tio +ursor, or lo 'ue debes usarlos métodos del cursor ara obtener los datos / li*arlos a la interfa%!
:eamos6
AdaptadorContactos.java
7?? ? Adaptador para la l%sta de contactos ?7publ%c class AdaptadorContactos e=tends Rec8clerV%e6Adapter9AdaptadorContactos6V%e3olderF >
pr%&ate Cursor %te,s4
77 Instanc%a de escuca pr%&ate OnIte,Cl%cZ!%stener escuca4
7?? ? Inter/a para escucar cl%cZs del rec8cler ?7 %nter/ace OnIte,Cl%cZ!%stener >
7/23/2019 Consumir Un Servicio Web REST Desde Android
• El método etIte,Count$* se basa en el resultado de s%e$* del cursor %te,s!
• -entro de on%ndV%e3older$* usamos ,o&eToPos%t%on$* en el cursor ara auntar al re*istro actual! "ue*o se obtiene elnombre / aellido del contacto Ccomo se vio en el wireframeD con el método de utilidad UConsultas6obtenerStr%n$*, araasi*narlo a cada ítem de la lista!
• saremos un método sapCursor$* ara intercambiar los datos del cursor actual con uno nuevo!
• Relacionaremos la columna '%dContacto' con la osici&n dentro del adatador con el método obtenerIdContacto$*! Estocon el fin de relacionar ambas valores de forma directa!
$(ora te re*untar)s, #c'mo funciona la escucha declarada dentro del recycler)
Sencillo! -ebido a 'ue el view (older reresenta cada fila en forma de view, entonces convertimos a este elemento en una escuc(a deltio V%e6OnCl%cZ!%stener!
"o si*uiente es crear una interfa% 'ue reresente al elemento 'ue escuc(ar) lo 'ue escuc(& el view (older de forma secuencial! Esta esla interfa% OnIte,Cl%cZ!%stener la cual tendr) an)lo*amente un controlador onCl%cZ$* 'ue recibe el view (older / a %dContacto!
+omo ves, el controlador OnCl%cZ!%stener6onCl%cZ$* en el view (older llama a su ve% al controladorOnIte,Cl%cZ!%stener6onCl%cZ$* con los valores actuales!
#; quién ser3 la escucha)
<=a actividad de contactos>
7/23/2019 Consumir Un Servicio Web REST Desde Android
Paso #! <reara la actividad de lista de contactos!
Ba/ varias cosas or (acer si 'ueremos mostrar nuestra lista oblada!
aD mlemente las interfaces !oaderCallbacZs / AdaptadorContactos6OnIte,Cl%cZ!%stener ! bD <reara la lista obteniendo el rec/cler / asi*nado un !%near!a8outManaer / el adatador!cD nicia un nuevo !oader / consulta todos los contactos en onCreate!oader$*! "ue*o usa el método sapCursor$* del adatador en
on!oad"%n%sed$* ara actuali%ar los datos!dD Escribe la declaraci&n del método onCl%cZ$* de la interfa% del adatador!eD 3uarda la clave de $< ara al*unos de los usuarios 'ue tienes en la base de datos en tu arc(ivo de referencias! "ue*o usaremos laclave ara enviar eticiones con :olley! Si descar*as el c&di*o comleto odr)s ver la clase UPre/erenc%as, donde ten*o un método refabricado ara *uardar / obtener esta clave!
"e/endo las tareas anteriores uedes comen%ar a editar tu actividad! 6 *uíate or el si*uiente c&di*o9
7/23/2019 Consumir Un Servicio Web REST Desde Android
7ota 'ue si la el icono de confirmaci&n en la toolbar es resionado, entonces se inicia una tarea asíncrona llamadaTareaA@ad%rContacto, dentro de la cual usaremos el comando ContentResol&er6%nsert$* ara a.adir los datos del formulario a latabla contacto! Esto evitar) alterar el (ilo rincial con la inserci&n!
+on este es'uema *lobal en la mente comen%aré a codificar los comonentes!
7/23/2019 Consumir Un Servicio Web REST Desde Android
+on estos movimientos /a disones de los elementos visuales 'ue activar)n la inserci&n!
Paso #-! odifica la actividad de inserci&n ara 'ue recolecte los datos asi*nados or el usuario en cada Ed%tTe=t! +ada uno de estosdeben ser a.adidos a un ContentValues 'ue se asar) a la tarea asíncrona, la cual usar) al content resolver ara insertar estos datos!
ActividadnsercionContacto.java
publ%c class Act%&%dadInserc%onContacto e=tends AppCo,patAct%&%t8>
<ara modificar un contacto ensé en reciclar la actividad de inserci&n, /a 'ue se re'uiere el mismo formulario, ero con los camos deteto reviamente car*ados!
-e esta forma a(orraría *ran cantidad de tiemo / c&di*o! Solo tendría 'ue recibir la uri del contacto / comen%ar una car*a de datos ara asi*narlos a cada edit tet! ncluso se uede usar la misma TareaInsertarContacto ara la modificaci&n!
En cuanto a la eliminaci&n, usaré un action button! $l momento de resionarlo se iniciar) una tarea asíncrona 'ue use el métodoContentResol&er6delete$* ara marcar el contacto como eliminado o eliminarlo definitivamente si a?n no (a sido sincroni%ado!
-é#ame ilustrarte con un dia*rama9
7/23/2019 Consumir Un Servicio Web REST Desde Android
Paso #! -irí*ete a Actividad/istaContactos!>ava e inicia la actividad Act%&%dadInserc%onContacto a través destartAct%&%t8$*! El intent 'ue lleve consi*o debe tener la uri del contacto seleccionado, la cual uedes construir con el métodoContactos6constru%rUr%Contacto$*!
7/23/2019 Consumir Un Servicio Web REST Desde Android
Paso #0! El si*uiente movimiento es actuali%ar la tarea asíncrona de inserci&n ara 'ue reciba una uri en su método e=ecute$*! +onesto odremos identificar dos casos osibles, donde el valor de null si*nifica 'ue (aremos una inserci&n C%nsert$*D / una urieistente indica actuali%ar el re*istro Cupdate$*D!
%/ $null 2 ur%* > 7? Ver%/%cac%nB S% el contacto ;ue se &a a actual%ar an no a s%do s%ncron%ado+ es dec%r su colu,na '%nsertado' 2 0+ entonces la colu,na ',od%/%cado' no debe ser alterada
?7 Cursor c 2 resol&er6;uer8$ur%+ ne Str%nJK>Contactos6INSERTADO+ null+ null+ null*4
6bviamente esto obli*a a 'ue dentro del método %nsertar$* se a.ada la uri del contacto de la si*uiente forma9
ne TareaAnad%rContacto$etContentResol&er$*+ &alores*6e=ecute$ur%Contacto*4
Paso #5! "a eliminaci&n re'uiere de un nuevo action button ara disarar el evento! Eso si*nifica una modificaci&n del arc(ivomenuinsercioncontacto!:ml! Heamos9
menu_insercion_contacto.xml
7/23/2019 Consumir Un Servicio Web REST Desde Android
acc%on_el%,%nar or defecto estar) oculto, /a 'ue en la inserci&n normal no debe aarecer! <ero en la modificaci&n contactos esnecesario! <ara ello verifica dentro de onCreateOpt%onsMenu$* si ur%Contacto es diferente de null / lue*o cambia la visibilidad delítem!
"a sincroni%aci&n local o del cliente $ndroid se basa en el resultado 'ue arro#e la etici&n 1ET (acia el recurso s8nc 'ue vimos en elaartado n?mero I!
"a idea es comarar la car*a de contactos 'ue envía el servidor con los contactos locales en S"ite! -e este resultado 'uedar)na'uellos elementos 'ue deben ser a*re*ados, modificados / eliminados de la base de datos local!
"a sincroni%aci&n la imlementaremos con el frameworM de S/nc$daters de $ndroid ara reducir la dificultad de uso de servicios /momentos de sincroni%aci&n!
-ebido a 'ue la sincroni%aci&n es or demanda CmanualD, necesitamos un action button ara disarar la acci&n! $dem)s me areceideal avisar a la interfa% 'ue la sincroni%aci&n termin& eitosamente o se detuvo or errores!
El rocesador local es una entidad 'ue se encar*a de transformar el formato JS67 a elementos Contacto! "ue*o (ace un roceso decomaraci&n ara determinar 'ué cambios son necesarios en el cliente! -e esta manera, envía oeraciones al content rovider ara 'uese actualice S"ite / or ende la actividad de contactos!
7/23/2019 Consumir Un Servicio Web REST Desde Android
Paso #! El usuario necesita un action button 'ue le ermite iniciar la sincroni%aci&n, así 'ue solo abre el arc(ivomenulistacontactos!:ml / a*ré*alo ara 'ue se manten*a visible!
Paso #-! "o si*uiente es disarar el evento de sincroni%aci&n al resionar acc%on_s8nc! <ara ello constru/e un método llamados%ncron%ar$* / convoca al método ContentResol&er6re;uestS8nc$* ara iniciar una sincroni%aci&n manual!
77 Ver%/%cac%n para e&%tar %n%c%ar ,Gs de una s8nc a la &e Account cuentaAct%&a 2 UCuentas6obtenerCuentaAct%&a$t%s*4 %/ $ContentResol&er6%sS8ncAct%&e$cuentaAct%&a+ Contrato6AUTORIDAD** >
7/23/2019 Consumir Un Servicio Web REST Desde Android
El método UCuentas6obtenerCuentaAct%&a$* etrae la cuenta activa *uardada en las referencias! <uedes ver su contenido sidescar*as el c&di*o!
Recuerda 'ue en mi artículo N+&mo Sincroni%ar S"ite con /S" En $ndroidO te eli'ué 'ue la sincroni%aci&n or demanda se dasi asamos como ar*umentos S]NC_E#TRAS_E#PEDITED / S]NC_E#TRAS_MANUA! con el valor de true!
<or el momento no suceder) nada or'ue no tenemos un S2ncAdapter creado todavía, así 'ue rocederé a crearlo!
Paso #-! +rea un S/nc$dater ara reali%ar las sincroni%aciones! Recuerda 'ue también es necesario un autenticador ara 'ue elframeworM funcione correctamente!
El autenticador re'uiere de una definici&n F" ara la informaci&n *eneral de las cuentas! <ara construirlo, crea un nuevo arc(ivodentro de la careta res:ml llamado autenticador!:ml / a.ade el si*uiente c&di*o!
$(ora crea la clase autenticadora dentro del a'uete s2nc, 'ue etienda de AbstractAccountAutent%cator! +omo no usaremosautenticaci&n de cuentas, solo sobrescribe en blanco los métodos!
Autenticador.java
7? ? Autent%cador au=%l%ar para la apl%cac%n ?7publ%c class Autent%cador e=tends AbstractAccountAutent%cator >
publ%c Autent%cador$Conte=t conte=t* >
super$conte=t*4
O&err%de publ%c undle ed%tPropert%es$ AccountAutent%catorResponse r+ Str%n s* > tro ne UnsupportedOperat%onE=cept%on$*4
O&err%de publ%c undle etAutToZen$ AccountAutent%catorResponse r+ Account account+ Str%n s+ undle bundle* tros NetorZErrorE=cept%on > tro ne UnsupportedOperat%onE=cept%on$*4
O&err%de publ%c Str%n etAutToZen!abel$Str%n s* > tro ne UnsupportedOperat%onE=cept%on$*4
O&err%de publ%c undle updateCredent%als$ AccountAutent%catorResponse r+ Account account+ Str%n s+ undle bundle* tros NetorZErrorE=cept%on > tro ne UnsupportedOperat%onE=cept%on$*4
O&err%de publ%c undle as"eatures$
AccountAutent%catorResponse r+ Account account+ Str%nJK str%ns* tros NetorZErrorE=cept%on > tro ne UnsupportedOperat%onE=cept%on$*4
<ara finali%ar el se*mento de la autenticaci&n ve a <ile F =e, F Service F Service / nombra al nuevo servicioSer&%c%oAutent%cac%on! Este comonente también ser) auiliar, or lo 'ue sus métodos van sobrescritos or defecto!
7/23/2019 Consumir Un Servicio Web REST Desde Android
$(ora crea una nueva clase Java llamada S8ncAdapter 'ue (erede de AbstractTreaderS8ncAdapter! +rea dos constructores, unocon la firma ara versiones inferiores a la G!0 / otra ara las recientes! En se*uida sobrescribe el método onPer/or,S8nc$* en blanco!
!yncAdapter.java
publ%c class S8ncAdapter e=tends AbstractTreadedS8ncAdapter >
7?? ? Retorna %nter/a de co,un%cac%n para uso %nterno del /ra,eorZ ?7 O&err%de publ%c I%nder on%nd$Intent %ntent* > return s8ncAdapter6etS8ncAdapter%nder$*4
7o olvides 'ue este servicio re'uiere una confi*uraci&n revia 'ue se describe en un arc(ivo ml con la eti'ueta 9s8nc-adapterF!Sabiendo esto, crea un nuevo arc(ivo dentro de res:ml 'ue se llame s2ncadapter!:ml / a*re*a las si*uientes características9
Basta a'uí el s/nc adater se e#ecuta cuando el usuario resiona el bot&n de sincroni%aci&n, ero no sucede absolutamente nada, /a 'ueonPer/or,S8nc$* no tiene acciones or e#ecutar! <ara ello tenemos 'ue crear un comonente 'ue acceda al servidor rimero!
Paso #0! +rea una nueva clase llamada RESTSer&%ce dentro del a'uete ,eb! El ro&sito de esta es usar a Holle/ ara crear dosmétodo reresentativos del servicio web9 et$* / post$*!
#$!%!ervice.java
7/23/2019 Consumir Un Servicio Web REST Desde Android
77 A@ad%r pet%c%n a la p%la Volle8S%nleton6etInstance$conte=to*6addToRe;uest\ueue$pet%c%on*4
;)sicamente lo 'ue (a*o es encasular eticiones sonObectRe;uest de Holle/ en métodos 'ue ermitan tener control desde afuera!<ara Holle/ uso el si*uiente sin*leton!
? ? para, conte=t conte=to donde se eecutarGn las pet%c%ones ? return Instanc%a ?7 publ%c stat%c s8ncron%ed Volle8S%nleton etInstance$Conte=t conte=t* > %/ $s%nleton 22 null* > s%nleton 2 ne Volle8S%nleton$conte=t6etAppl%cat%onConte=t$**4 return s%nleton4
7?? ? Obt%ene la %nstanc%a de la cola de pet%c%ones ? ? return cola de pet%c%ones ?7 pr%&ate Re;uest\ueue etRe;uest\ueue$* > %/ $re;uest\ueue 22 null* >
Paso #5! "a etici&n 'ue se lan%& desde s8nc!ocal$* no rocesa la resuesta o error 'ue esta rodu%ca! "a ar'uitectura muestra 'ueusaremos un comonente llamado Procesador!ocal, el cual se encar*a de transformar el contenido JS67 en <6J6s Java arareali%ar una comaraci&n!
7o obstante, rimero es necesario crear la clase 'ue reresente l&*icamente a cada contacto ara 'ue el rocesador la imlemente!
El ob#etivo de la clase Contacto es mostrar los atributos de cada re*istro ara reali%ar el arsin* JS67 resectivo! Su contenido seríaeste9
• apl%carSan%dad$*9 "o uso al momento de arsear la resuesta JS67 en o#os ara evitar tener camos con el valor null 'ue er#udi'uen las comaraciones 'ue se (acen en co,pararCon$*!
• esMasRec%ente$*9 +omarar dos ob#etos +ontacto ara determinar cual es mas reciente basado en el atributo version!
• co,pararCon$*9 -etermina si dos contactos son i*uales!
Paso #;! +omo /a lo (e venido diciendo, el rocesador transforma la resuesta JS67 en unidades de datos entendibles en la l&*ica del ro*rama Cinstancias de ContactoD!
"ue*o comara los re*istros de S"ite eistentes con los contactos resultantes del arsin* / determina 'ue inserciones,modificaciones / eliminaciones deben reali%arse localmente!
El al*oritmo *eneral sería así9
a' <arsear arra/ JS67 de contactos a instancias Contactob' +onsultar los contactos localesc' +omarar cada contacto local con la lista de remotos, donde P Si el contacto local eiste en la lista de remotos, entonces se descarta de inserci&n P Si el contacto local eiste, entonces buscar diferencias con el remoto ara ro*ramar actuali%aci&n P Si el contacto local no eisten en la lista remota, entonces ro*ramar eliminaci&nd' Enviar todas las oeraciones ro*ramadas
$sectos a destacar9
• sa la clase ContentPro&%derOperat%on / sus método est)ticos newInsert(), newUpdate() / newDelete() ara reresentar una oeraci&n 'ue ser* e#ecutada como arte de un batc( en el ContentPro&%der, con appl8atc$*!
• "a librería Bson te ermite refle#ar un strin* con formato JS67 en un ob#eto 'ue coincida con los atributos 'ue oseen!
7/23/2019 Consumir Un Servicio Web REST Desde Android
77 Crear ur% de este contacto Ur% updateUr% 2 Contactos6constru%rUr%Contacto$/%laActual6%dContacto*4
7? A;u se apl%ca la resoluc%n de con/l%ctos de ,od%/%cac%ones de un ,%s,o recurso tanto en el ser&%dro co,o en la app6 \u%Hn tena la &ers%n ,Gs actual+ serG to,ado
else > 7? Se deduce ;ue a;uellos ele,entos ;ue no co%nc%d%eron+ 8a no e=%sten en el ser&%dor+ por lo ;ue se el%,%narGn ?7 Ur% deleteUr% 2 Contactos6constru%rUr%Contacto$/%laActual6%dContacto*4 !o6%$TA1+ 5Prora,ar El%,%nac%n del contacto 5 [ deleteUr%*4
? Con&%erte una /%la de un Cursor en un nue&o Contacto ? ? para, c cursor ? return obeto contacto ?7 pr%&ate Contacto deCursorAContacto$Cursor c* > return ne Contacto$ c6etStr%n$ConsultaContactos6ID_CONTACTO*+
7/23/2019 Consumir Un Servicio Web REST Desde Android
"a resuesta de la etici&n 1ET es rocesada con el método tratar1et$*, donde usamos el Procesador!ocal / lue*o alicar loscambios a través de ContentResol&er6appl8atc$*!
<or otro lado, los errores uedes tratarlos en otro método diferente como el 'ue /o nombré en el c&di*o anterior CtratarErrores$*D!Recuerda 'ue la resuesta de un error trae consi*o un ob#eto Json 'ue contiene un atributo 'estado' / un ',ensae'!
;as)ndome en eso, creé una clase e'ue.a 'ue reresente esa resuesta ara tener un arsin* con 3son, llamada RespuestaAp%!
publ%c class RespuestaAp% > pr%&ate %nt estado4 pr%&ate Str%n ,ensae4
En este momento /a es osible sincroni%ar localmente nuestra a! <ara robarlo, a*re*a dos nuevos re*istros en la base de datos/s'l / resiona el bot&n de sincroni%ar! -eberían de coiarse ambos re*istros en la alicaci&n $ndroid!
"ue*o rueba editar los re*istros del servidor / vuelve a sincroni%ar! También rueba la eliminaci&n ara ver si se relica!
;! Sincroni$ar base de datos )2s"l del servidor
"a sincroni%aci&n del servidor la iniciaré al final de la sincroni%aci&n local! +uando esta termine, entonces notificaré al usuario de 'ueeste roceso culmin& con satisfacci&n!
$(ora el roblema es encontrar la forma de recolectar todos los re*istros de la base de datos 'ue estén marcados como insertados,modificados / eliminados! "ue*o arsearlos a JS67 / enviarlos en la etici&n con la forma 'ue re'uiere el método post$* en elarc(ivo s2nc!p7p!
7/23/2019 Consumir Un Servicio Web REST Desde Android
"a soluci&n la encontrar)s en la creaci&n de la clase ProcesadorRe,oto, la cual es tiene naturale%a similar a Procesador!ocal! Estave% (aremos el roceso inverso, obteniendo cada una de las oeraciones remotas ara a*ruarlas en un ob#eto JS67!
;)sate en esta serie de asos ara conse*uir las oeraciones9
1! sa el método ContentResol&er6;uer8$* ara etraer re*istros marcados! <or e#emlo, los contactos insertados se consi*uen conla condici&n '3ERE %nsertado 2 0'!2! tera sobre el cursor con un %le / maea cada fila como un Map! Esto ermitir) reali%ar f)cilmente el arsin* con 3son!G! $*re*a el maeado a una lista!I! Retorna en la lista si esta tiene uno o m)s elementos!
Paso #! $sí 'ue crea una nueva clase dentro del a'uete s2nc llamada ProcesadorRe,oto / a*re*a el si*uiente c&di*o!
pr%&ate Map9Str%n+ ObectF ,apearActual%ac%on$Cursor c* > 77 Nue&o ,apa para re/learlo en SON Map9Str%n+ ObectF ,apaContacto 2 ne 3asMap9Str%n+ ObectF$*4
77 A@ad%r &alores de colu,nas co,o atr%butos UDatos6arearStr%nAMapa$,apaContacto+ Contactos6ID_CONTACTO+ c*4
7/23/2019 Consumir Un Servicio Web REST Desde Android
7ota 'ue el método crearPa8load$* acumula los resultados de las tres oeraciones en un solo maa 'ue ser) enviado en con elmétodo post$* de la clase RESTSer&%ce!
$dicionalmente tenemos un método llamado des,arcarContactos$* cu/a funci&n es oner en 0 las banderas de todos los re*istrossincroni%ados! +on ello evito 'ue se envíen a otra oeraci&n sin tener nada 'ue ver!
Paso #-! Envía la etici&n POST #usto al final de las acciones del método s8nc!ocal$*! <on el resultado del método crearPa8load$* de una instancia del rocesador remoto, como se*undo ar)metro del método post$*!
pr%&ate &o%d s8ncRe,ota$* > procRe,oto 2 ne ProcesadorRe,oto$*4
77 Constru%r pa8load con todas las operac%ones re,otas pend%entes Str%n datos 2 procRe,oto6crearPa8load$cr*4
;!G =oti.icar estados de sincroni$ación con Snac@1ars
Si e#ecutas la a (asta el momento, disfrutar)s de la sincroni%aci&n local / remota! El /ocat te mostrar) los sucesos 'ue va/anocurriendo en la etici&n BTT<, el arsin* JS67 / las oeraciones en el ContentPro&%der!
@ #ero qué hay del usuario)
@ #C'mo sabr3 el que la sincroni&aci'n termin' o fall')
Eisten varios elementos visuales 'ue odrían a/udarte, tales como los Toasts, SnacM;ars, notificaciones, barras de ro*reso oindicadores ersonali%ados en los views! Ba/ *ran variedad ara esco*er!
7/23/2019 Consumir Un Servicio Web REST Desde Android
En mi caso (aré 'ue las snacM bars soorten mis avisos!
El roblema de notificar estados es 'ue no sabemos en 'ué momento ir)n a terminar las acciones en el bacM*round 'ue e#ecuta elS8ncAdapter! "o 'ue no ermite e#ecutar acciones de forma secuencial!
<ero no te reocues! "a soluci&n la (allar)s en un comonente llamado "ocal;roadcastana*er ! Este se encar*a de enviar intentsentre los comonentes locales de tu a, como lo es la comunicaci&n entre el s/nc adater / la actividad contactos!
<ara comen%ar a enviar notificaciones solo si*ue estos asos9
! +rea una nueva clase 'ue etienda de roadCastRece%&er dentro de la actividad o comonente 'ue recibir) mensa#es! -ictaminalas acciones 'ue se e#ecutar)n al recibir el mensa#e dentro de onRece%&e$*!-! Re*istra el receiver con el método re%sterRece%&er$* del !ocalroadcastManaer! Este re*istro re'uiere un filtroIntent"%lter 'ue esecifi'ue todas las acciones de las 'ue estar) endiente el recetor!0! -esre*istralo en un lu*ar donde no sea necesario recibir las notificaciones con !ocalroadcastManaer6unre%sterRece%&er$* !5! inalmente envía mensa#es desde otro comonente con el método !ocalroadcastManaer6sendroadcast$* , instanciandointents con la acci&n ob#etivo / a.adiendo ar*umentos 'ue re'uieran rocesarse en el recetor!
:eamos.
Paso #! $bre Act%&%dad!%staContactos / a*re*a una nueva clase an&nima del tio roadcastRece%&er, dentro de onCreate$*!"ue*o sobrescsribe onRece%&e$* ara 'ue rodu%ca una SnacZbar con el mensa#e de teto 'ue vendr) desde otros comonentes!
+abe aclarar 'ue ACTION_S]NC es solo una constante de la clase ntent ara esecificar acciones de sincroni%aci&n, sin embar*o uedescrear tu roia constante ara determinar la acci&n!
Paso #0! El desre*istro uedes (acerlo en el método onPause$*, /a 'ue no es de utilidad recibir mensa#es cuando la actividad est)siendo sueruesta or otro comonente / muc(o menos cuando est) en se*undo lano!
Paso #5! $bre tu s/nc adater / envía intents desde el método tratarErrores$*! También uedes (acerlo al terminar lasincroni%aci&n comleta en tratarPost$*!
7/23/2019 Consumir Un Servicio Web REST Desde Android
El c&di*o anterior envía un intent con el mensa#e “Sincroni$ación completa” en caso de 'ue la sincroni%aci&n termine de formasatisfactoria! Recuerda enviar el mensa#e con !ocalroadcastManaer6sendroadcast$* !
Si ercibes 'ue tus mensa#es no se reciben, intenta revisar 'ue las acciones de los intents coincidan!
$l e#ecutar la a con todos los untos de envío de mensa#es, odr)s ver las snacM bars de la si*uiente forma!
7/23/2019 Consumir Un Servicio Web REST Desde Android
"os servicios REST son mu/ ?tiles ara or*ani%ar tus r)cticas de intercambio de datos entre alicaciones! #?otaste la gran diferencia
entre el uso de U@s para locali&ar recursos, en ve& de enviar peticiones sin forma, hacia m(ltiples archivos hp)
Recuerda 'ue cada alicaci&n demanda un conceto diferente de sincroni%aci&n de datos deendiendo del modelo de ne*ocio ocaracterísticas del servicio 'ue reste tu a a los usuarios! En mi caso, el e#emlo de <eole$ uede funcionar sin conei&n ainternet / ermite al usuario ele*ir en 'ue momento sincroni%ar sus datos!
+abe adicionar la imortancia de las oeraciones en batc( en el servicio web ara 'ue tu alicaci&n envíe ocas eticiones BTT< (aciael servidor! +on este enfo'ue, es osible otimi%ar la batería del disositivo m&vil al momento de sincroni%ar!
<or ?ltimo, te recomiendo investi*ar mu/ bien tus re'uerimientos de sincroni%aci&n / las estrate*ias 'ue alicar)s! Estos factores sonfundamentales ara ele*ir el rumbo de desarrollo 'ue tomar) tu ro/ecto / rote*er la informaci&n de cada usuario!