Tip Android #05: utilizar el almacenamiento externo


VERSIONES

  1. 25/01/2013 (Primera publicación)
  2. 19/10/2013: Aplicación de ejemplo para Jelly Bean 4.3

  3. 25/01/2013
    android tip

    Para guardar ficheros en un dispositivo Android es muy tentandor simplemente utilizar “/sdcard/” para acceder a la tarjeta de almacenamiento externa, o al menos al directorio que el dispositivo considere como tal ya que hoy en día algunos dispositivos carecen de esta funcionalidad pero ofrecen parte del almacenamiento interno accesible al usuario como si de una tarjeta SD se tratara.

    Sin embargo, es una mala práctica ya que algún fabricante puede montar este directorio en otra ubicación, por ejemplo /media o /storage. La mejor solución es utilizar la clase Enviroment:

    1. Validar que hay disponible un directorio considerado de almacenamiento externo (que por ejemplo en el caso de Nexus 7 es en realidad interno) y que podemos leer/escribir en el mismo comprobando el valor según constante devuelto por getExternalStorageState.

                    Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
      
    2. Obtener la ruta completa a ese directorio usando la API de Android (getExternalStorageDirectory()) y a partir de ahí usar la API I/O estándar de java (File, Stream…) .
      String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "file.txt";
      
    3. Recordar siempre que es necesario el permiso WRITE_EXTERNAL_STORAGE para poder escribir en la tarjeta/directorio.
      <uses-permission android:name="android.permissions.WRITE_EXTERNAL_STORAGE" />
      

      Y aunque no es necesario, Google recomienda solicitar permiso de lectura si sólo vamos a leer.

       <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
      
    4. Podemos afinar más, y comprobar si hay espacio suficiente disponible con la clase StatFs (en Android 4.3 hay métodos deprecated). En este ejemplo se obtiene el espacio total y el disponible en bytes y MB.
      StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
      long available = ((long) stat.getAvailableBlocks() * (long) stat.getBlockSize()); 
      long total = ((long) stat.getBlockCount() * (long) stat.getBlockSize()); 
      
      float totalMB = (float)total/1024/1024;
      float availableMB = (float)available/1024/1024; 
      

    Si por curiosidad queremos saber si el almacenamiento externo es verdaderamente extraíble, podemos usar esta sentencia partir de API 9 (Gingerbread):

    Environment.isExternalStorageRemovable();
    

    Por ejemplo en la Nexus 7 devuelve falso, pero en la Galaxy Ace devuelve cierto (si la tarjeta de memoria está insertada y montada en el sistema de archivos).

    Nota: si queremos almacenar datos internos de la aplicación no visibles por el usuario, y que además estos se eliminen tras su desinstalación deberemos utilizar el siguiente código en una Activity para obtener la ruta raiz (a partir de API 8 Froyo):

    		this.getExternalFilesDir(null).getAbsolutePath();
    
    

    Este método devuelve rutas de este tipo: “/mnt/sdcard/Android/data/com.danieme.tipsandroid.demo/files”.

    Para probar este tip he creado un proyecto de ejemplo. Este es el resultado de su ejecución en tres dispositivos reales

    HTC Desire con Froyo 2.2.2. Es un dispositivo que admite tarjetas SD pero no tiene insertada ninguna.

    almacenamiento froyo

    Samsung Galaxy ACE (Gingerbread 2.3.6) con una tarjeta SD insertada.

    almacenamiento gingerbread

    Samsung Galaxy Nexus (Jelly Bean 4.3), dispositivo que no admite tarjetas SD (vésae cómo simula la existencia del almacenamiento externo).

    almacenamiento jelly bean

    El proyecto completo para Eclise ADT se encuentra en Github. Para más información sobre cómo utilizar GitHub, consultar este artículo.

    << TIPS ANDROID

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: