sábado, 17 de septiembre de 2016

Descargar una imagen jpg de internet y guardarla.

En este artículo, como el título indica, se mostrará como descargar una imagen en formato jpg de internet (disponiendo de su url) y como guardarla en una carpeta en el almacenamiento externo del dispositivo.


Nota: este método solo sirve para imágenes de pequeño tamaño.


Para descargar la imagen de internet utilizaremos la siguiente clase:

private class DownloadImage extends AsyncTask {
  ProgressDialog pDialog;
  private String TAG = "DownloadImage";

  @Override
  protected void onPreExecute() {
      // TODO Auto-generated method stub
      super.onPreExecute();
      pDialog = new ProgressDialog(PrincipalActivity.this);
      pDialog.setMessage(getResources().getString(R.string.DescargandoImagen));
      pDialog.setCancelable(true);
      pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
      pDialog.show();
  }

  private Bitmap downloadImageBitmap(String sUrl) {
      Bitmap bitmap = null;
      try {
          InputStream inputStream = new URL(sUrl).openStream();   // Download Image from URL
          bitmap = BitmapFactory.decodeStream(inputStream);       // Decode Bitmap
          inputStream.close();
      } catch (Exception e) {
          Log.d(TAG, "Exception 1, Something went wrong!");
          e.printStackTrace();
      }
      pDialog.dismiss();
      // Aquí se puede añadir el compartir imagen
      // Aquí se puede añadir el establecer el fondo de pantalla
      return bitmap;
  }

  @Override
  protected Bitmap doInBackground(String... params) {
      return downloadImageBitmap(params[0]);
  }

  protected void onPostExecute(Bitmap result) {
      String date = (DateFormat.format("yyyyMMdd_hhmmss", new java.util.Date()).toString());
      saveImageExtPath(result,date + ".jpg","/tu_carpeta");
  }
}

Utiliza AsyncTask para que la descarga se produzca en segundo plano y no "paralizar" la aplicación durante el proceso de descarga de la imagen. Además se mostrará un ProgressDialog indicando dicho proceso.

Una vez descargada la imagen (onPostExecute) se llamará al procedimiento que guardará la imagen en el dispositivo externos (SD Card) saveImageExtPath();

Tiene tres parámetros:
  1. El primer parámetro es la imagen en formato bitmap resultado de la descarga de internet.
  2. El segundo parámetro es el nombre de la imagen guardada que está compuesto, en este caso, por la fecha y hora en formato yyyyMMdd_hhmmss.jpg aunque puede ser modificado por el que tu necesites.
  3. El tercer parámetro es la carpeta donde se guardará la imagen a partir del directorio raíz del almacenamiento externo.
El procedimiento es el siguiente:

public void saveImageExtPath(Bitmap bipmap, String nameImage, String path){
  FileOutputStream fileOutputStream = null;
  String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() + path;
  File dir = new File(file_path);
  if (!dir.exists()){
      dir.mkdirs();
  }
  File new_file = new File(dir,nameImage);
  try {
      fileOutputStream = new FileOutputStream(new_file);
      bipmap.compress(Bitmap.CompressFormat.JPEG,100,fileOutputStream);
      fileOutputStream.flush();
      fileOutputStream.close();
      // añade la imagen a la galería de fotos
      MediaScannerConnection.scanFile(this, new String[] { new_file.getPath() }, new String[] { "image/jpeg" }, null);
      Toast.makeText(getApplicationContext(),getResources().getString(R.string.mensajeImagenGuardada) + " " + path + "/" + nameImage + ")",Toast.LENGTH_LONG).show();
  } catch (FileNotFoundException e){
      e.printStackTrace();
  } catch (IOException e) {
      e.printStackTrace();
  }
}


Al final del proceso mostrará un mensaje (Toast) indicando que la descarga de la imagen se ha producido y l ruta donde se ha almacenado la imagen.

Para que se actualice la galería de imágenes de nuestro dispositivo se utiliza MediaScannerConnection.scanFile()

Para descargar una imagen y guardarla utiliza la sentencia:

new DownloadImage().execute(urlImagenJPG);

Para tener acceso a la memoria externa debemos añadir en el manifest.xml:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

 Si en vez de querer utilizar la memoria externa queremos utilizar la memoria interna podemos utilizar el método:

public void saveImage(Context context, Bitmap b, String imageName) {
 FileOutputStream foStream;
 try {
     foStream = context.openFileOutput(imageName, Context.MODE_PRIVATE);
     b.compress(Bitmap.CompressFormat.JPEG, 100, foStream);
     foStream.close();
 } catch (Exception e) {
     Log.d("saveImage", "Exception 2, Something went wrong!");
     e.printStackTrace();
 }
}

y para recuperar la imagen:

public Bitmap loadImageBitmap(Context context, String imageName) {
 Bitmap bitmap = null;
 FileInputStream fiStream;
 try {
     fiStream= context.openFileInput(imageName);
     bitmap= BitmapFactory.decodeStream(fiStream);
     fiStream.close();
 } catch (Exception e) {
     Log.d("saveImage", "Exception 3, Something went wrong!");
     e.printStackTrace();
 }
 return bitmap;
}


Otras acciones

Si queremos compartir la imagen guardada en el almacenamiento externo (conociendo la ruta completa de la imagen) podemos utilizar:

// Compartir la imagen guardada
File ruta_sd = Environment.getExternalStorageDirectory();
String name = rutaImagen;
File photoFile = new File(ruta_sd.getAbsolutePath(),name);
try {
   if (photoFile.exists()){
       Intent share = new Intent(Intent.ACTION_SEND);
       share.setType("image/jpeg");
       share.putExtra(Intent.EXTRA_TEXT,nombreWebcam);
       share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(photoFile));
       startActivity(Intent.createChooser(share,getResources().getString(R.string.CompartirImagen)));
       boolean deleted = photoFile.delete();
   }else {
       Toast.makeText(getApplicationContext(),getResources().getString(R.string.VuelveAIntentarlo),Toast.LENGTH_SHORT).show();
   }
} catch (Exception e){
   Log.e("Error Fichero","El fichero no existe");
}


Por último, si queremos añadir la imagen como fondo de pantalla de nuestro dispositivo:
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getBaseContext());
try {
  wallpaperManager.setBitmap(bipmap);
} catch (IOException e) {
  Log.e("Main", "Cant set wallpaper");
}


Fuentes:

1 comentario:

  1. Gracias al blog he logrado muchas veces descargar películas en iphone, porque así podré tener suficiente ayuda a encontrar la película que deseo.

    ResponderEliminar