Cómo enviar datos a un servidor en Android (III): recoger el resultado

Buenas, la semana pasada os hablé sobre el proyecto de software libre que se está empezando desde este blog y para el cual os pedimos vuestra colaboración. Había dejado para hablaros de este tema pendiente una serie sobre como enviar datos a un servidor web con Android, así que hoy vamos a finalizar esta serie.

Lo que haremos esta semana será una clase que se encargue de gestionar libros en Android, enviar desde Android una serie de datos y esperar a que nos lleguen. Una vez recibida la respuesta la parsearemos. Para ello vamos a crear una clase Libro que se encargará de enviar nuestros datos a un servidor. Veamos como queda:

public class Libro {

 private int idLibro = 0;
 private String titulo = "";
 private String isbn = "";
 public int getIdLibro() {return idLibro;}
 public void setIdLibro(int idLibro) {this.idLibro = idLibro;}
 public String getTitulo() {return titulo;}
 public void setTitulo(String titulo) {this.titulo = titulo;}
 public String getIsbn() {return isbn;}
 public void setIsbn(String isbn) {this.isbn = isbn;}
 
 private static String KEY_SUCCESS = "success";
 
 public void saveLibro(Activity activity){

      HttpClientManager httpclient = new HttpClientManager(activity);
      httpclient.addNameValue("idlibro", String.valueOf(getIdLibro()));
      httpclient.addNameValue("titulo", getTitulo());      
      httpclient.addNameValue("isbn", getIsbn());
      
      httpclient.setOnExecuteHttpPostAsyncListener(new OnExecuteHttpPostAsyncListener() {
    @Override
    public void onExecuteHttpPostAsyncListener(String ResponseBody) {
     try {
      JSONObject json = new JSONObject(ResponseBody);
      if (json.getString(KEY_SUCCESS) != null) {
       if((Integer.parseInt(json.getString(KEY_SUCCESS)) == 1)){
        if(json.has("libro")){
         parseJSONLibro(json.getJSONObject("libro"));
        }
        listenerAsyncPost.onFinishAsyncPost("Se ha guardado correctamente el libro");
       } else {
        listenerAsyncPost.onErrorAsyncPost("Se ha producido un error");
       }
      } else {
       listenerAsyncPost.onErrorAsyncPost("Se ha producido un error");
      }
     } catch (JSONException e) {      
      listenerAsyncPost.onErrorAsyncPost("Se ha producido un error");
     }     
    }

    @Override
    public void onErrorHttpPostAsyncListener(String message) {
     listenerAsyncPost.onErrorAsyncPost("Se ha producido un error " + message);
    }
   });      
      httpclient.executeHttpPost("Aquí la url de vuestro servicio");
  
 }
 
 private void parseJSONLibro(JSONObject jsonLibro) throws JSONException{
  setIdLibro(jsonLibro.getInt("id"));
  setTitulo(jsonLibro.getString("titulo"));
  setIsbn(jsonLibro.getString("isbn"));
 }
 
 public interface OnExecuteAsyncPostListener{ void onFinishAsyncPost(String message); void onErrorAsyncPost(String message); }
 public OnExecuteAsyncPostListener listenerAsyncPost;
 public void setOnExecuteAsyncPostListener(OnExecuteAsyncPostListener l){listenerAsyncPost = l;}
 
}


Veamos un poco esta clase. Lo primero que tenemos son un par de variables y propiedades básicas como el idLibro, Titulo e Isbn.

Vamos un momento hasta el final y vemos definido un listener listenerAsyncPost que nos servirá para avisarnos cuando haya terminado el envío y recepción de la información. El listener tendrá dos eventos, uno para cuando todo acabe correctamente y otro para cuando de un error y nos devolverá un String con un mensaje. Esto lo podeis complicar luego todo lo que querais.

Ahora si volvemos hacia arriba otra vez para revisar el método saveLibro. Si os acordais, en la primera semana hicimos una clase para enviar datos a una url por post, vamos a crear un objeto de este tipo HttpClientManager. Utilizaremos el método addNameValue para indicarle los parámetros que enviaremos por POST.

Luego definimos que es lo que vamos a hacer cuando se ejecute el post, para eso utilizamos el listener que creamos OnExecuteHttpPostAsyncListener.

Dentro de este puede ocurrir que todo se ejecute correctamente y nos devolverá un string con el resultado que puede ser un texto plano, un json, un xml o lo que vosotros querais devolver desde vuestro servidor, si el proceso falla devolverá un error con un mensaje.

Si os acordais, nosotros devolviamos un json (que no deja de ser un texto). Convertimos este texto a un objeto JSONObject y verificamos la variable "success", ya que aunque nos devuelva correctamente el json puede ser que no se haya insertado el libro.

Una vez verificado esto, si todo va bien, verifico que tengo un elemento "libro" en mi json y se lo paso a un método a parte parseJSONLibro que se encarga de leer los parámetros del elemento libro y setear las propiedades de mi objeto.

Lo más interesante es lo que se hace en el fin de cada rama de if, else y try. Siempre se llama al listener que creamos en esta clase según el caso, y se  le da un mensaje.

Finalmente, al final del método saveLibro ejecuto el método executeHttpPost del objeto HttpClientManager, y le paso la url del servicio web que creamos en la anterior entrega. OJO: yo aquí no pongo ninguna url para no liaros, así que aquí debeis poner vosotros la que corresponda según vuestro caso.

Esta clase ya está lista para ser utilizada, ahora nos falta ver como utilizarla. Ya vereis que esto es muy sencillo.

public class GuardarLibroActivity extends Activity {

 private Button btnGuardar;
 private Libro libro;


Lo primero que haremos será en una Activity, en este caso GuardarLibroActivity, definimos un botón y  un objeto de tipo Libro. Se supone que debeis tener un layout con un botón y que debeis inicializar el botón, lo cual también supondré que despues de unos meses leyendome ya sabreis hacer. En el onCreate a parte de inicializar el botón vamos a ver como setear el objeto Libro.


libro = new Libro();
libro.setIdLibro(1);
libro.setTitulo("el señor de los anillos");
libro.setIsbn("78w357897348957348597");
        
libro.setOnExecuteAsyncPostListener(new OnExecuteAsyncPostListener() {
   @Override
   public void onFinishAsyncPost(String message) {
      Toast.makeText(GuardarLibroActivity.this, message, Toast.LENGTH_LONG).show();  
   }
   
   @Override
   public void onErrorAsyncPost(String message) {
    Toast.makeText(GuardarLibroActivity.this, message, Toast.LENGTH_LONG).show();  
   }
  });
        
btnGuardar.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {    
    libro.saveLibro(GuardarLibroActivity.this);
   }
  });


Como podeis ver simplemente inicializo el objeto Libro, seteo sus propiedades y su listener para que me muestre un mensaje cuando finalice o de un error. En el evento onClick del botón simplemente llamo al  método saveLibro que iniciará el proceso de envío de información al servidor.

Yo lo he hecho muy simple aquí, dando los valores directamente al objeto libro, pero vosotros podeis poner un formulario donde el usuario tenga que rellenar los datos. Eso ya os lo dejo a vuestro gusto. Lo importante es que una vez tengais los datos sepais como enviarlos a un servidor para guardarlos y darle al usuario un feedback de como ha ido el proceso.

Bueno, hasta aquí esta serie. Espero que haya sido de ayuda. Esta semana no me voy a despedir sin volveros a recordar el proyecto de software libre que hemos empezado, ya tenemos decido que vamos a hacer un comparador de precios y en el grupo de Linkedin que hemos hecho ya se está hablando de él, de lo que queréis que se haga en el proyecto y más cosas.

No es necesario saber programar para ayudar. Podeis aportar ideas para el manejo, funcionalidades, diseños, ayudar con los precios para que el comparador sea lo más fiable posible. O simplemente contadselo a vuestros amigos si creeis que le puede interesar el proyecto.

Comments are closed.