Cómo descargar imagenes en Android

Buenas, la semana pasada vimos como ponerle bordes redondeados a una imagen y hacerla cuadrada, para el ejemplo de utilización de nuestro método utilizamos una imagen ubicada como recurso en la aplicación, y nos quedo pendiente ver como obtener las imágenes desde un repositorio en internet. Esta semana veremos como hacer esto.



Lo primero que debéis hacer antes de nada es darle permisos de internet a nuestra aplicación, esto lo hemos visto en artículos anteriores.


Ahora lo mejor es llevar los métodos que vamos a ver a una clase, yo me voy a crear una llamada ImageManager. Tambien veremos como hacer todo este proceso en un hilo de ejecución diferente del de la aplicación, de esta forma las imagenes se irán descargando y el resto de la aplicación seguirá ejecutandose. Veamos el contructor y las variables que hemos de definir.


private final Map<String, Drawable> drawableMap;

final Context context;

public ImageManager(Context c) {  
     drawableMap = new HashMap<String, Drawable>();
    context = c;
}


Hasta aquí todo es bastante sencillo, estamos definiendo un par de variables en la clase e inicializándolas en el constructor de la clase. Veamos ahora el método principal de la clase, el que se encargará de descargar la imagen.


public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
     
    
    final Handler handler = new Handler() {
 @Override
 public void handleMessage(Message message) {
       imageView.setImageDrawable((Drawable) message.obj);
 }
    };
 
    Thread thread = new Thread() {
  @Override
  public void run() {
      try{
          Drawable drawable = fetchDrawable(urlString);
          Message message = handler.obtainMessage(1, drawable);
          handler.sendMessage(message);
      } catch(Exception e){
          imageView.setVisibility(View.GONE);
      }
  }
    };
    thread.start(); 
}


Como veis el método no es muy extenso. Primero definimos nuestro handler que será el encargado de procesar los mensajes del nuevo hilo de ejecución cuando nuestra imagen se haya descargado y asignársela al ImageView.


Después definimos el hilo(thread), para el cual en un objeto Drawable descargaremos y convertiremos nuestra imagen con el método fetchDrawable, después asociamos el objeto drawable con nuestro handler y iniciamos el nuevo hilo con el método start.


 public Drawable fetchDrawable(String urlString) {
        if (drawableMap.containsKey(urlString)) {
            return drawableMap.get(urlString);
        }

        try {
            InputStream is = fetch(urlString);
            Drawable drawable = Drawable.createFromStream(is, "src"+urlString);
            if (drawable != null) {
                drawableMap.put(urlString, drawable);
                return drawable;  
            } else {
             return null;
            }         
        } catch (MalformedURLException e) {
           return null;
        } catch (IOException e) {
           return null;
        } catch (Exception e){
           return null;
        }
    }


El método fetchDrawable que os he puesto aquí se encarga de verificar si la URL que hemos indicado ya existe en drawableMap, el cual almacena pares llave/valor, y devuelve el drawable correspondiente en caso afirmativo.


Si no teniamos la imagen la descargamos con el método fetch el cuál nos devuelve un objeto de tipo InputStream a partir del cual crearemos el objeto drawable con el método estático createFromStream y lo almacenamos en drawableMap.


private InputStream fetch(String strURL) throws IOException{
 InputStream inputStream = null;
 URL url = new URL(strURL);
 URLConnection conn = url.openConnection();
 
 try{
  HttpURLConnection httpConn = (HttpURLConnection)conn;
  httpConn.setRequestMethod("GET");
  httpConn.connect();
 
  if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
   inputStream = httpConn.getInputStream();
  }
 }  catch (Exception ex){}
 return inputStream;
}



El método fetch se encarga de abrir una conexión HTTP mediante el método GET, obtener una respuesta y devolverla en un objeto de tipo InputStream.


Hasta aquí el código de nuestra clase, ahora solamente queda utilizarla en nuestra activity, podeis recolectar cualquier imagen de internet en cualquier página, por ejemplo la nuestra haciendo botón derecho y copiando la dirección, y con unos cuantos ImageView vereis como las imagenes se van descargando. Mientras tanto al descargarse en un hilo diferente podeis realizar otras acciones en vuestra aplicación. Os pongo un pequeño ejemplo de uso.


ImageView imageView = (ImageView) findViewById(R.id.image);
ImageManager imageManager = new ImageManager(this);
imageManager.fetchDrawableOnThread("http://.....", imageView);


Si queréis que estas imágenes tengan una permanencia más duradera en vuestra aplicación podéis guardarlas en la tarjeta SD del dispositivo.

Comments are closed.