Buenos días, en esta entrada veremos como podemos guardar una imagen en nuestra memoria interna del dispositivo que estemos usando.
La funcionalidad de guardar imágenes en nuestro terminal puede ser una buena idea para mantener datos y cargarlos mas tarde. Para ello aprovecharemos el tutorial anterior para descargar las imágenes que podemos encontrar Aquí
Usando el anterior tutorial bajaremos la imagen, la mostraremos, y en el botón que añadiremos a la GUI vamos a llamar al método para guardar nuestra imagen en una carpeta privada.
-
GUI
Cuando hayamos creado nuestro proyecto Android, modificaremos el XML para que quede así:
<RelativeLayout xmlns:android=http://schemas.android.com/apk/res/android xmlns:tools=http://schemas.android.com/tools android:layout_width=match_parent android:layout_height=match_parent tools:context=.MainActivity>; ImageView android:id=@+id/imagen android:layout_width=wrap_content android:layout_height=wrap_content android:layout_alignParentTop=true; Button android:id=@+id/btnGuardar android:layout_width=wrap_content android:layout_height=wrap_content android:text=@string/txtGuardar android:layout_alignParentBottom=true android:layout_centerHorizontal=true; </RelativeLayout>
Con este xml lograremos una interfaz gráfica como la siguiente:
Como vemos, es una Interfaz gráfica de lo mas normal y sin ningún tipo de dificultad, para el propósito que queremos no necesitamos mucho mas.
-
Activity
La activity es prácticamente la misma que en el tutorial anterior, aunque aún no agregaremos la funcionalidad para guardar la imagen:
public class MainActivity extends Activity { public static final String URL = http://www.thebiblescholar.com/android_awesome.jpg; private ImageView imgImagen; private Button btnGuardar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imgImagen = (ImageView)findViewById(R.id.imagen); btnGuardar = (Button)findViewById(R.id.btnGuardar); CargaImagenes nuevaTarea = new CargaImagenes(); nuevaTarea.execute(URL); } private class CargaImagenes extends AsyncTaskString, Void, Bitmap&gt;{ ProgressDialog pDialog; @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); pDialog = new ProgressDialog(MainActivity.this); pDialog.setMessage(Cargando Imagen); pDialog.setCancelable(true); pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); pDialog.show(); } @Override protected Bitmap doInBackground(String... params) { // TODO Auto-generated method stub Log.i(doInBackground , Entra en doInBackground); String url = params[0]; Bitmap imagen = descargarImagen(url); return imagen; } @Override protected void onPostExecute(Bitmap result) { // TODO Auto-generated method stub super.onPostExecute(result); imgImagen.setImageBitmap(result); pDialog.dismiss(); } } private Bitmap descargarImagen (String imageHttpAddress){ URL imageUrl = null; Bitmap imagen = null; try{ imageUrl = new URL(imageHttpAddress); HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection(); conn.connect(); imagen = BitmapFactory.decodeStream(conn.getInputStream()); }catch(IOException ex){ ex.printStackTrace(); } return imagen; } }
-
Button
En el elemento Button añadiremos un OnClickListener(), en el cual añadiremos la funcionalidad deseada.
btnGuardar.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub Bitmap imagen = ((BitmapDrawable)imgImagen.getDrawable()).getBitmap(); String ruta = guardarImagen(getApplicationContext(), imagen, imagen); Toast.makeText(getApplicationContext(), ruta, Toast.LENGTH_LONG).show(); } });
En el método onClick() tenemos 3 líneas, las cuales van a realizar lo deseado. Primero creamos un objeto de la clase Bitmap, en el cual mediante un cast a la clase BitmapDrawable podremos coger la imagen que hemos establecido en el ImageView. Este paso podríamos habernoslo ahorrado si hubieramos hecho todo el proceso en la AsyncTask, pero con esto podemos saber una de las maneras que hay de poder conseguir la imagen que tenemos establecida en los ImageView.
Lo siguiente es la creación de un objeto del tipo String, donde le asignaremos el valor de retorno que nos retorne el método guardarImagen(), al cual le pasamos 3 parámetros:
- Context: la información de la aplicación.
- “imagen”: Esto no es mas que el nombre que le aplicaremos al archivo de la imagen que creemos, en este caso la he llamado “imagen”, pero perfectamente podríamos haber capturado algún nombre mediante un Dialog o un TextView.
- imagen: Es el objeto Bitmap que hemos creado y hemos recogido del ImageView.
Ahora procedemos a analizar el método guardarImagen() y lo que realiza:
-
Método guardarImagen()
El método guardarImagen() es el siguiente:
private String guardarImagen (Context context, String nombre, Bitmap imagen){ ContextWrapper cw = new ContextWrapper(context); File dirImages = cw.getDir(Imagenes, Context.MODE_PRIVATE); File myPath = new File(dirImages, nombre + .png); FileOutputStream fos = null; try{ fos = new FileOutputStream(myPath); imagen.compress(Bitmap.CompressFormat.JPEG, 10, fos); fos.flush(); }catch (FileNotFoundException ex){ ex.printStackTrace(); }catch (IOException ex){ ex.printStackTrace(); } return myPath.getAbsolutePath(); }
Como vemos recibimos 3 parámetros, Context, String que es el nombre de la imagen y Bitmap que es la imagen.
En este método lo que hacemos en un principio es crear unn objeto de la clase ContextWrapper con el cual extraeremos el directorio privado de nuestra aplicación en nuestro terminal.
A continuación, mediante objetos del tipo File creamos las rutas, en el primer caso, si observamos la línea:
File dirImages = cw.getDir(Imagenes, Context.MODE_PRIVATE);
Estamos consiguiendo la ruta de nuestra aplicación, creando consigo una carpeta llamada “Imagenes”, la cual hacemos privada, por lo que solo nuestra aplicación podría acceder a ella.
En el siguiente caso estamos creando la ruta de nuestra imagen, en la cual usaremos la del objeto dirImages concatenada con el nombre de nuestra imagen y su extensión “.png”.
A continuación creamos un objeto de la clase FileOutputStream, el cual se encargará de crear un flujo de salida que escribe bytes en un archivo, aunque lo inicializamos a null, ya que llamaremos al constructor dentro de un bloque try-catch para manejar las excepciones que pueda dar.
En el bloque Try-catch, construimos el objeto FileOutputStream, pasandole como argumento el objeto File que creamos con anterioridad, en este caso myPath, ya que contienela ruta completa a nuestra imagen. Si la ruta ya existiera, podríamos reemplazarla o añadirla.
A continuación mediante el método compress de la clase Bitmap, elegimos un formato de compresión, la calidad de la imagen mediante un int, y pasamos como último argumento el objeto que hemos creado de al clase FileOutputStream. Por último, limpiamos el buffer de salida.
Por último retornamos la ruta de la imagen en el terminal, que luego visualizaremos.
-
AndroidManifest.xml
No debemos olvidarnos de agregar el permiso de uso de Internet a la aplicación, porque si no lo hacemos tendremos un error, para ello abrimos el archivo AndroidManifest.xml ubicado en nuestro directorio raiz del proyecto y agregamos la siguiente linea de código:
<uses-permission android:name=android.permission.INTERNET/>;
-
Consultar archivo guardado
Para consultar si el archivo ha sido bajado debemos abrir la perspectiva DDMS de Eclipse, para ello, vamos a Window/Other Perspective/Other, buscaremos en la lista DDMS y aceptaremos.
Una vez abramos esta perspectiva en la ventana de la izquierda pulsamos sobre el emulador en funcionamiento. A continuación, en la derecha, pulsamos sobre “File Explorer”, como veremos en las siguientes imágenes;
A continuación, nos vamos al directorio “data”:
Buscamos el nombre del paquete de nuestro proyecto y lo abrimos, donde encontraremos la carpeta que hemos creado, con el nombre modificado, pero que aunque sea diferentes, en el código seguirá siendo “Imagenes” como definimos:
Una vez ya elaborados estos pasos, podríamos ejecutar nuestra aplicación y probarla:
Aquí una screenshot con el resultado final:
Aquí un video de la aplicación en ejecución:
Sin más, espero que sea de ayuda a quien busque una manera de almacenar imágenes, ya sean descargadas de internet u otros métodos, en la memoria interna del teléfono, en la próxima entrada veremos como guardarlas en la tarjeta SD o memoria externa del teléfono.
Cualquier aporte o corrección son bienvenidos!.
Saludos!!!