Skip to content

Most visited

Recently visited

navigation

Opciones de almacenamiento

Vista rápida de almacenamiento

  • Usar preferencias compartidas para datos primitivos
  • Usar el almacenamiento interno del dispositivo para datos privados
  • Usar el almacenamiento externo para grandes conjuntos de datos que no son privados
  • Usar bases de datos SQLite para obtener almacenamiento estructurado

En este documento:

  1. Cómo utilizar las preferencias compartidas
  2. Cómo usar el almacenamiento interno
  3. Cómo usar el almacenamiento externo
  4. Cómo utilizar las bases de datos
  5. Cómo usar una conexión de red

Consulta también:

  1. Proveedores de contenido y solucionadores de contenido

Android ofrece diferentes opciones para que guardes datos persistentes de la aplicación. La solución que elijas depende de tus necesidades específicas; por ejemplo, si los datos deben ser privados para tu aplicación o estar disponibles para otras aplicaciones (y el usuario), y la cantidad de espacio que requieren tus datos.

Tus opciones de almacenamiento de datos son las siguientes:

Preferencias compartidas
Almacenamiento de datos primitivos privados en pares clave-valor.
Almacenamiento interno
Almacenamiento de datos privados en la memoria del dispositivo.
Almacenamiento externo
Almacenamiento de datos públicos en el almacenamiento externo compartido.
Bases de datos SQLite
Almacenamiento de datos estructurados en una base de datos privada.
Conexión de red
Almacenamiento de datos en la Web mediante tu propio servidor de red.

Android ofrece un método para que expongas tus datos privados a otras aplicaciones, mediante un proveedor de contenido. Un proveedor de contenido es un componente opcional que expone el acceso de lectura y escritura a los datos de tu aplicación, sujetos a las restricciones que desees establecer. Para obtener más información sobre cómo usar los proveedores de contenido, consulta la documentación Proveedores de contenido.

Cómo utilizar las preferencias compartidas

La clase de SharedPreferences ofrece un marco general que te permite guardar y recuperar pares clave-valor persistentes de tipos de datos primitivos. Puedes usar SharedPreferences para guardar todos los tipos de datos primitivos: booleanos, elementos flotantes, valores enteros, valores largos y strings. Estos datos se conservarán de una sesión de usuario a otra (incluso si tu aplicación finaliza).

Si deseas obtener un objeto de SharedPreferences para tu aplicación, usa uno de los dos métodos siguientes:

Para escribir valores, haz lo siguiente:

  1. Llama a edit() para obtener un SharedPreferences.Editor.
  2. Agrega valores con métodos, como putBoolean() y putString().
  3. Confirma los nuevos valores con commit().

Para leer valores, usa métodos de SharedPreferences, como getBoolean() y getString().

A continuación, se describe un ejemplo mediante el cual se guarda una preferencia para el modo de presión silencioso en una calculadora:

public class Calc extends Activity {
    public static final String PREFS_NAME = "MyPrefsFile";

    @Override
    protected void onCreate(Bundle state){
       super.onCreate(state);
       . . .

       // Restore preferences
       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
       boolean silent = settings.getBoolean("silentMode", false);
       setSilent(silent);
    }

    @Override
    protected void onStop(){
       super.onStop();

      // We need an Editor object to make preference changes.
      // All objects are from android.context.Context
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);

      // Commit the edits!
      editor.commit();
    }
}

Cómo usar el almacenamiento interno

Puedes guardar archivos directamente en el almacenamiento interno del dispositivo. De forma predeterminada, los archivos que se guardan en el almacenamiento interno son privados para tu aplicación y otras aplicaciones no pueden tener acceso a ellos (tampoco el usuario). Cuando el usuario desinstala tu aplicación, estos archivos se quitan.

Par crear y escribir un archivo privado en el almacenamiento interno, haz lo siguiente:

  1. Llama a openFileOutput() mediante el nombre del archivo y el modo de operación. Esto muestra un FileOutputStream.
  2. Realiza operaciones de escritura en el archivo con write().
  3. Cierra el flujo con close().

Por ejemplo:

String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();

MODE_PRIVATE creará el archivo (o reemplazará un archivo del mismo nombre) y lo hará privado para tu aplicación. Otros modos disponibles son los siguientes: MODE_APPEND, MODE_WORLD_READABLE y MODE_WORLD_WRITEABLE.

Nota: Las constantes MODE_WORLD_READABLE y MODE_WORLD_WRITEABLE dejaron de estar disponibles desde el nivel de API 17. A partir de Android N, su uso generará una SecurityException . Esto significa que las apps para Android N y versiones posteriores no pueden compartir archivos privados por nombre y los intentos de compartir una URI de “file://” generará una FileUriExposedException. Si tu app debe compartir archivos privados con otras apps, podrá hacer uso de un FileProvider junto con FLAG_GRANT_READ_URI_PERMISSION. Consulta también Cómo compartir archivos.

Para leer un archivo desde el almacenamiento interno, haz lo siguiente:

  1. Llama a openFileInput() y usa el nombre del archivo que deseas leer. Esto muestra un FileInputStream.
  2. Lee los bytes del archivo con read().
  3. A continuación, cierra el flujo con close().

Sugerencia: Si deseas guardar un archivo estático en tu aplicación en el momento de la compilación, guarda el archivo en el directorio de tu proyecto res/raw/. Puedes abrirlo con openRawResource() mediante el ID de recursos de R.raw.<filename>. Este método muestra un InputStream que puedes usar para leer el archivo (pero no puedes realizar operaciones de escritura en el archivo original).

Cómo guardar archivos de caché

Si deseas almacenar en caché algunos datos, en lugar de guardarlos de manera continua debes usar getCacheDir() para abrir un File que represente el directorio interior donde tu aplicación debe guardar los archivos de caché temporales.

Cuando el dispositivo tenga poco espacio de almacenamiento interno, Android podrá quitar estos archivos de caché para recuperar espacio. Sin embargo, no debes confiar en que el sistema borrará estos archivos. Siempre deberás encargarte de mantener los archivos de caché y mantenerlos dentro de un límite de espacio razonable, por ejemplo, 1 MB. Cuando el usuario desinstala tu aplicación, estos archivos se quitan.

Otros métodos útiles

getFilesDir()
Obtiene la ruta de acceso absoluta al directorio de sistema de archivos donde se guardan tus archivos internos.
getDir()
Crea un directorio (o abre uno existente) dentro de tu espacio de almacenamiento interno.
deleteFile()
Quita un archivo guardado en el almacenamiento interno.
fileList()
Muestra un conjunto de archivos que tu aplicación guarda actualmente.

Cómo usar el almacenamiento externo

Todo dispositivo compatible con Android admite un “almacenamiento externo” compartido, que puedes usar para guardar archivos. Puede ser un medio de almacenamiento extraíble (como una tarjeta SD) o un medio almacenamiento interno (no extraíble). Los archivos guardados en el almacenamiento externo pueden ser leídos por cualquier usuario y este puede modificarlos cuando habilita el almacenamiento masivo de USB para transferir archivos a una computadora.

Advertencia: Es posible que el almacenamiento externo deje de estar disponible si el usuario conecta el almacenamiento externo a una computadora o quita el medio, y no se implementan medidas de seguridad en los archivos que guardes en el almacenamiento externo. Todas las aplicaciones pueden realizar operaciones de lectura y escritura en los archivos guardados en el almacenamiento externo y el usuario puede quitarlos.

Uso del acceso a directorios determinados

En Android 7.0 o versiones posteriores, si necesitas acceder a un directorio específico en el almacenamiento externo, usa el acceso a directorios determinados. El acceso a directorios determinados simplifica la manera en que tu aplicación accede a los directorios de almacenamiento externo estándar, como el directorio Pictures, y brinda una IU de permisos simples que detalla claramente el directorio al cual la aplicación solicita acceso. Para obtener más información sobre el acceso a directorios determinados, consulta Uso del acceso a directorios determinados.

Cómo obtener acceso al almacenamiento externo

A fin de realizar operaciones de lectura escritura en archivos en el almacenamiento externo, tu app debe obtener los permisos de sistema del READ_EXTERNAL_STORAGE o WRITE_EXTERNAL_STORAGE. Por ejemplo:

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

Si necesitas leer y escribir archivos, solo debes solicitar el permiso de WRITE_EXTERNAL_STORAGE, ya que este también requiere implícitamente acceso de lectura.

Nota: A partir de Android 4.4, estos permisos no son necesarios si deseas leer o escribir archivos que solamente son privados para tu app. Para obtener más información, consulta la sección siguiente sobre cómo guardar archivos privados para la aplicación.

Cómo comprobar la disponibilidad de medios

Antes de hacer cualquier trabajo con el almacenamiento externo, siempre debes llamar a getExternalStorageState() a fin de comprobar si el medio está disponible. El medio podría conectarse a una computadora o faltar, ser de solo lectura o hallarse en algún otro estado. Por ejemplo, a continuación, se describen algunos métodos que puedes usar para comprobar la disponibilidad:

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

El método getExternalStorageState() muestra otros estados que tal vez desees comprobar, como el uso compartido de los medios (su conexión a una computadora), la falta total de estos, su eliminación incorrecta, etc. Puedes usar estas opciones para transmitir al usuario más información cuando tu aplicación necesite acceder al medio.

Cómo guardar archivos que se pueden compartir con otras apps

Por lo general, los nuevos archivos que el usuario puede obtener mediante tu app deben guardarse en una ubicación “pública” del dispositivo, en la cual otras apps puedan acceder a ellos y el usuario pueda copiarlos fácilmente desde el dispositivo. Cuando lo hagas, debes usar uno de los directorios públicos compartidos, como Music/, Pictures/ y Ringtones/.

Para obtener un File que represente el directorio público adecuado, llama a getExternalStoragePublicDirectory() y usa el tipo de directorio que desees, como DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES u otros. Al guardar tus archivos en el directorio de tipos de medios correspondiente, el escáner multimedia del sistema puede categorizar adecuadamente tus archivos en el sistema (por ejemplo, los tonos se muestran en la configuración del sistema como tonos, no como música).

Por ejemplo, a continuación, se describe un método que crea un directorio para un nuevo álbum de fotografías en el directorio público de imágenes:

public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

Cómo guardar archivos privados para la app

Si gestionas archivos que no deseas que otras apps usen (como texturas gráficas o efectos de sonido usados solo por tu app), debes usar un directorio de almacenamiento privado en el almacenamiento externo; para ello, llama a getExternalFilesDir(). Este método también toma un argumento de type para especificar el tipo de subdirectorio (por ejemplo, DIRECTORY_MOVIES). Si necesitas un directorio de medios específicos, usa null para obtener el directorio raíz del directorio privado de tu app.

A partir de Android 4.4, para realizar operaciones de lectura o escritura de archivos en los directorios privados de tu app no se requieren los permisos de READ_EXTERNAL_STORAGE ni WRITE_EXTERNAL_STORAGE. Por eso, puedes definir que el permiso deba solicitarse solo en las versiones anteriores de Android; para ello, agrega el atributo maxSdkVersion :

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

Nota: cuando el usuario desinstala tu aplicación, este directorio y todo su contenido se quitan. Además, el escáner multimedia no lee los archivos de estos directorios, por lo cual no es posible acceder a ellos desde el proveedor de contenido MediaStore. Por ello, no debes usar estos directorios para los medios que, en última instancia, pertenecen al usuario, como fotografías tomadas o editadas con tu app, o música que el usuario adquirió a través de ella. Esos archivos deben guardarse en directorios públicos.

A veces, un dispositivo que asignó una partición de la memoria interna para usarse como almacenamiento externo también puede ofrecer una ranura para tarjeta SD. Cuando ese dispositivo se ejecuta en Android 4.3 o versiones anteriores, el método de getExternalFilesDir() brinda acceso solo a la partición interna y tu aplicación no puede realizar operaciones de lectura o escritura en la tarjeta SD. Sin embargo, a partir de Android 4.4 puedes acceder a ambas ubicaciones llamando a getExternalFilesDirs(), lo cual muestra un conjunto de File con entradas a cada ubicación. La primera entrada del conjunto se considera el almacenamiento externo principal y debes usar esa ubicación, a menos que esté llena o no se encuentre disponible. Si deseas poder acceder a las dos ubicaciones posibles y además brindar compatibilidad con Android 4.3 y las versiones anteriores, usa el método estático de la biblioteca de compatibilidad, ContextCompat.getExternalFilesDirs(). Esto también muestra un arreglo de File, pero siempre incluye solo una entrada en Android 4.3 y versiones anteriores.

Advertencia Si bien el proveedor de contenido de MediaStore no puede acceder a los directorios proporcionados por getExternalFilesDir() y getExternalFilesDirs(), otras apps con el permiso de READ_EXTERNAL_STORAGE pueden acceder a todos los archivos del almacenamiento externo, incluidos estos. Si necesitas restringir el acceso a tus archivos por completo, en su lugar debes escribir tus archivos en el almacenamiento interno.

Cómo guardar archivos de caché

Para abrir un File que represente el directorio de almacenamiento en caché externo en el cual debes guardar los archivos de caché, llama a getExternalCacheDir(). Si el usuario desinstala tu aplicación, estos archivos se borrarán automáticamente.

En un caso similar al de ContextCompat.getExternalFilesDirs(), mencionado anteriormente, también puedes acceder a un directorio de caché en un medio de almacenamiento externo secundario (si está disponible) llamando a ContextCompat.getExternalCacheDirs().

Sugerencia: A fin de preservar el espacio del archivo y mantener el rendimiento de tu app, es importante que administres cuidadosamente tus archivos de caché y quites aquellos que ya no sean necesarios durante todo el ciclo de vida de tu app.

Cómo utilizar las bases de datos

Android ofrece compatibilidad total con las bases de datos SQLite. Cualquier clase dentro de la aplicación, no fuera de ella, será posible acceder por nombre a cualquier base de datos que crees.

El método recomendado para crear una nueva base de datos SQLite consiste en crear una subclase de SQLiteOpenHelper y anular el método de onCreate(), en el cual puedes ejecutar un comando de SQLite a fin de crear tablas en la base de datos. Por ejemplo:

public class DictionaryOpenHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 2;
    private static final String DICTIONARY_TABLE_NAME = "dictionary";
    private static final String DICTIONARY_TABLE_CREATE =
                "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
                KEY_WORD + " TEXT, " +
                KEY_DEFINITION + " TEXT);";

    DictionaryOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DICTIONARY_TABLE_CREATE);
    }
}

Puedes obtener una instancia de tu implementación de SQLiteOpenHelper mediante el constructor definido. Para realizar operaciones de lectura y escritura en la base de datos, llama a getWritableDatabase() y getReadableDatabase(), respectivamente. Estas dos opciones muestran un objeto SQLiteDatabase que representa la base de datos y proporciona métodos para las operaciones de SQLite.

Puedes ejecutar consultas de SQLite a través de los métodos de SQLiteDatabase query(), los cuales aceptan varios parámetros de consulta, como la tabla para consulta, la proyección, la selección, las columnas y el agrupamiento, entre otros. En el caso de consultas complejas, como aquellas que requieren alias de columna, debes usar SQLiteQueryBuilder, el cual ofrece diferentes métodos convenientes para crear consultas.

Cada consulta de SQLite mostrará un Cursor que señale todas las filas que encontró la consulta. El Cursor siempre es el mecanismo con el cual puedes navegar por los resultados de una consulta de la base de datos, y leer filas y columnas.

Para hallar ejemplos de apps que demuestren la forma de usar las bases de datos SQLite en Android, consulta las aplicaciones del bloc de notas y el diccionario de búsquedas.

Depuración de la base de datos

El Android SDK incluye una herramienta de base de datos sqlite3 que te permite explorar contenido de tablas, ejecutar comandos de SQL y llevar a cabo otras funciones útiles en las bases de datos SQLite. Consulta Cómo examinar las bases de datos sqlite3 desde una interfaz remota para aprender cómo usar esta herramienta.

Cómo usar una conexión de red

Puedes usar la red (cuando se encuentre disponible) para almacenar y obtener datos de tus propios servicios basados en la Web. Para realizar operaciones en la red, usa las clases de los siguientes paquetes:

This site uses cookies to store your preferences for site-specific language and display options.

Hooray!

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a one-minute survey?
Help us improve Android tools and documentation.