Guardar imágenes en la memoria interna del dispositivo

Cuando se instala una aplicación en un dispositivo, esta instala consigo una serie de directorios en la carpeta “data/data”, situada en el directorio raíz del dispositivo. Esto podemos verlo utilizando el Android Device Monitor. El directorio que se crea toma el nombre del nombre del paquete de nuestra aplicación y contiene en principio la carpeta “cache” y un archivo “libs”.

El botón de 'Android Device Monitor' es el del muñeco de Android, al lado del de Android SDK Manager

Andorid Device Monitor

El directorio personal de la aplicación está en '/data/data/nombreAplicación'

El directorio personal de la aplicación está en ‘/data/data/nombreAplicación’. En este caso, el paquete de nuestra aplicación se llama ‘tutoriales.codicatos.pruebaotto’

Nuestra aplicación puede guardar imágenes de uso exclusivo por la misma en un directorio personal dentro de esta carpeta llamado “files” y así disponer de ellos cuando los necesitemos. Por ejemplo, si desarrollamos una aplicación de dietética, tal vez necesitemos mostrar imágenes de alimentos. En este caso, guardaríamos las imágenes en este directorio y así las tendríamos siempre a mano.
 
No hace falta mencionar que las imágenes deben ser de un peso lo más reducido posible, ya que si no, llenaremos la memoria del dispositivo rápidamente, impidiendo al usuario poder seguir descargando aplicaciones.

Paso a paso

A continuación veremos cómo guardar imágenes desde nuestro directorio de recursos en la memoria interna y cómo obtenerlas y eliminarlas.

  1. Conversión de Bitmap a byte[]
  2. Guardar en la memoria interna
  3. Extraer de la memoria interna y usar
  4. Eliminar de la memoria interna

1. Conversión de Bitmap a byte[]


La conversión de las imágenes a byte[] es imprescindible para poder hacer operaciones con ellas. El siguiente trozo de código nos muestra cómo obtener un Bitmap a partir de una imagen que tengamos guardada en la carpeta “assets” de nuestro proyecto (“app/src/main/assets”).
Consiste en abrir un flujo de entrada (InputStream) hacia el archivo de la carpeta “assets” y convertirlo en Bitmap con el método decodeStream() de BitmapFactory. Tendremos que capturar una posible IOException.

A continuación, crearemos un flujo de salida de byte[] (ByteArrayOutputStream) y lo usaremos para cargar en este el Bitmap comprimido y después obtener el byte[].

Ya disponemos del byte[]. El Bitmap a partir del cual lo hemos creado nos ha podido llegar verdaderamente de un servicio web o tal vez la aplicación lo obtenga desde alguna dirección o através de la cámara de fotos.

2. Guardar en la memoria interna


Ahora ya podemos guardarlo en la memoria interna de la misma manera que se guarda cualquier otro byte[]. Crearemos un flujo de dalida de archivos (FileOutputStream) hacia un archivo en el directorio “files”. Si el directorio o el archivo no existen (como es el caso), se crearán automáticamente. Abrir un flujo de salida de archivos crea el archivo automáticamente o usa uno ya existente con el mismo nombre. A este flujo le diremos que escriba nuestro byte[] y luego lo cerraremos. Tendremos que capturar una FileNotFoundException y un IOException. Si nos da pereza, podemos capturar solamente Exception y utilizar instanceof.

El método openFileOutput() nos dará un objeto FileOutputStream hacia el archivo “imagen.gif” (si no existe lo creará) situado en el directorio de los archivos privados de la aplicación, cosa que le indicamos pasándole Context.MODE_PRIVATE como segundo argumento. Si ahora vamos al Android Device Manager podremos ver cómo se han creado el directorio y el archivo:

Estructura de archivos en el Andrid Device Monitor en la que se ve el archivo 'imagen.gif' dentro de la carpeta files del directorio de la aplicación

Archivo ‘imagen.gif’ guardado en ‘files’

Observa que, aunque la imagen tenía una extensión GIF, podíamos haberlo omitido, ya que al ser un byte[], la extensión no le afecta. Se guardará como un archivo txt.

3. Recuperar el archivo y usarlo


Recuperar el archivo consistirá en abrir un flujo de entrada de archivos (FileInputStream) apuntando hacia el archivo en concreto y convertirlo de nuevo en byte[] para después pasarlo a Bitmap.

Para indicarle la ruta al archivo hacia el que queremos abrir el flujo, usamos el método getFilesDir().getPath(), que nos dará la ruta al directorio “data/data/nuestraAplicación/files”, y le concatenamos una barra y el nombre del archivo que queremos recuperar. Luego obtenemos el Bitmap utilizando el método BitmapFactory.decodeStream() y lo cargamos en un ImageView.

4. Eliminar un archivo de “files”


Esta es la parte más sencilla. Consiste en crear un objeto File que apunte hacia el archivo que queremos eliminar y ejecutar sobre este el método delete(), que devolverá un booleano indicando si se ha eliminado el archivo o no.

Antes de eliminar el archivo, tal vez sea conveniente comprobar si este existe o no para no pensar que el método nos está dando fallos si recibimos un false cada vez que lo intentemos borrar, creyendo que el archivo está en el dispositivo cuando en realidad no lo está. Para ello solo tendríamos que ejecutar sobre el objeto File el método exists().

De esta forma todo queda mucho más claro. Es conveniente resaltar que mientras que al crear un FileOutputStream se crea el archivo en la ruta indicada si este no existe, al crear un File, si este no existe, sus atributos filePath y status valdrán null.

1 Comentario
  1. Renata 1 año

    Hola, ¿Me podríais decir como podría guardar una imagen o video proveniente de la cámara en la memoria interna?
    Se que se puede hacer con un File Provider, pero no termino de enterarme en las explicaciones en ingles.

    Gracias por la ayuda!

Contesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

©2017 Codictados Comunidad libre para el aprendizaje de codigo Online

o

Inicia Sesión con tu Usuario y Contraseña

o    

¿Olvidó sus datos?