Leyendo servicios web desde Android: JSON

Buenas, estas dos semanas anteriores vimos como instalar en Ubuntu un entorno de desarrollo para PHP y MySQL y luego creamos nuestro primer servicio web para poder leerlo desde cualquier dispositivo (Android, IPhone, otro sitio web...). La semana pasada nos quedó pendiente ver como utilizar este servicio web en una aplicación Android, así que vamos allá.



En el ejercicio de esta semana lo que vamos a hacer es conectarnos a nuestro servidor, leeremos y parsearemos el JSON que nos devuelva y por último lo guardaremos en base de datos en nuestro dispositivo.


Para los que no tenéis un servidor donde realizar las pruebas no os preocupéis, con vuestro dispositivo y un router wifi podéis probarlo sin problema.

Empezamos. Lo primero que haremos es abrir Eclipse. En un proyecto nuevo crearemos una nueva clase llamada JSONManager la cual va a tener el siguiente método static y public:



 public static JSONObject getJSONfromURL(String url){
     InputStream is = null;
     String result = "";
     JSONObject json = null;
      try{
         HttpClient httpclient = new DefaultHttpClient();
         HttpPost httppost = new HttpPost(url);
         HttpResponse response = httpclient.execute(httppost);
         HttpEntity entity = response.getEntity();
         is = entity.getContent();
     }catch(Exception e){}

      try{
         BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
         StringBuilder sb = new StringBuilder();
         String line = null;
         while ((line = reader.readLine()) != null) {
             sb.append(line + "\n");
         }
         is.close();
         result=sb.toString();
     } catch(Exception e){}

     try{
         json = new JSONObject(result);
     }catch(JSONException e){}

      return json;
 }


El método se conectará a la URL que le indiquemos y tratará de leer y parsear la respuesta en un objeto JSONObject. La primera parte del método abre la conexión http y obtiene la respuesta en un InputStream. La segunda parte, lee la respuesta y la parsea con un objeto BufferedReader para poder finalmente pasarla a un String. Este String es necesario en la tercera parte para crear un nuevo objeto JSONObject que será lo que vamos a devolver finalmente.


Para la siguiente parte creamos una nueva clase, la cual voy a llamar JSONParserLibros. Esta clase se va a encargar de leer el servicio ayudado del método anterior y guardar en base de datos. Veamos que es lo que hace.



private Activity activity;
private JSONObject jObject; 
private ProgressDialog progressDialog = null;
private Runnable runReadAndParseJSON;

public JSONParserLibros(Activity a){
   activity = a;
}

public void readAndParseJSONLibros() throws JSONException{
   runReadAndParseJSON = new Runnable() {
      @Override
      public void run() {
       try{
          readJSONLibros();
       } catch(Exception e){}
      }
   };
   Thread thread = new Thread(null, runReadAndParseJSON,"bgReadJSONLibros");
   thread.start();
   progressDialog = ProgressDialog.show(activity, "Descargando información", "Por favor espere",true);
}

private void readJSONLibros() throws JSONException{
   jObject = JSONManager.getJSONfromURL("http://192.168.1.87/android/service.libros.php");
   if(jObject != null)
          parseJSONLibros(jObject.getJSONArray("libros"));
   activity.runOnUiThread(returnRes);
}

private void parseJSONLibros(JSONArray librosArray) throws JSONException{
  for(int i = 0; i < librosArray.length(); i++){
     Libro l = new Libro();
     l.setIdLibro(librosArray.getJSONObject(i).getInt("id"));
     l.setTitulo(librosArray.getJSONObject(i).getString("libro"));
     l.setISBN(librosArray.getJSONObject(i).getString("isbn"));
     l.save(activity);
  }
}

private Runnable returnRes = new Runnable(){ 
 @Override 
 public void run() {
  progressDialog.dismiss();
 }
};


Como veis, tiene bastantes métodos, vamos a ver que hace cada uno. Lo primero que nos encontramos son variables y el contructor de la clase.

A continuación tenemos el método público que utilizaremos para llamar a nuestro servicio readAndParseJsonLibros. Este método crea un nuevo hilo de ejecución dentro del cual se va a hacer la llamada al servicio web, además se inicia una ventana de dialogo que avisará al usuario que se está haciendo una descarga.

La razón de hacerlo en un hilo de ejecución diferente es porque este es un proceso asíncrono que va a depender de diferentes factores como la velocidad de la conexión o de lo que tarde en responder el servidor.

El siguiente método readJsonLibros es private, y va a obtener el objeto JSON resultante de la llamada a nuestro servicio web mediante el método de la clase JSONMananger. Lo que hacemos a continuación es buscar el array de objetos json incluido dentro de libros. Aquí lo que vamos a tener es cada uno de los objetos json libro. Por último, se llama a un objeto Runnable definido al final de la clase que lo que va a hacer es cerrar la ventana de diálogo.


Como veis, he puesto una IP de una red local para hacer la llamada al servicio, esta corresponde al equipo donde he desarrollado el servicio web. En el momento de probar esto, si teneis un router wifi, deberéis activar la conexión wifi en vuestro dispositivo Android y conectaros a vuestra red local para que podáis tener acceso al servicio. En caso de no tener wifi teneis otras opciones como montar el servicio web en un servidor en internet, los datos se descargarán echando mano de vuestra conexión 3G , o también lo podeis probar con el emulador de Android.


Por último está el método parseJSONLibros, este simplemente recorre el array que obtuvimos antes, en cada una de las vueltas se a tener acceso a un objeto json libro, el cual tiene las propiedades: id, libro e isbn. Podemos acceder al objeto mediante librosArray.getJSONObject(i), donde i es la posición que queremos recuperar, y para acceder a las propiedades simplemente con getInt("nombre") o getString("nombre") dependiendo del tipo de dato que tengamos que recuperar.


Por último, en mi caso me he creado un objeto Libro, al cual seteo las propiedades correspondientes y llamo al método save para guardar en la base de datos de la aplicación. No os pongo como sería esta parte porque ya hemos tratado cómo guardar datos en base de datos SQLite también podéis ver el resultado de lo que habéis descargado leyendo los datos de la base de datos.


Para utilizar esta clase simplemente debereis crear una instancia del objeto JSONParserLibros y llamar al método readAndParseJSONLibros en la parte de vuestra aplicación que más os interese. Utilizada en el método OnCreate de una Activity quedaría de la siguiente forma:



JSONParserLibros json = new JSONParserLibros(this);
json.readAndParseJSONLibros();

Uno de los aspectos que debeis tener en cuenta también es la frecuencia con la que se actualizan vuestros contenidos, si los libros se actualizan de media cada 2 días lo que podeis hacer es guardar en las SharedPreferences la última fecha de actualización y en el método público readAndParseJsonLibros verificar que hayan pasado 2 días o más para llamar a vuestro servicio. Cada vez que hagais lectura reescribis esta fecha con la fecha actual.

Bueno, hasta aquí la última parte de esta serie de capítulos dedicados a los servicios web. Espero os sean de ayuda. Por último, os voy adelantando el tema de la semana que viene, como registrar visitas con Google Analytics en nuestra aplicación Android.

Comments are closed.