Android Webservices

81
JUEVES, 8 DE MAYO DE 2014 WebService: Conexiones a base de datos Mysql desde Android. PARTE 1 (Insertar) Buenas amigos, llevo un tiempo sin hacer nada por aquí, ya que estoy trabajando con un grupo de programadores en un proyecto, pero a petición popular, y a la cantidad de email que me han mandado pidiéndome información para realizar conexiones a Mysql desde android, voy a realizar este tema. Bien, el tema en sí es complejo, ojo, no difícil de entender, si no complejo de realizar, vamos a realizar mucho código para lo que realmente necesitamos, interactuar con una base de datos mysql en un servidor. Si habéis hecho conexiones a mysql desde java sabréis que con una clase que contenga 4 o 5 lineas de código podíamos realizar nuestra conexión a mysql, podéis comprobarlo aquí , posteriormente solo teníamos que manejar los datos obtenidos (7 u 8 lineas) y ya podíamos mostrar resultados en nuestro programa. Bien, esto en android cambia y se vuelve más complejo ya que, por seguridad, deberemos crear un webservice para que nos sirva de puente entre nuestra aplicación y nuestro servidor. Un Webservice suele ser un archivo PHP que recibe peticiones de nuestra app y se las envía al servidor, posteriormente el servidor responde a nuestro webservice, y este, a su vez, responde a nuestra app. Os dejo una imagen para que lo entendáis mejor.

description

Webservices con Android, acceso a datos en MySql a través de servicios web en Android

Transcript of Android Webservices

Page 1: Android Webservices

JUEVES, 8 DE MAYO DE 2014

WebService: Conexiones a base de datos Mysql desde Android. PARTE 1 (Insertar)Buenas amigos, llevo un tiempo sin hacer nada por aquí, ya que estoy trabajando con un grupo de programadores en un proyecto, pero a petición popular, y a la cantidad de email que me han mandado pidiéndome información para realizar conexiones a Mysql desde android, voy a realizar este tema.

Bien, el tema en sí es complejo, ojo, no difícil de entender, si no complejo de realizar, vamos a realizar mucho código para lo que realmente necesitamos, interactuar con una base de datos mysql en un servidor.

Si habéis hecho conexiones a mysql desde java sabréis que con una clase que contenga 4 o 5 lineas de código podíamos realizar nuestra conexión a mysql, podéis comprobarlo aquí, posteriormente solo teníamos que manejar los datos obtenidos (7 u 8 lineas) y ya podíamos mostrar resultados en nuestro programa. Bien, esto en android cambia y se vuelve más complejo ya que, por seguridad, deberemos crear un webservice para que nos sirva de puente entre nuestra aplicación y nuestro servidor.

Un Webservice suele ser un archivo PHP que recibe peticiones de nuestra app y se las envía al servidor, posteriormente el servidor responde a nuestro webservice, y este, a su vez, responde a nuestra app. Os dejo una imagen para que lo entendáis mejor.

Un WebService no tiene porque ser un archivo PHP, también podríamos realizar en nuestro servidor un programa en java que escuche por socket nuestra app y pasarle parámetros para que se comunique con el servidor, o podríamos crear un archivo javascript, o cualquier otra cosa que nos valga para comunicar nuestra app con nuestro servidor, pero ya digo, que lo más fácil, rápido y sencillo es un archivo PHP, no os compliquéis.

Bien, para crear la conexión a mysql necesitaremos:

Servidor con base de datos Mysql.

Page 2: Android Webservices

Mi base de datos esta compuesta por una tabla "personas" con los siguientes campos:

DNI---Varchar

Nombre--Varchar

Teléfono--Varchar

Email.--Varchar

Uno o varios WebService (según necesitemos). Yo voy a utilizar 2:

Insert.php

selectAll.php

Una conexión mediante la clase HttpClient de la API de Apache

No hay que agregar librerías, esta API va incluida en el repositorio android.

Ejecutarlo todo mediante hilos AsyncTask.

A partir de la versión 3 o superior, correrlo todo en AsyncTask es obligatorio.

Bueno, sabiendo esto, creamos un nuevo proyecto con su respectiva activity.

Mi activity va a ser muy simple:

Podéis observar que consta de:

4 TextView y 4 Edittext, para los campos a rellenar.

2 Button para insertar y mostrar.

2 ImageButton para pasar de una persona a otra y se nos vaya mostrando.

Page 3: Android Webservices

Bien, una vez tengamos nuestro diseño, nos vamos a nuestra clase.

Lo primero es ligar nuestra clase con el archivo xml y sus componentes:

Antes de continuar vamos a ir a nuestro archivo AndroidManifest y vamos a agregar

permisos de INTERNET, muy importante.

Una vez hecho todo lo anterior vamos a crear un método que envíe la información que

introducimos en los campos a nuestroWebService para que este se lo comunique al

servidor y obtener una respuesta.

Page 4: Android Webservices

Bueno, no os asustéis de ver tanta linea, ante todo saber que solo trabajamos con 2

clases y un ArrayList: HttpClient: Clase encargada de enviar la información almacenada en httpPost a nuestro WebService.

HttpPost: almacena los datos que serán enviados, por medio de HttpClient, a nuestro WebService.

List: Almacena objetos de tipo "NameValuePair" el cual almacena por constructor (NameValuePair es una interfaz la cual implementa la clase BasicNameValuePair ) una variable y el valor que contendrá dicha variable, las cuales son las que obtendrá nuestro WebService.

Veamos: Implementamos las clases con las que vamos a trabajar:

HttpClient httpclient=new DefaultHttpClient();

HttpPost httppost=new HttpPost("URL DE NUESTRO WEBSERVICE EN EL SERVIDOR")

Yo tengo puesto la ip local de mi pc, ya que si ponemos localhost o 127.0.0.1, el dispositivo va a buscar su propio localhost, el que va incluido en el móvil, y puede crear errores, lo mejor si estas probando, la ip local de tu pc. Si utilizas el emulador que trae el eclipse SDK android, tendrás que poner 10.0.0.2, ya que si no te dará fallo.

List nameValuePairs=new ArrayList(4);

Page 5: Android Webservices

En este caso le damos a nuestro ArrayList un tamaño (4) ya que son el número de variables con las que vamos a tratar, si quieres utilizar 3, pones 3, y así sucesivamente.

Ya tenemos nuestras clases preparadas, ahora vamos a almacenar los datos de nuestros EditText en nuestroArrayList:

nameValuePairs.add(BasicNameValuePair("dni", dni.getText().toString().trim()));

Bien, esto no tiene mucha historia, almacenamos objetos de BasicNameValuePair con una variable y el valor que va a tener que le pasamos por constructor. Agregamos a nuestro ArrayList un objeto de este tipo según el tamaño que le hayamos dado.

Una vez almacenados los datos, le pasamos el ArrayList a nuestra clase HttpPost para que lo codifique:

httppost.setEntity(new UrlEncodeForEntity(nameValuePairs));

Bueno, una vez que lo tenemos codificado con la url del webservice y la información de nuestro ArrayList, hacemos que HttpClient lo envíe:

httpclient.execute(httppost);

Bueno, no era tan difícil, si un poco complejo, pero no difícil.

Bien, ya hemos enviado nuestra información a nuestro WebService, veamoslo con lo que

le hemos enviado:

Veamos, este es nuestro WebService, un archivo escrito en PHP que interactua con

nuestro servidor, su funcionamiento sería de la siguiente manera: Rellenamos las variables del localhost con la información de nuestro servidor:

Hostname: Nombre del host.

Database: Nombre de nuestra base de datos.

Username: Nombre de usuario del servidor.

Password: Contraseña del servidor.

Page 6: Android Webservices

Posteriormente, con los datos de servidor que hemos introducido, le pedimos que conecte al servidor y almacene la respuesta en otra variable:

$localhost = mysql_connect($hostname_localhost,$username_localhost,$password_localhost)

Si no puede conectar enviara un informe de error

or trigger_error(mysql_error(),E_USER_ERROR);

Una vez conectado al servidor, buscará nuestra base de datos y se conectará:

mysql_select_db($database_localhost, $localhost);

Posteriormente, y una vez encontrad la base de datos, obtendrá las variables que le pasamos por nuestra aplicación y las almacenará en otras variables que pueda manejar mejor.

$nombre=$_POST['nombre'];

$dni=$_POST['dni'];

$telefono=$_POST['telefono'];

$email=$_POST['email'];

Daos cuenta de que los nombres entre comillas simples se llaman igual a las variables que les pasamos por nuestra app.

Almacenadas las variables, introduce los valores en un sentencia sql para realizar una consulta al servidor:

$query_search = "insert into personas(nombre,dni,telefono,email) values ('".$nombre."','".$dni."','".$telefono."','".$email."')";

Cuidado con las comillas simples y dobles, que puede ser un follón jeje.

Finalmente, y si todo ha ido bien, realizará la consulta a nuestro servidor, el cual, en caso de fallar la sentencia, nos enviará un informe de error.

$query_exec = mysql_query($query_search) or die(mysql_error());

Cerramos la conexión.

mysql_close($localhost);

Bien, ya tenemos el código java para conectarnos a nuestro servidor por medio de android

y tenemos un webservice escrito en PHP que hace de puente entre nuestra app y el

servidor, pero aún nos queda un último paso, realizar la consulta por medio de una

clase AsyncTask.

NOTA:No voy a hacer aquí una explicación sobre el funcionamiento de una clase AsyncTask, ya

que me quedaría muy extenso el post, en el futuro crearé un tema para esta clase. En google

puedes encontrar mucha información sobre esta clase.

Nos volvemos a nuestra clase, y creamos una clase interna que herede de AsyncTask:

Page 7: Android Webservices

Bien, en el método doInBackground creamos una condición if, en el cual introducimos

como condición el método insertar() (por esa razón lo hice booleano) si se los datos han

sido insertados, el método nos devuelve true y nos muestra un Toast con el éxito de la

operación y limpiando nuestro formulario, todo esto debe correr en un hilo ya que si no

bloquearía nuestroAsyncTask y nos funde a errores, si los datos no han podido ser

insertados, el método insertar nos devolverá false, y nos mostrará un Toast corriendo en

un hilo.

Bueno, ya lo tenemos todo: Un servidor. Bien!

Un WebService. Bien!

Un método para conectar con nuestro WebService. Bien!

Una clase AsyncTsk que ejecuta nuestro código. Bien!

Solo nos falta ir al botón insertar y darle una acción, para cuando se pulse ejecute todo al

mismo tiempo.

Page 8: Android Webservices

Finalmente ya lo tenemos, cuando pulsemos nuestro botón comprobará que no haya

ningún campo vacío, si lo hay, enviará un mensaje y no insertará nada.

Bueno, mencionar que mi dispositivo android no me hace bien las capturas de fotos y nos

puedo mostrar una captura con datos, pero si os puedo mostrar como los muestra mi

tabla personas una vez insertado los datos.

También os dejo la clase, el archivo .xml y el webservice en este enlace:

https://www.mediafire.com/?qyrmwvks9cyl2rx

Page 9: Android Webservices

PD: No he mencionado nada de encriptación (MD5, Base64...) o los certificados SSL,

quiero hacer una entrada acerca de la seguridad.

Continuaremos la lección en la PARTE 2.

Un saludo.

Page 10: Android Webservices

VIERNES, 9 DE MAYO DE 2014

WebService: Conexión a base de datos Mysql desde Android. PARTE 2.(Mostrar)Buenas amigos, en este nuevo tema vamos a continuar hablando de como conectar nuestra aplicación android a nuestro servidor Mysql. En el tema anterior, la PARTE 1, estuvimos viendo como insertar datos en nuestra base de datos, en este tema veremos como recuperar esos datos y mostrarlos en nuestro dispositivo.

Bien, deciros que no voy a utilizar JSON para obtener los datos, si no que crearé una clase Personas donde iré almacenando los datos de cada persona, para posteriormente guardar ese objeto "Persona" en un ArrayList. Esta forma de hacerlo quizás no sea la más correcta, pero es suficientemente válida como para explicarla. La forma correcta sería utilizando JSON, pero no quiero complicar más el tema.

Empecemos, aquí os dejo la clase, el archivo .xml y el webservice de la PARTE 1, por si no lo tenéis:

WebSeviceExample

Bien, lo primero que haremos será agregar una nueva clase Personas, la cual tendrá como atributos:

Nombre

DNI

Telefono

Email

Page 11: Android Webservices

Una vez la tengamos creada, nos vamos a nuestra clase y creamos nuevos atributos que vamos a utilizar:

private int posicion=0;

private List listaPersonas;

Esta lista la iniciamos en el método onCretae():

listaPersonas=new ArrayList();

Posteriormente creamos un método para obtener los datos del WebService:

Page 12: Android Webservices

Veamos, este código cambia ligeramente con respecto al método insertar que creamos en la PARTE 1.

Este método es de tipo String, por lo tanto nos devolverá una String con los resultados obtenidos de nuestro servidor.

Creamos una variable local de tipo String llamada resquest, esta almacenará la respuesta.

String resquest="";

Instanciamos HttpClient y HttpPost para comunicarnos con nuestro Webservice.

HttpClient httpclient=new DefaultHttpClient();

HttpPost httppost=new HttpPost("URL DE NUESTRO WEBSERVICE EN EL SERVIDOR");

Con respecto a nuestro método "ingresar", no vamos a crear un ArrayList para almacenar datos y pasárselos al servidor, ya que es el servidor el que nos tiene que pasar los datos.

Tampoco vamos codificar datos, ya que no tenemos datos que codificar.

Creamos un objeto de la clase ResponseHandler, ya que para que nos de una respuesta el webservicedebemos de pasarle este handler al método excute() de HttpClient por parámetro para que nos devuelva los datos.

ResponseHandler responseHandler=new BasicResponseHandler();

Le decimos a HttpClient que ejecute la petición a nuestro webservice, y este nos devolverá una String, la cual almacenamos en resquest:

resquest=httpclient.execute(httppost, responseHandler);

Bien, ya tenemos el código para obtener los datos del servidor, veamos que es lo que hace nuestro Webservice cuando conectamos con él.:

Page 13: Android Webservices

Como podéis observar, cambia poco con respecto a nuestro WebService "insert.php": Lo primero es meter la información de nuestro servidor:

Hostname: Nombre del host.

Database: Nombre de nuestra base de datos.

Username: Nombre de usuario del servidor.

Password: Contraseña del servidor.

Posteriormente nuestro WebService intentará conectar al servidor, enviando un informe de error en caso de no porder conectar:

 $localhost=mysql_connect($hostname_localhost,$username_localhost,$password_localhost)

or trigger_error(mysql_error(),E_USER_ERROR);

Una vez conectado al servidor, intentará conectar con nuestra base de datos

mysql_select_db($database_localhost, $localhost);

Luego, creamos una sentencia sql para que obtenga todos los datos del servidor.

$query_search = "select * from personas order by dni";

Ejecuta la sentencia sql:

$query_exec = mysql_query($query_search) or die(mysql_error());

Finalmente, y mediante un bucle WHILE nos irá imprimiendo los resultados.

while($row = mysql_fetch_array($query_exec)){

echo $row['nombre']." ".$row['dni']." ".$row['telefono']." ".$row['email']."/";

}

Cerramos la conexión:

mysql_close($localhost);

Page 14: Android Webservices

Decir que la barra al final del echo "/" y los "br", los pongo para filtrar y descomponer la información que me envía el servidor, ya que este me manda una String con todas las filas, y yo las filtro para poder manejar los datos individualmente.

Bien, ya sabemos como funciona nuestro WebService y tenemos almacenada la información del servidor, ahora vamos a crear un método que nos filtre los resultados y nos lo almacene en objetos:

Veamos: Creamos un método booleano que en caso de no obtener resultados de nuestro WebService retornará false y en caso de obtener resultados, lo descompondrá, lo almacenará y retornará true.

Limpiamos nuestro ArrayList por si tuviese algo de información.

listaPersonas.clear();

Ahora creamos una condición if para comprobar que nuestro resultado contiene información para poder continuar.

if(!mostrar().equalsIgnoreCase(""))

Si la condición es cierta, pasamos el primer filtro separando la información por bloques utilizando como elemento separatorio la barra "/"

String [] cargaDatos=mostrar().split("/");

Acordaos de que nuestro webservice imprimía una barra "/" cada vez que mostraba una fila, es la que utilizo para el split.

Tenemos las filas almacenadas en un array, pero cada posición del array almacena una String con todos los datos de la persona, por lo tanto le vamos a pasar un segundo filtro para almacenar finalmente los datos de forma individual.

Creamos un for que recorra nuestro array "cargaDatos".

for (int i = 0; i < cargarDatos.length; i++) {

Por cada posición del array lo descomponemos con otro split, en este caso utilizaremos br para nuestro split.

String datosPersona[]=cargarDatos[i].split("<"br">");

Page 15: Android Webservices

quitarle las comillas a "br", que es que si no me crea un conflicto con el html y me genera un salto de linea

Creamos un objeto de la clase Personas

Perosnas personas=new Personas();

Le damos a cada atributo de personas el valor almacenado en nuestro array "datosPersonas"

personas.setNombre(datosPersona[0]);

personas.setDni(datosPersona[1]);

personas.setTelefono(datosPersona[2]);

personas.setEmail(datosPersona[3]);

Finalmente agregamos nuestro objeto Personas a nuestro ArrayList:

listaPersonas.add(personas);

Antes de pasar a nuestro AsyncTask para cargar los datos, vamos a crear otro método que nos imprima en nuestro formulario los datos almacenados en nuestro ArrayList.

Este método no tiene mucha historia, le pasamos una posición por parámetro y, corriendo en un hilo, nos busca el objeto almacenado en la posición indicada y lo muestra en nuestro formulario.

Finalmente lo ejecutamos todo en nuestro AsyncTask:

 Ya con todo, nos vamos a nuestro botón mostrar y le damos una acción:

Page 16: Android Webservices

Para darle un poco más de chicha creamos los ImageButton "mas" y "menos", la acción de estos botones sería:

La acción de "mas" sería: Comprobar que la lista no este vacía

if(!listaPersonas.isEmpty)

Si no esta vacía comprueba que la variable int posicion no tenga un valor superior al tamaño de nuestroArrayList

if(posicion>=listaPersonas.size()-1)

Si es superior o igual, iguala el valor de posicion al tamaño de nuestro ArrayList y muestra el objeto, en nuestro formulario, de dicha posición.

posicion=listaPersonas.size()-1;

mostrarPersona(posicion)

Si no es superior o igual, suma +1 al valor de posicion y muestra los resultados en nuestro formulario:

posicion++;

mostrarPersona(posicion);

La acción de nuestro botón "menos" es muy parecida:

Page 17: Android Webservices

Bien, es mu parecido al funcionamiento de nuestro botón "mas" así que supongo que no necesite una explicación.

Bien amigos, hasta aquí la PARTE 2, espero no haberos hecho un cacao mental, y haberme expresado con claridad

Os dejo el link con el WebService "selectAll.php" y la clase con todos los métodos.

WebServiceExampleCodePARTE2

Continuaremos con la PARTE 3

PD: Decir, una vez más, que esta forma de hacerlo no sea la más correcta, pero es valida, ya que no vulnero la seguridad en ningún momento (Certificados SSL y encriptación en los próximos temas), aunque si es verdad que no he tenido cuidado a la hora de optimizar la memoria que consume por lo poca cosa que es, pero ya os digo, que consume mucho para la poca cosa que es, pero lo he hecho así aún sabiéndolo, porque no me quería entretener con esto mucho tiempo. La optimización de memoria corre por vuestra cuenta :P

Un saludo a todos.

Page 18: Android Webservices

MARTES, 13 DE MAYO DE 2014

WebService: Conexiones a Mysql desde Android. PARTE 3 (Update).Buenas amigos, vamos a continuar con el tema de los WebService. En entradas anteriores veíamos como insertar datos en nuestra base de datos mysql (PARTE 1) y posteriormente como mostrar los datos, de nuestra base de datos, en nuestra aplicación (PARTE 2). Ahora, en esta nueva entrada, vamos a ver como actualizar los registros de nuestra base de datos.

Bien, primero voy a modificar mi archivo xml para que quede de la siguiente manera:

Bueno, creamos un método para conectar con nuestro webservice:

Page 19: Android Webservices

Veamos, este método es exactamente igual que el método insertar de la PARTE 1, lo único que cambia es la url del servidor. Veamos:

Implementamos las clases con las que vamos a trabajar:

HttpClient httpclient=new DefaultHttpClient();

HttpPost httppost=new HttpPost("URL DE NUESTRO WEBSERVICE EN EL SERVIDOR")

Yo tengo puesto la ip local de mi pc, ya que si ponemos localhost o 127.0.0.1, el dispositivo va a buscar su propio localhost, el que va incluido en el móvil, y puede crear errores, lo mejor si estas probando, la ip local de tu pc. Si utilizas el emulador que trae el eclipse SDK android, tendrás que poner 10.0.0.2, ya que si no te dará fallo.

List nameValuePairs=new ArrayList(4);

En este caso le damos a nuestro ArrayList un tamaño (4) ya que son el número de variables con las que vamos a tratar, si quieres utilizar 3, pones 3, y así sucesivamente.

Ya tenemos nuestras clases preparadas, ahora vamos a almacenar los datos de nuestros EditText en nuestro ArrayList:

nameValuePairs.add(BasicNameValuePair("dni", dni.getText().toString().trim()));

Bien, esto no tiene mucha historia, almacenamos objetos de BasicNameValuePair con una variable y el valor que va a tener que le pasamos por

Page 20: Android Webservices

constructor. Agregamos a nuestro ArrayList un objeto de este tipo según el tamaño que le hayamos dado.

Una vez almacenados los datos, le pasamos el ArrayList a nuestra clase HttpPost para que lo codifique:

httppost.setEntity(new UrlEncodeForEntity(nameValuePairs));

Bueno, una vez que lo tenemos codificado con la url del webservice y la información de nuestro ArrayList, hacemos que HttpClient lo envíe:

httpclient.execute(httppost);

Ahora vamos a ver como trabaja nuestro WebService:

Rellenamos las variables del localhost con la información de nuestro servidor:

Hostname: Nombre del host.

Database: Nombre de nuestra base de datos.

Username: Nombre de usuario del servidor.

Password: Contraseña del servidor.

Posteriormente, con los datos de servidor que hemos introducido, le pedimos que conecte al servidor y almacene la respuesta en otra variable:

 $localhost=mysql_connect($hostname_localhost,$username_localhost,$password_localhost)

Si no puede conectar enviara un informe de error

or trigger_error(mysql_error(),E_USER_ERROR);

Una vez conectado al servidor, buscará nuestra base de datos y se conectará:

mysql_select_db($database_localhost, $localhost);

Posteriormente, y una vez encontrada la base de datos, obtendrá las variables que le pasamos por nuestra aplicación y las almacenará en otras variables que pueda manejar mejor.

$nombre=$_POST['nombre'];

$dni=$_POST['dni'];

$telefono=$_POST['telefono'];

$email=$_POST['email'];

Page 21: Android Webservices

Daos cuenta de que los nombres entre comillas simples se llaman igual a las variables que les pasamos por nuestra app.

Almacenadas las variables, introduce los valores en un sentencia sql para realizar una consulta al servidor:

$query_search = "update personas set nombre='".$nombre."', telefono='".$telefono."',email='".$email."' where dni='".$dni."'";

Cuidado con las comillas simples y dobles, que puede ser un follón jeje.

Finalmente, y si todo ha ido bien, realizará la consulta a nuestro servidor, el cual, en caso de fallar la sentencia, nos enviará un informe de error.

$query_exec = mysql_query($query_search) or die(mysql_error());

Cerramos la conexión.

mysql_close($localhost);

Antes de ir con nuestra AsyncTask, voy a crear un método que no podamos modificar el campo dni, ya que lo utilizo comoprimary key:

Lo que hace este método es recorrer nuestro ArrayList listaPersonas comprobando el campo dni de cada persona, si el dnide nuestro campo EditText dni coincide con el campo dni del objeto personas, devuelve true, por lo que podrá actualizar nuestro registro, en caso de que no coincida, mostrará un Toast comunicando que no puede modificar el registro (porque nuestro dni no existe en la base de datos) y nos devuelve false.

Ahora si, vamos a ver nuestro AsyncTask:

Page 22: Android Webservices

Bien, en el método doInBackground creamos una condición if, en el cual introducimos como condición el método update() si se los datos han sido actualizados, el método nos devuelve true y nos muestra un Toast con el éxito de la operación y limpiando nuestro formulario, todo esto debe correr en un hilo ya que si no bloquearía nuestro AsyncTask y nos funde a errores, si los datos no han podido ser actualizados, el método update() nos devolverá false, y nos mostrará un Toast corriendo en un hilo.

Bueno, solo nos queda darle una acción a nuestro botón actualizar:

Page 23: Android Webservices

Como nuestro botón insertar, primero comprueba que no haya campos vacíos, posteriormente, y si los campos no están vacíos, comprueba que exista el dni, y si todo ha ido bien, nos ejecuta nuestro código update, si no, nos mostrará por pantalla un Toast con el tipo de error.

Bien amigos, hasta aquí la opción para actualizar los registros de nuestra base de datos.

Aquí os dejo el .xml, la clase y el php: WebServiceCodeExamplePARTE3

Continuaremos con la PARTE 4.

Un saludo.

Page 24: Android Webservices

MIÉRCOLES, 14 DE MAYO DE 2014

WebService. Conexión a base de datos Mysql desde Android. PARTE 4 (Borrar)Buenas amigos, en temas anteriores estuvimos viendo como insertar registros a una base de datos Mysql (PARTE 1), como mostrar esos datos en nuestra app (PARTE 2) y como modificarlos (PARTE 3). Bien, como es obvio, en esta nueva parte veremos como borrar registros de nuestra base de datos.

Primeramente voy a crear un método en mi clase WebServiceExample para que conecte con el webservice asociado y le pase un parámetro, DNI, para que nos borre a nuestro usuario según su dni.

Bueno, si hemos seguidos todas las partes de este tutorial, esto tiene que estar dominado, varía muy poco entre unas cosas y otras.

Implementamos las clases con las que vamos a trabajar: HttpClient httpclient=new DefaultHttpClient();

HttpPost httppost=new HttpPost("URL DE NUESTRO WEBSERVICE EN EL SERVIDOR")

Yo tengo puesto la ip local de mi pc, ya que si ponemos localhost o 127.0.0.1, el dispositivo va a buscar su propio localhost, el que va incluido en el móvil, y puede crear errores, lo mejor si estas probando, la ip local de tu pc. Si utilizas el emulador que trae el eclipse SDK android, tendrás que poner 10.0.0.2, ya que si no te dará fallo.

Page 25: Android Webservices

List nameValuePairs=new ArrayList(1);

En este caso le damos a nuestro ArrayList un tamaño (1) ya que son el número de variables con las que vamos a tratar, si quieres utilizar 3, pones 3, y así sucesivamente.

Ya tenemos nuestras clases preparadas, ahora vamos a almacenar los datos de nuestros EditText en nuestro ArrayList:

nameValuePairs.add(BasicNameValuePair("dni", dni.getText().toString().trim()));

Bien, esto no tiene mucha historia, almacenamos objetos de BasicNameValuePair con una variable y el valor que va a tener que le pasamos por constructor. Agregamos a nuestro ArrayList un objeto de este tipo según el tamaño que le hayamos dado.

Una vez almacenados los datos, le pasamos el ArrayList a nuestra clase HttpPost para que lo codifique:

httppost.setEntity(new UrlEncodeForEntity(nameValuePairs));

Bueno, una vez que lo tenemos codificado con la url del webservice y la información de nuestro ArrayList, hacemos que HttpClient lo envíe:

httpclient.execute(httppost);

Ahora nos vamos a nuestro webservice para ver como trabaja:

Cómo veis, el webservice también cambia poco con respecto a los anteriores: Rellenamos las variables del localhost con la información de nuestro servidor:

Hostname: Nombre del host.

Database: Nombre de nuestra base de datos.

Username: Nombre de usuario del servidor.

Password: Contraseña del servidor.

Page 26: Android Webservices

Posteriormente, con los datos de servidor que hemos introducido, le pedimos que conecte al servidor y almacene la respuesta en otra variable:

 $localhost=mysql_connect($hostname_localhost,$username_localhost,$password_localhost)

Si no puede conectar enviara un informe de error

or trigger_error(mysql_error(),E_USER_ERROR);

Una vez conectado al servidor, buscará nuestra base de datos y se conectará:

mysql_select_db($database_localhost, $localhost);

Posteriormente, y una vez encontrada la base de datos, obtendrá la variable que le pasamos por nuestra aplicación y las almacenará en otra variable que pueda manejar mejor.

$dni=$_POST['dni'];

Almacenada la variable, introduce el valor en un sentencia sql para realizar una consulta al servidor:

$query_search = "delete from personas where dni='".$dni."'";

Finalmente, y si todo ha ido bien, realizará la consulta a nuestro servidor, el cual, en caso de fallar la sentencia, nos enviará un informe de error.

$query_exec = mysql_query($query_search) or die(mysql_error());

Cerramos la conexión.

mysql_close($localhost);

Ahora, y como ya deberías saber, vamos a crear una clase AsyncTask para que ejecute nuestra conexión en segundo plano:

Page 27: Android Webservices

Bueno, en el método doInBackground creamos una condición if, en el cual introducimos como condición el método eliminar() si se los datos han sido eliminados, el método nos devuelve true y nos muestra un Toast con el éxito de la operación y limpiando nuestro formulario, todo esto debe correr en un hilo ya que si no bloquearía nuestro AsyncTask y nos funde a errores, si los datos no han podido ser borrados, el método eliminar() nos devolverá false, y nos mostrará un Toast corriendo en un hilo.

Finalmente vamos a nuestro botón eliminar y le damos una acción:

Page 28: Android Webservices

Bien, con esto ya podríamos eliminar los registros de nuestra base de datos.

Continuaremos en la PARTE 5

Aquí os dejo la clase, el archivo xml y el PHP: WebServiceCodeExampleParte4

Un saludo a todos.

Page 29: Android Webservices

MARTES, 20 DE MAYO DE 2014

WebService: Subir Imagen a Servidor desde Android.Buenas amigos, estuvimos viendo en temas anteriores como manejar los datos de un servidor con una base de datos mysql. En este nuevo tema vamos a ver como subir, a nuestro servidor, una imagen tomada con la cámara de nuestro dispositivo.

Bien el tema en sí es un poco complejo pero con un poco de orden podemos lograrlo hacer muy fácilmente. Decir, antes de continuar, que también he creado una nueva tabla en la base de datos llamada "imagenes", la cual la componen un campo ID(primary key y auto incremento) y un campo imagen (Varchar) donde almaceno el nombre, OJO, no la ruta, el nombre de la imagen.

Antes de empezar agregamos permisos a nuestra aplicación:

Posteriormente agregamos la librería httpmine de Apache

httpmine-4.2.5.jar

Creamos una carpeta en nuestro servidor, en mi caso "imágenes". Si ya la tienes creada, ni caso a este punto.

Ahora creamos nuestro archivo xml con los componentes que desee cada uno. En mi caso se compondrán de:

ImageButton: Para lanzar nuestra cámara.

EditText: Para nombrar nuestra imagen

ImageView: Para mostrar la imagen obtenida.

Button: Para subir la imagen a nuestro servidor.

Page 30: Android Webservices

Tras realizar nuestro .xml nos vamos a nuestra clase y declaramos los atributos que vamos a necesitar:

Como veis tenemos declarados nuestros 4 componente:1. ImageButton camara

2. ImageView imagen

3. EditText nombreImagen

4. Button upload

y otros 3 que vamos a ir utilizando a lo largo de este tema:1. Uri output.

2. String foto

3. File file.

Una vez llegados hasta aquí creamos un método para activar la cámara del dispositivo:

Page 31: Android Webservices

Primeramente almacenamos en la String foto la ruta donde se va a guardar nuestra imagen, en el dispositivo, con el nombre que hayamos elegido.

foto = Environment.getExternalStorageDirectory() +"/" +nombreImagen.getText().toString().trim()+".jpg";

Pasamos nuestra String foto a File.

file=new File(foto);

Creamos un Intent que accederá a la cámara de nuestro dispositivo.

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

Pasamos nuestro File a Uri.

output=Uri.fromFile(file);

Le pasamos a nuestro Intent la orden de almacenar en el dispositivo la imagen, y el Uri con la ruta de la imagen.

intent.putExtra(MediaStore.EXTRA_OUTPUT, output);

Nos abre una nueva Activity con nuestra cámara y almacena el resultado para procesarla en el método sobreescrito starActivityForResult(parametro1,parametro2).

startActivityForResult(intent, 1);

El 1 es para indicar que queremos acceder a la cámara.

Bien, con este método se nos abrirá la cámara de nuestro dispositivo y al obtener una imagen el métodostartActivityForResult se encargará de procesarla y mostrarla en nuestro ImageView:

Page 32: Android Webservices

Creamos un objeto de la clase ContentResolver que nos dará acceso al contenido almacenado en la app.

 ContentResolver cr=this.getContentResolver();

Creamos un objeto de la clase Bitmap para manejar nuestra imagen que hemos obtenido de nuestra cámara.

Bitmap bit=android.provider.MediaStore.Images.Media.getBitmap(cr, output);

Le pasamos por argumentos nuestro objeto ContentResolver para permitir el acceso y nuestro Uri indicándole en que ruta está.

Una vez hecho esto, le indicamos en que orientación debe estar, esto de por si no lo hace android, tenemos que crear un código para indicar que si una imagen se obtiene en posición landscape u horizontal nos la tiene que mostrar en landscape u horizontal en nuestro ImageView. Esto lo podemos conseguir por medio de un switch y de la siguiente manera:

Creamos una variable de tipo int que almacenara los grados que debe ser rotada la imagen.

int rotate=0;

Page 33: Android Webservices

Creamos un objeto ExifInterface que se encargará de evaluar en que orientación esta nuestra imagen

 ExifInterface exif = new ExifInterface(file.getAbsolutePath());

Le pasamos por argumentos la ruta absoluta de nuestra imagen.

Creamos y almacenamos la orientación que nos devuelve ExifInterface:

int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

Con un switch le damos un valor a rotate según el valor devuelto por ExifInterface:

switch (orientation) {

   case ExifInterface.ORIENTATION_ROTATE_270:

            rotate = 270;

             break;

  case ExifInterface.ORIENTATION_ROTATE_180:

             rotate = 180;

             break;

   case ExifInterface.ORIENTATION_ROTATE_90:

             rotate = 90;

             break;

        }

Creamos un objeto de la clase Matrix que será la encargada de transformar nuestra imagen y rotarla en su posición.

Matrix matrix=new Matrix();

Le pasamos la rotación que queremos que tenga:

matrix.postRotate(rotate);

Le indicamos a Bitmap la nueva configuración de la imagen:

bit = Bitmap.createBitmap(bit , 0, 0, bit.getWidth(), bit.getHeight(), matrix, true);

Finalmente insertamos nuestra imagen procesada a nuestro ImageView

imagen.setImageBitmap(bit);

Bien, hecho esto le damos a nuestro ImageButton la acción para iniciar la cámara:

Page 34: Android Webservices

Esta acción comprueba que el Edittext nombreImagen no esté vacío, si lo está, nos manda un Toast de aviso, si no, iniciará la cámara.

Con todo esto ya podremos hacer fotos e ir mostrándolas en nuestro ImageView.

Para subir nuestra imagen a servidor necesitaremos:1. Un método que conecte con un WebService

2. Un WebService que guarde nuestra imagen.

3. Una clase AsyncTask para ejecutarlo todo.

Nuestro método quedaría de la siguiente forma:

Creamos un objeto DefaultHttpClient para realiza la conexión a nuestro WebService.

HttpClient httpclient=new DefaultHttpClient();

Le cambiamos los parámetros (normalmente utilizamos los valores por defecto, en este caso no)

httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

Creamos un objeto HttpPost y le pasamos la ruta de nuestro WebService en el servidor por el construtor.

HttpPost httppost = new HttpPost("http://192.168.0.11/picarcodigo/upload.php");

Creamos un objeto de MultipartEntity, la cual se encuentra en la librería que os pasé antes. Se encargará de ayudarnos a subir el archivo almacenándolo (en temas anteriores vimos que utilizábamos BasicNameValuePairpara almacenarlos).

MultipartEntity mpEntity = new MultipartEntity(); 

Creamos un objeto FileBody el cual ayudará a subir el contenido indicando, por constructor, el archivo a subir y el tipo, en este caso una imagen en formato jpg ("image/jpeg").

 ContentBody foto = new FileBody(file, "image/jpeg");

Page 35: Android Webservices

Le pasamos en contenido almacenado en FileBoody y se lo pasamos MultipartEntity para que lo almacene

mpEntity.addPart("fotoUp", foto);

Pasamos el objeto mpEntity y lo almacenamos en nuestro httppost

httppost.setEntity(mpEntity);

Ejecutamos nuestro httpclient pasándole toda la información necesaria por httppost

httpclient.execute(httppost);

Una vez ejecutado todo, obtenemos la conexión y la cerramos.

httpclient.getConnectionManager().shutdown();

Bien, es un poco complejo, pero siguiendo los pasos es sencillo. Veamos como queda nuestro WebService:

Bien, un poco distinto a lo visto en otros temas: Le indicamos cual va a ser la ruta que va a tener en nuestro servidor, recordar que mi carpeta se llamaba imagenes.

$ruta = "imagenes/" .basename($_FILES['fotoUp']['name']);

A la variable $_FILES se le adjudicara la ruta y el nombre.

Creamos una condición if y con la ayuda del método move_uploaded_file movemos la imagen desde nuestro dispositivo al servidor.

if(move_uploaded_file($_FILES['fotoUp']['tmp_name'], $ruta))

Este método tiene 2 parámetros, el primero es de donde viene el archivo y el segundo es donde va a ser copiado.

Damos permisos al archivo por medio del método chmod

chmod ("uploads/".basename( $_FILES['fotoUp']['name']), 0644);

2 parámetros, el tipo de archivo, y los permisos, 0644 en este caso. El 6 para administrador, el primer 4 para grupos y el segundo 4 para usuarios (creo que es así, no estoy muy puesto en permisos)Adjunto tabla de la wikipedia:

Page 36: Android Webservices

Bien, así queda nuestro WebService, pongámoslo todo a correr en un AsyncTask:

Bien nuestra clase AsyncTask va a utilizar los métodos onPreExecute y onPostExecute, los cuales realizan acciones antes y después de la acción del método doInBackground() respectivamente.

En el método onPreExecute creamos un progressDialog que se mostrará mientras se sube nuestra imagen, y lo cerramos en el on PostExecute una vez realizada la acción de doInBackground.

En el método doInBackground llamamos al método uploadFoto y le pasamos por parámetro la url de nuestra imagen. Posteriormente, y como dije al principio del tema insertaremos el nombre de la imagen en una tabla de la base de datos.

No voy a explicar lo que hace el método insertar, ni su WebService, os pongo las imágenes y si queréis saber como funciona exactamente podéis visitar la PARTE 1.

Método onInsertar():

Page 38: Android Webservices

Comprobamos que el archivo existe, y si es así, nos ejecuta toda la parafernalia.

Bien, espero que no haya sido mucho lío ni mucha confusión. Este código funciona, estar seguro de que tenéis vuestro servidor correctamente configurado cuando ejecutéis.

Aquí os dejo los archivos (xml, .java y .php): WebServiceUploadImage

Page 39: Android Webservices

JUEVES, 22 DE MAYO DE 2014

Android: Trabajando con ViewPagerBuenas amigos, en este nuevo tema vamos a ver como realizar una app en el que poder deslizar nuestras activitys y que se nos vayan mostrando muy parecidamente a como lo hace google play. Esto nos puede facilitar el diseño de nuestra aplicación ya que nos permite tener varias activitys funcionando en una sola.

Antes de nada voy a ir enumerando los componentes que nos harán falta:1. Librería JakeWharton Android ViewPagerIndicator

2. Un archivo xml donde colocaremos el diseño de nuestra activity

3. Un archivo xml que contendrá un ViewPager y un TitlePageIndicator

4. Un archivo .java que herede de Fragment

5. Un archivo .java que herede de FragmentActivity

6. Una clase PageAdapter para crear las distintas activitys

7. Una clase DepthPageTransformer que nos proporciona google

Bien, todos estos archivos los podéis descargar al final des tema.

Primero Importamos la librería JakeWharton Android ViewPagerIndicator (podéis ver el proyecto en github pulsandoaquí)a nuestro proyecto android. Debemos importarla como proyecto Android existente y no como .jar, para ello vamos a realizar los siguientes pasos:

En eclipse, pulsamos file/new/other

En la nueva ventana que se nos abre pulsamos sobre "Android Project from Existing Code"

Page 40: Android Webservices

Buscamos nuestra librería en el pc y pulsamos finish

Nota: Esta librería en particular os debería aparecer con el nombre library. Una vez tengamos la librería incluida, pinchamos sobre nuestro proyecto con botón derecho y elegimos"properties"

Page 41: Android Webservices

En la ventana que se nos abre pinchamos sobre Android y en la parte de abajo a la derecha nos sale una opción"library", pulsamos en "add", elegimos nuestra librería y pulsamos "OK"

Ya tenemos nuestra librería android en nuestro proyecto.

NOTA: No confundir una librería android con una librería java

Una vez la librería este añadida vamos a realizar nuestras 2 archivos xml: El primer archivo xml está compuesto por un ViewPager y un TitlePagerIndicator

Page 42: Android Webservices

Os lo pongo de esta manera para que lo veáis mejor.

El segundo xml que voy a utilizar va a ser el mismo que utilicé para el tema de subir imagen a servidor sin darle ninguna funcionalidad, solo quiero que veáis como se desliza la screen al pasarla con el dedo, el darle funciones es cosa vuestra.

Bien, teniendo ya  nuestros archivos xml creados vamos a empezar a crear clases, necesitaremos 4:

MyFragmentPagerAdapter

Page 43: Android Webservices

Bueno, algo que no he explicado son los fragments, estos se comportan como en html los div o capas, es decir, son un conjunto de activitys que se pueden unir o acoplar para formar una activity más completa.

Bien, no es algo que vayamos a profundizar aquí, pero para que os orientéis.

Dicho esto, esta clase que hemos creado heredará de FragmentPageAdapter y almacenará en un list de fragment losfragments que le vayamos pasando por constructor.

El primer método nos agrega un fragment a nuestro list.

public void addFragment(Fragment fragment) {

        this.fragments.add(fragment);//Agregamos fragment a nuestra list

    }

El segundo método es sobreescrito, y nos devuelve un elemento de nuestra list pasando su posición por parámetro.

 @Override

Page 44: Android Webservices

    public Fragment getItem(int arg0) {

        return this.fragments.get(arg0);//Obtenemos un item de nuestra list

    } 

El tercer método es sobreescrito y nos devuelve la cantidad de elementos que hay almacenados en nuestro list.

@Override

    public int getCount() {

        return this.fragments.size();//Obtenemos el tamañp de nuestra list

    }

El cuarto método es sobreescrito, y da un titulo a cada fragment según posición.

 @Override

    public CharSequence getPageTitle(int position) {

     String s="";

     switch(position){

     case 0:  s="Pestaña 1"; break;

     case 1:  s="Pestaña 2"; break;

     case 2:  s="Pestaña 3"; break;

     case 3:  s="Pestaña 4"; break;

     }

        return s;

    }

Esta clase no tiene más explicación, es muy sencilla.

DepthPageTransfomer Bueno esta clase nos la proporciona google junto con ZoomOutPageTransformer y su función es darle una animación a nuestros fragments mientras deslizamos la pantalla. No voy a explicarla, ya lo hace muy bien google, solo tenéis que copiarla y agregarla al proyecto, de todas maneras, yo la dejaré al final del tema junto al resto de archivos. Podéis verla aquí

ViewPagerFragment

Page 45: Android Webservices

Esta clase, como observaréis, no hereda de activity, si no de fragment, es una porción de la activity final que queremos crear:

Creamos un método static que nos devuelva como resultado un objeto de nuestro fragment. Utilizaremos este método para invocarlo en la siguiente clase.

public static ViewPagerFragment newInstance() { 

        // Instantiate a new fragment

ViewPagerFragment fragment = new ViewPagerFragment(); 

        return fragment; 

    }

Sobreescribimos el método onCreate(), pero como ya dije, solo quiero mostrar la activity, no le voy a dar ninguna acción, así que lo dejo vacío

@Override

public void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

}

Para terminar, sobreescribimos el método onCreateView(), en el cual es donde iniciamos los componentes de nuestro archivo xml en los fragments. Podéis observar que en este método apunto al xml que quiero que muestre.

Page 46: Android Webservices

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// TODO Auto-generated method stub

ViewGroup rootView = (ViewGroup) inflater.inflate(

                R.layout.activity_image_upload, container, false);

return rootView;

}

Vuelvo a repetir, no le voy a dar acción, solo quiero que veáis como hace slide al pasar el dedo.

ViewPagerExampleActivity

Bien, esta clase es la importante, la que nos va a hacer funcionar. Podéis observar que esta clase hereda deFragmentActivity. Esta clase formara una activity con todos los fragments que le pasemos.

Primero declaramos nuestro ViewPager y nuestro PageIndicator

private ViewPager pager = null;

private PageIndicator mIndicator;

Page 47: Android Webservices

Posteriormente, en el método onCreate(), y a continuación de referenciar nuestro ViewPager con el archivo xml, le damos una animación con el método setPageTransformer, donde le pasaremos por parámetro un booleano y nuestra clase DepthPageTransformer():

this.pager.setPageTransformer(true, new DepthPageTransformer());

A continuación creamos un objeto de nuestro adapter MyFragmentAdapter, y le pasamos por argumentosgetSupportFragmentManager() para obtener el soporte de la aplicación y mostrar posteriormente nuestrosfragments, y el contexto (this)

MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(

                getSupportFragmentManager(),this);

Creamos un for para agregar 4 fragments a nuestro adapter.

for (int i = 0; i< 4; i++) {

        adapter.addFragment(ViewPagerFragment.newInstance());

        this.pager.setAdapter(adapter);

}

Podéis ver que al añadir un fragment utilizamos el método static creado en el fragmentanterior

Finalmente referenciamos nuestro PageIndicator con nuestro xml y le agregamos nuestro viewpager para que pueda ponerles titulo.

mIndicator = (TitlePageIndicator)findViewById(R.id.indicator);

mIndicator.setViewPager(pager);

Bien, esto es todo, si habéis seguido bien los pasos, se os tienen que ir deslizando los diferentes fragments con su titulo mientras pasáis con el dedo.

Aquí os dejo los archivos: ViewPagerExample

Un saludo a todos.

Page 48: Android Webservices

SÁBADO, 31 DE MAYO DE 2014

Android: Integrar Google Map en nuestra aplicaciónBuenas amigos, en este nuevo tema vamos a ver como integrar la API de GoogleMaps en nuestra aplicación android. Bien, es un tema un poco complejo, ya que tenemos que descargar librerías de nuestro sdk manager y obtener una clave de google, pero con paciencia y siguiendo los pasos cuidadosamente, lograremos integrar los mapas de google en nuestra app.

Lo primero que vamos a hacer es abrir nuestro SDK Manager para descargar una librería del repositorio degoogle.

Posteriormente nos vamos al final del todo, a la carpeta "extras" y marcamos "Google Play Services"

Pulsamos en "Install Packages" para instalar.

NOTA: Cuidado con instalar paquetes que no queráis, puede influir en el funcionamiento de eclipse.

Una vez descargada, vamos a agregarla como librería Android a nuestro proyecto:

Pinchamos sobre File/New/Other y elegimos "Android Project For Existing Code"

Page 49: Android Webservices

En la ventana que se nos abre, buscamos la ruta donde este nuestra librería "Google Play Services". Tenéis que ir a la carpeta donde tengáis vuestro sdk, y dentro seguir la ruta"sdk\extras\google\google_play_services\libproject\google-play-services_lib"

Una vez tengáis vuestra librería agregada, pincháis sobre vuestro proyecto y elegís "preferences", posteriormente, en la ventana que se abre, pincháis en "android" y abajo a la derecha podéis agregar la librería a vuestro proyecto

Page 50: Android Webservices

Una vez tengamos la librería, debemos registrar nuestra app y obtener una clave Google Maps para poder utilizarla en nuestra aplicación.

NOTA: Esto lo hace google para mantener cierto control, ya que una app que al utilizar más de 25.000 veces Google Mapsdebe de empezar a pagar una cantidad de dinero (pequeña) por cada vez que se utilice de más Google Maps. Esto no supone un problema para una persona con una app, pero si que lo es si 30.000 personas tienen la app y utilizan a menudoGoogle Maps.

Bien, para obtener una clave para utilizar Google Maps, necesitaremos un código cifrado en SHA-1 que nos proporciona el mismo eclipse:

Pinchamos en eclipse en "window/preference" y en la ventana que se abre, pinchamos en "Android/build"

Page 51: Android Webservices

Bueno, ahi os aparecerá vuestro código en SHA-1, lo copiáis en un bloc de notas, para utilizarlo posteriormente.

Ahora, vamos a ir a Google Developer Console  

Una vez en la pagina, pincháis sobre "API Access" y posteriormente pincháis sobre "Create new Android Key"

En esta nueva ventana que se abre debéis poner vuestro código SHA-1 seguido de punto y coma ";" y el nombre de nuestro proyecto, quedando de la siguiente forma:

XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX;com.example.picarcodigo (todo junto).

Pulsáis en "create" y ya os ha tenido que generar una key, os aparecerá en un cuadro similar a este.

Bueno, copiáis vuestra key en un bloc de notas para utilizarla posteriormente, vamos a generar algo de código.

Page 52: Android Webservices

Lo primero que debemos hacer cuando creemos nuestro proyecto es agregar permisos a nuestra aplicación:

android.permission.INTERNET

android.permission.ACCESS_NETWORK_STATE

android.permission.WRITE_EXTERNAL_STORAGE

com.google.android.providers.gsf.permission.READ_GSERVICES

android.permission.ACCESS_COARSE_LOCATION

android.permission.ACCESS_FINE_LOCATION

Posteriormente agregamos la siguiente linea de código:

Google Maps utiliza OpenGl para renderizar mapas, si no tenéis instalado OpenGl, es

obligatorio ponerlo.

Ahora, continuando con nuestro manifest, debajo de donde tengamos declarada nuestra

activity, añadimos 2 meta-data.

Page 53: Android Webservices

En "android:value" del primer meta, pegáis, entre comillas, vuestra clave, quedando de

la siguiente manera

Con esto ya, podemos trabajar con Google Maps en nuestra app.

Bien, ahora vais a vuestro archivo xml y agregáis lo siguiente:

Bien, esto no necesita mucha explicación, un fragment donde nos cargará nuestro mapa.

Vamos a ir ahora a nuestra clase para darle funcionalidad.

Page 54: Android Webservices

Bien, en código, como podéis observar, no es difícil:

Referenciamos nuestro xml

setContentView(R.layout.activity_maps_example);

Referenciamos el fragment de nuestro xml mediante la clase

"SupportMapFragment"

SupportMapFragment fm = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);

Pasamos nuestro "SupportMapFragment" a la clase GoogleMap para poder

manejar los mapas

GoogleMap map = fm.getMap(); 

Creamos un objeto de la clase LatLng (Latitud y Longitud) para introducir

coordenadas (Google Maps trabaja con coordenadas) que introduciremos posteriormente en

nuestro mapa

LatLng murcia = new LatLng(38.00, -1.12);

Activamos nuestra localización

map.setMyLocationEnabled(true);

Le pasamos las coordenadas y el zoom que nos va a mostrar, en mi caso, 2.0f

(float)

map.moveCamera(CameraUpdateFactory.newLatLngZoom(murcia, 2.0f));

Page 55: Android Webservices

Finalmente, añadimos un marcador de posición

map.addMarker(new MarkerOptions()

                .title("Murcia")//Titulo de nuestro marcador

                .snippet("Picarcodigo.blogspot.com")//Informción

                .position(murcia));//Posición.

Bien, si habéis seguido bien los pasos no debéis de tener ningún problema.

Page 56: Android Webservices

LUNES, 30 DE JUNIO DE 2014

WebService: Obtener datos mysql desde Android con JSONBuenas amigos, llevo un tiempo desaparecido ya que estoy realizando un proyecto que, afortunadamente, ya está en fase de testeo, y hasta nueva orden voy a estar un poco parado, así que voy a realizar nuevas entradas y a contestar todos aquellos emails que me han enviado con sus dudas, tengan paciencia les llegará a todos. Dicho esto, estuvimos hablando en un tema anterior como mostrar datos de una base de datos mysql en nuestra aplicación sin utilizar JSON. Bien, en este nuevo tema veremos lo mismo pero utilizando JSON.

Para comenzar, ¿Que vamos a utilizar?:

Un servicio Apache con Mysql

Un WebService

Una clase "Personas" para almacenar datos

Una clase Main para ejecutarlo todo.

NOTA: Al final del post os daré los archivos.

Bien, como ya he dicho en temas anteriores no voy a comentar como crear un servicio Apache ya que me quedaría muy extenso el tutorial, buscar en google, hay a patadas.

Antes de continuar decir que voy a trabajar con una tabla "Personas" con 4 campos (dni, nombre, telefono, email).

Comenzaremos creando nuestro WebService:

Page 57: Android Webservices

Lo primero es meter la información de nuestro servidor:

Hostname: Nombre del host.

Database: Nombre de nuestra base de datos.

Username: Nombre de usuario del servidor.

Password: Contraseña del servidor.

Posteriormente nuestro WebService intentará conectar al servidor, enviando un informe de error en caso de no poder conectar:

 $localhost=mysql_connect($hostname_localhost,$username_localhost,$password_localhost)

or trigger_error(mysql_error(),E_USER_ERROR);

Una vez conectado al servidor, intentará conectar con nuestra base de datos

mysql_select_db($database_localhost, $localhost);

Luego, creamos una sentencia sql para que obtenga todos los datos del servidor.

$query_search = "select * from personas order by dni";

Ejecuta la sentencia sql:

$query_exec = mysql_query($query_search) or die(mysql_error());

Creamos una variable llamada "json" que tendrá formato de Array.

$json=Array();

Creamos una sentencia condicional "if" y le agregaremos el método mysql_num_rows(), al que le pasaremos por parámetro la ejecución de la sentencia sql, comprobando si la tabla está vacía o no.

if(mysql_num_rows($query_exec))

Page 58: Android Webservices

Si tenemos filas en nuestra tabla, se ejecutará un bucle "while" donde por medio del método mysql_fetch_associremos almacenando las filas en la variable $row

while($row=mysql_fetch_assoc($query_exec))

Y se lo pasamos a nuestra variable $json para que lo almacene para posteriormente enviárselo a nuestra app.

$json['personas'][]=$row;

Cerramos la conexión con el servidor

mysql_close($localhost);

Imprimimos por medio de echo nuestro $json con ayuda del método json_encode.

echo json_encode($json);

Ahora vais a vuestro navegador y comprobáis que funciona, introduciendo la url del "selectAllJSON.php" (así se llama mi webservice).

En mi caso la url sería: http://localhost/picarcodigo/selectAllJSON.php

Y lo que me imprime por pantalla sigue el formato JSON:

{"personas":[{"nombre":"Bartolome Abellan","dni":"55578932Z z","telefono":"555789000","email":"[email protected]"},{"nombre":"cgghj","dni":"ghjj","telefono":"3689","email":"ghjkog"},{"nombre":"ghkjf","dni":"hdguj","telefono":"5699","email":"gghk"}]}

Bien, ya tenemos listo nuestro WebService con JSON integrado veamos como quedará nuestra app.

Lo primero es crear una clase "Personas" en las que almacenaremos los datos de cada persona:

Page 59: Android Webservices

NOTA:No voy a explicar esta clase, si no sabes que hace o cual es su función, debes estudiar más, es algo básico.

Page 60: Android Webservices

Voy a trabajar en mi app con esta interfaz, la cual pasaré al final del post.

Bien, ya tenemos nuestro webservice y sabemos con que interfaz trabajar, vamos a ver código java.

Nuestra clase principal contendrá los siguientes métodos: String mostrar(): Método que realizará la conexión a nuestro servidor por WebService, obteniendo un objetoString como resultado

boolean filtrarDatos(): Este método obtendrá el objeto String del método mostrar() y lo filtrará por diferentes clases JSON rellenando objetos de tipo Personas que almacenaremos en un ArrayList. Parece complejo, pero no lo es, ya lo veréis.

void mostrarPersonas(int Position): Nos cargará y mostrará los datos de las personas almacenadas en determinadas posiciones de nuestro ArrayList.

String convertStreamToString(InputStream is): Este método convertirá objetos de tipo InputStream en objetos de tipo String.

Todo esto ejecutado desde una clase AsyncTask.

Page 61: Android Webservices

Instanciamos HttpClient y HttpPost para comunicarnos con nuestro Webservice.

HttpClient httpclient=new DefaultHttpClient();

HttpPost httppost=new HttpPost("URL DE NUESTRO WEBSERVICE EN EL SERVIDOR");

Creamos una variable local de tipo String llamada resultado, esta almacenará la respuesta.

String resultado="";

Implementamos la interfaz HttpResponse para obtener el resultado de ejecutar httpclient.

response = httpclient.execute(httppost);

Implementamos la interfaz httpEntity para procesar la respuesta obtenida en HttpResponse.

HttpEntity entity = response.getEntity();

Utilizamos la clase InputStream para convertir los datos entity a byte.

InputStream instream = entity.getContent();

Le damos a nuestra variable "resultado" el valor de convertir los bytes de InputStream a String por medio del método convertStreamToString(InputStream is).

resultado= convertStreamToString(instream)

Finalmente devolvemos nuestra cadena con los datos

return resultado;

Aquí podéis ver lo que hace el método convertStreamToString(InputStream is):

Page 62: Android Webservices

Este método no lo he creado yo, lo he cogido de internet, los hay a patadas y es la mejor solución para pasar datos de unInputStream a String, es muy sencillo.

 Bien, hemos leído nuestro WebService y hemos almacenado su valor en la variable resultado, ahora vamos a pasarlo ese resultado por nuestro método filtrarDatos().

Limpiamos nuestro ArrayList, por si tuviese algo de información.

listaPersonas.clear();

Page 63: Android Webservices

Creamos una variable de tipo String "data" donde almacenaremos el resultado obtenido al ejecutar la conexión al servidor

String data=mostrar();

Realizamos una condición "if" por si data está vacío

if(!data.equalsIgnoreCase(""))

 Creamos un objeto JSONObject donde le pasaremos por constructor la información que obtuvimos de nuestroWebService almacenada en la variable de tipo String "data".

JSONObject json = new JSONObject(data); 

Posteriormente pasamos JSONObject a JSONArray, indicándole por parámetro el nombre del array de nuestroJSON, en nuestro caso "persona".

JSONArray jsonArray = json.optJSONArray("personas"); 

Una pequeña pausa, puedes observar en el WebService que he creado que al json le daba un nombre de parámetro:

$json['personas'][]=$row;

Ese nombre, que va entre comillas simples y corchetes (personas), es la referencia que le hago a JSONArray en su parámetro. Si se llamase coche, yo tendría que poner coche en el parámetro JSONArray.

Bien, con esto tendríamos almacenado en JSONArray diferentes objetos JSON, cada uno con la información de cada fila de nuestra tabla, por lo que para ir recorriendo cada uno deberíamos utilizar un for, ya que en su esencia, lo que vamos a hacer es recorrer un array.

for (int i = 0; i < jsonArray.length(); i++)

Una vez dentro del for, crearemos un objeto de tipo persona con cada ciclo del for

personas=new Persona();

Crearemos un objeto de tipo JSONObject por cada ciclo, recogiendo así todos los datos que tenemos almacenados en JSONArray.

JSONObject jsonArrayChild = jsonArray.getJSONObject(i);

Una vez hecho esto, sería ir dándole a cada atributo de personas su correspondiente valor

personas.setDni(jsonArrayChild.optString("dni"));

personas.setNombre(jsonArrayChild.optString("nombre"));

personas.setTelefono(jsonArrayChild.optString("telefono"));

personas.setEmail(jsonArrayChild.optString("email"));

Fijaos bien que cuando llamo a jsonArrayChild.optString("dni"), le vamos a pasar a personas el valor almacenado en dni, e igual para los otros casos

Posteriormente agregamos el objeto personas a nuestro ArrayList

listaPersonas.add(personas);

Con esto ya tendríamos los datos de nuestro servidor almacenados en objetos de tipo personas que a su vez están almacenados en un ArrayList, listos para ser mostrados por pantalla, lo cual haremos con el método mostrarPersona();

Page 64: Android Webservices

Bien, este método no tiene mucha explicación, leo los objetos almacenados en nuestro ArrayList en la posición que se le pasa por parámetro y lo muestro en los Edittext.

Para ejecutarlo todo utilizaremos una clase AsyncTask

Y ejecutaremos nuestro AsyncTask al pulsar el botón mostrar:

Y, como opcional, para movernos entre nuestro datos, podéis agregar los botones "siguiente" y "previo"

Page 65: Android Webservices

Lo único que hacen estos últimos es sumar 1 a posición (mas) o restar 1(menos)

NOTA: Agregar permisos de Internet si no lo tenéis agregado.

Archivos para descargar: WebServiceJSONExample

Si tenéis dudas u os atascáis en algo, preguntar.

Un saludo

Page 66: Android Webservices

JUEVES, 16 DE OCTUBRE DE 2014

Tareas en 2º plano Android (Parte I): Clase AsyncTaskBuenas amigos, en este nuevo tema vamos a ver como manejar hilos en segundo plano en nuestra aplicación por medio de la clase AsyncTask. Esta clase nos permitirá ejecutar acciones en segundo plano como lo hacían en java los threads.

Bien, si eres nuevo en android pero conoces java es posible que te resulte un poco complejo entender el sistema de hilos, ya que es totalmente diferente a como creábamos un hilo en java, pero nada más lejos de la realidad, veréis que, explicando una sencillas reglas y mostrando las diferentes fases por la que pasa un hilo en android, es tan fácil de entender como un hilo en java.

Bueno, las reglas básicas para crear una clase AsyncTask en android son:

La clase AsyncTask se debe crear como una clase interna de la clase donde

deseamos crear nuestro hilo.

NOTA: No os fijéis en los componentes, solo en que es una clase interna. La clase AsyncTask se instancia en nuestro hilo principal, es decir, fuera del AsyncTask.

Page 67: Android Webservices

Para iniciar nuestro AsyncTask, debemos de invocar el método execute() de la propia clase.

Con esto, ya sabemos hacer que nuestra clase AsyncTask se ejecute en 2º plano, ahora

vamos a ver las fases por las que pasa nuestro AsyncTask una vez empieza a

ejecutarse:

La clase AsyncTask tiene varios métodos que podemos sobreescribir en los que

podemos definir:

Page 68: Android Webservices

Que hacer antes de iniciar la tarea en 2º plano

Que hacer durante la tarea en 2º plano

Que hacer después de ejecutar la tarea en segundo plano.

Veamoslos: onPreExecute(): Este método realiza las acciones que le indiquemos antes de iniciar la tarea en 2º plano.

doInBackground(Params...): Este método es el método principal de nuestro AsyncTask. Es el encargado de ejecutar nuestro código en 2º plano. Es obligatorio ponerlo, si no lo ponéis, os coses a errores y warning

onPostExecute(Result...): Este método realiza las acciones que le indiquemos después de ejecutar la tarea en segundo plano.

onCancelled(): Este método cancela nuestro AsyncTask.

onProgressUpdate(progres...): Va recogiendo el progreso de nuestro AsyncTask.

Bien, estos métodos no se invocan fuera del AsyncTask, son internos, nosotros para

ejecutarlos solo debemos invocarexecute() y la propia clase los va ejecutando.

Page 69: Android Webservices

Bueno, una cosa que aún no he comentado es el uso de genéricos en esta clase (Si no

estas seguro de lo que son los genéricos te recomiendo dos cosas: 1º visitar este enlace y

lo 2º es que estudies más el temario básico de java).

Podéis observar que después de heredar de AsyncTask coloco 3 tipos de genéricos,

bien, esto va a ser el tipo de devolución de nuestros métodos (String, Integer, Float....),

aunque si pongo Void, le estoy indicando que no quiero tener ningún tipo de retorno, ya

sabéis que los métodos tipo void, no retornan nada. El primer genérico nos indica el tipo de devolución que tendrá el método onPostExecute()

El segundo genérico nos indica el tipo de devolución que tendrá el método onProgressUpdate()

El tercer genérico nos indica el tipo de devolución que tendrá el método doInBackground().

Otra cosa que quiero dejar clara, es los parámetros que tienen algunos métodos de esta

clase, por ejemplo, el métododoInBackground tiene su argumento formado de la

siguiente manera (Void...params), esto quiere decir que acepta cualquier número de

valores, desde ninguno hasta los que necesitemos. En caso de de llevar cierto numero de

valores, se deberían de cargar como un array: params[0], params[1], etc

A estos métodos se les llama "métodos con argumentos variables" y es algo que

deberíais conocer.

Bien amigos, este tema no tiene mucha más historia, si tenéis alguna duda u os atascais

en algo, preguntar.

Un saludo.

Page 70: Android Webservices

JUEVES, 16 DE OCTUBRE DE 2014

Tareas en 2º plano Android (Parte II): Clase TimerTaskBuenas amigos, en el tema anterior estuvimos hablando de como realizar una tarea en segundo plano con la ayuda de la claseAsyncTask. En este nuevo tema vamos a ver como funciona la clase TimerTask y sus diferencias con AsyncTask y nos va a resultar menos compleja de entender ya que nos va a resultar más familiar que AsyncTask.

Bien, esta clase se caracteriza por hacer repeticiones del hilo continuamente cada X segundos, es decir, funciona como un temporizador pudiendole indicar cuando queremos que inicie y cada cuanto tiempo queremos que se repita, estas repeticiones van a ser infinitas, es decir, una vez ejecutemos el hilo no parará de ejecutarse hasta que nosotros se lo indiquemos

Anteriormente, en java, para hacer esto con los threads, creabamos un bucle infinito (while, for...) y por medio del métodosleep() le indicabamos cada cuanto tiempo haciamos una repetición, bien, TimerTask funciona más o menos de la misma forma pero por si sola, no hace falta poner sleep() ni nada parecido.

Bien, sabiendo esto, una clase TimerTask se construye de la misma forma que una AsyncTask, es decir, como una clase interna:

Podemos observar, que efectivamente se construye como una clase interna de TimerExample y, a diferencia de AsyncTask, no utilizamos ni genéricos, ni métodos especiales que se ejecuten antes y/o después de realizar nuestra acción en segundo plano, aquí solo tenemos un método run() en el que poner nuestro código a ejecutar en segundo plano.

Page 71: Android Webservices

Una vez creada nuestra clase interna TimerTask, vamos a hacer que funcione, para ello vamos a utilizar la clase Timer.

NOTA: Una cosa antes de continuar, en lineas anteriores mencionabamos que TimerTask se encargaba de hacer repeticiones cada X segundos y que se iniciaba cuando nosotros se lo indicábamos, pues bueno, eso no es del todo cierto, quien realmente realiza esa función es la clase Timer, que vamos a ver ahora, TimerTask solo es el recipiente de nuestro código en segundo plano, pero realmente es Timer quien lo ejecuta. Recordarlo bien, ya que en lineas anteriores no os quería confundir y por eso hago esta aclaración ahora.

Bien, aclarado lo anterior, vamos a instanciar un objeto de la clase Timer y pasarle nuestro AsyncTask para ejecutar el hilo:

Page 72: Android Webservices

Creamos un atributo de la clase Timer:

       private Timer timer;

 En nuestro método onCreate() lo instanciamos:

                 timer=new Timer(); Creamos un objeto de nuestra clase AsyncTask:

               SubTimerExample sub=new SubTimerExample(); Ahora le pasamos al método scheduleAtFixedRate() de timer el TimerTask a ejecutar (sub), cuando lo queremos ejecutar (0) y cada cuanto tiempo se va a repetir en milisegundos (5000):

              timer.scheduleAtFixedRate(sub, 0, 5000);

Y ya está, con esto tenemos nuestro timer ejecutando a nuestro TimerTask cada X segundos, en caso de querer cancelar nuestra tarea en segundo plano utilizaremos los siguientes métodos de la clase Timer, OJO, es la clase Timer la que cancela el hilo, no la TimerTask:

void cancel(): Cancela nuestro timer:

              timer.cancel(); int purgue(): Remueve todos los timers cancelados de la pila de memoria. Importantisimo para controlar el consumo de memoria de nuestra app.

              timer.purge(); 

Estos 2 métodos junto con el método scheduleAtFixedRate(), son los más utilizados por esta clase.

Bien chicos, como podeis observar, estas clases son tan iguales como distintas, las Asynctask por un lado te permiten hacer más acciones mientras se ejecuta la tarea en segundo plano y nos viene bien para hacer Dialogs, ProgressDialogs y cosas así, mientras que Timer nos viene bien por si queremos actualizar nuestra activity cada X segundos, o hacer alguna comprobación de servidor cada X segundos, aunque para esto último es mejor usar los servicios, que explicaré pronto, aún así, sois vosotros los que finalmente decidiréis cual de las dos se adapta más a vuestra situación.

Bien amigos, eso es todo, si tenéis alguna duda u os atascais en algo, preguntar.

Un saludo.