Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Casos prácticos y prácticas recomendadas de almacenamiento en Android

Con el objetivo de darles a los usuarios más control sobre sus archivos y acotar el desorden, en Android 10 se introdujo un nuevo paradigma de almacenamiento para apps llamado almacenamiento específico. El almacenamiento específico cambia la forma en la que las apps almacenan los archivos y acceden a ellos en el almacenamiento externo de un dispositivo. Si deseas migrar tu app a fin de admitir el almacenamiento específico, sigue las prácticas recomendadas para casos prácticos de almacenamiento comunes que se describen en esta guía. Se organizan los casos prácticos en dos categorías: control de archivos multimedia y control de archivos que no son multimedia.

Para obtener más información sobre cómo almacenar archivos y acceder a ellos en Android, consulta las guías de capacitación sobre almacenamiento.

Cómo controlar archivos multimedia

En esta sección se describen algunos de los casos prácticos comunes para controlar archivos multimedia (archivos de video, imágenes y audio) y se explica el enfoque general que tu app puede usar. En la siguiente tabla, se resume cada uno de estos casos prácticos y se incluyen vínculos a cada una de las secciones que contienen más detalles.

Caso práctico Resumen
Cómo mostrar todos los archivos de imagen o video Usa el mismo enfoque para todas las versiones de Android.
Cómo mostrar imágenes o videos de una carpeta en particular Usa el mismo enfoque para todas las versiones de Android.
Cómo acceder a la información de ubicación desde las fotos Usa un enfoque si tu app usa almacenamiento específico. Usa un enfoque diferente si tu app inhabilita el almacenamiento específico.
Cómo modificar o borrar varios archivos multimedia en una sola operación Usa un enfoque para Android 11. En Android 10 inhabilita el almacenamiento específico y usa el enfoque para Android 9 y versiones anteriores.
Cómo importar una sola imagen que ya existe Usa el mismo enfoque para todas las versiones de Android.
Cómo capturar una sola imagen Usa el mismo enfoque para todas las versiones de Android.
Cómo compartir archivos multimedia con otras apps Usa el mismo enfoque para todas las versiones de Android.
Cómo compartir archivos multimedia con una app específica Usa el mismo enfoque para todas las versiones de Android.
Cómo acceder a archivos desde código o bibliotecas que usan rutas de archivos directas Usa un enfoque para Android 11. En Android 10 inhabilita el almacenamiento específico y usa el enfoque para Android 9 y versiones anteriores.

Cómo mostrar archivos de imagen o video de varias carpetas

Busca una colección multimedia con la API de query(). Para ordenar o filtrar los archivos multimedia, ajusta los parámetros projection, selection, selectionArgs y sortOrder.

Cómo mostrar imágenes o videos de una carpeta en particular

Usa este enfoque:

  1. Sigue las prácticas recomendadas que se describen en Cómo solicitar permisos de la app y solicita el permiso READ_EXTERNAL_STORAGE.
  2. Recupera archivos multimedia basados en el valor de MediaColumns.DATA, que contiene la ruta absoluta del sistema de archivos hasta el elemento multimedia del disco.

Cómo acceder a la información de ubicación desde las fotos

Si tu app usa almacenamiento específico, sigue los pasos de la sección Información de ubicación en fotografías de la guía de almacenamiento de contenido multimedia.

Cómo modificar o borrar varios archivos multimedia en una sola operación

Incorpora lógica basada en las versiones de Android en las que se ejecuta tu app.

Si se ejecuta en Android 11

Usa este enfoque:

  1. Crea un intent pendiente para la solicitud de escritura o eliminación de tu app con MediaStore.createWriteRequest() o MediaStore.createTrashRequest() y, luego, solicita al usuario permiso a fin de invocar ese intent y editar un conjunto de archivos.
  2. Evalúa la respuesta del usuario:

    • Si se otorgó el permiso, continúa con la operación de modificación o eliminación.
    • Si no se otorgó el permiso, explícale al usuario por qué la función de tu app necesita el permiso.

Obtén más información para realizar operaciones por lotes con estos métodos disponibles en Android 11.

Si se ejecuta en Android 10

Si tu app está orientada a Android 10 (nivel 29 de API), inhabilita el almacenamiento específico y continúa usando el enfoque para Android 9 y versiones anteriores a fin de realizar esta operación.

Si se ejecuta en Android 9 o versiones anteriores

Usa este enfoque:

  1. Sigue las recomendaciones que se describen en Cómo solicitar permisos de la app y solicita el permiso WRITE_EXTERNAL_STORAGE.
  2. Usa la API de MediaStore para modificar o borrar los archivos multimedia.

Cómo importar una sola imagen que ya existe

Si deseas importar una sola imagen que ya existe (por ejemplo, para usarla como foto del perfil de un usuario), tu app puede usar su propia IU en la operación, o bien el selector del sistema.

Cómo presentar tu propia interfaz de usuario

Usa este enfoque:

  1. Sigue las recomendaciones que se describen en Cómo solicitar permisos de la app y solicita el permiso READ_EXTERNAL_STORAGE.
  2. Usa la API de query() para buscar en una colección de archivos multimedia.
  3. Muestra los resultados en la IU personalizada de tu app.

Cómo usar el selector del sistema

Usa el intent ACTION_GET_CONTENT, que le pide al usuario que elija una imagen para importar.

Si deseas filtrar los tipos de imágenes que el selector del sistema presenta al usuario, puedes usar setType() o EXTRA_MIME_TYPES.

Cómo capturar una sola imagen

Si deseas capturar una sola imagen para usarla en tu app (por ejemplo, como foto del perfil de un usuario), usa el intent ACTION_IMAGE_CAPTURE a fin de pedirle al usuario que tome una foto con la cámara del dispositivo. El sistema almacena la foto capturada en la tabla MediaStore.Images.

Cómo compartir archivos multimedia con otras apps

Usa el método insert() para agregar directamente registros a MediaStore. Para obtener más información, consulta la sección Cómo agregar un elemento de la guía de almacenamiento de contenido multimedia.

Cómo compartir archivos multimedia con una app específica

Usa el componente FileProvider de Android, como se describe en la guía Cómo configurar el uso compartido de archivos.

Cómo acceder a archivos desde código o bibliotecas que usan rutas de archivos directas

Incorpora lógica basada en las versiones de Android en las que se ejecuta tu app.

Si se ejecuta en Android 11

Usa este enfoque:

  1. Sigue las recomendaciones que se describen en Cómo solicitar permisos de la app y solicita el permiso READ_EXTERNAL_STORAGE.
  2. Accede a los archivos mediante rutas de acceso directas.

Para obtener más información, consulta Cómo acceder a archivos usando rutas sin procesar.

Si se ejecuta en Android 10

Si tu app está orientada a Android 10 (nivel 29 de API), inhabilita el almacenamiento específico y continúa usando el enfoque para Android 9 y versiones anteriores a fin de realizar esta operación.

Si se ejecuta en Android 9 o versiones anteriores

Usa este enfoque:

  1. Sigue las recomendaciones que se describen en Cómo solicitar permisos de la app y solicita el permiso WRITE_EXTERNAL_STORAGE.
  2. Accede a los archivos mediante rutas de acceso directas.

Cómo controlar archivos que no son multimedia

En esta sección se describen algunos de los casos prácticos comunes para controlar archivos que no son multimedia y se explica el enfoque general que tu app puede usar. En la siguiente tabla, se resume cada uno de estos casos prácticos y se incluyen vínculos a cada una de las secciones que contienen más detalles.

Caso práctico Resumen
Cómo abrir un archivo de documento Usa el mismo enfoque para todas las versiones de Android.
Cómo migrar archivos existentes desde una ubicación de almacenamiento heredado Migra los archivos al almacenamiento específico cuando sea posible. Inhabilita el almacenamiento específico para Android 10 cuando sea necesario.
Cómo compartir contenido con otras apps Usa el mismo enfoque para todas las versiones de Android.
Cómo almacenar en caché archivos que no son multimedia Usa el mismo enfoque para todas las versiones de Android.

Cómo abrir un archivo de documento

Usa el intent ACTION_OPEN_DOCUMENT para pedirle al usuario que elija un archivo para abrir mediante el selector del sistema. Si deseas filtrar los tipos de archivos que el selector del sistema presenta al usuario, puedes usar setType() o EXTRA_MIME_TYPES.

Por ejemplo, puedes usar el siguiente código para encontrar todos los archivos PDF, DDT y TXT:

Kotlin

startActivityForResult(
        Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "*/*"
            putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(
                    "application/pdf", // .pdf
                    "application/vnd.oasis.opendocument.text", // .odt
                    "text/plain" // .txt
            ))
        },
        REQUEST_CODE
      )

Java

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {
                "application/pdf", // .pdf
                "application/vnd.oasis.opendocument.text", // .odt
                "text/plain" // .txt
        });
        startActivityForResult(intent, REQUEST_CODE);

Cómo migrar archivos existentes desde una ubicación de almacenamiento heredado

Se considera que un directorio es una ubicación de almacenamiento heredado si no es un directorio específico de la app o un directorio público compartido. Si tu app crea o consume archivos en una ubicación de almacenamiento heredado, te recomendamos que migres los archivos a ubicaciones a las que se pueda acceder con almacenamiento específico y realizar los cambios necesarios para trabajar con archivos en este tipo de almacenamiento.

Cómo mantener el acceso a la ubicación de almacenamiento heredado para la migración de datos

Tu app debe mantener el acceso a la ubicación de almacenamiento heredado para migrar cualquier archivo de apps a ubicaciones a las que se pueda acceder con almacenamiento específico. El enfoque que debes usar depende del nivel de la API de destino de tu app.

Si tu app se orienta a Android 11
  1. Usa la marca preserveLegacyExternalStorage para conservar el modelo de almacenamiento heredado, de modo que tu app pueda migrar los datos de un usuario cuando este actualice a la nueva versión orientada a Android 11.

  2. Para continuar, inhabilita el almacenamiento específico de modo que tu app pueda seguir accediendo a tus archivos en la ubicación de almacenamiento heredado, en dispositivos Android 10.

Si tu app se orienta a Android 10

Inhabilita el almacenamiento específico para que sea más fácil mantener el comportamiento de tu app en todas las versiones de Android.

Cómo migrar los datos de la app

Cuando tu app esté lista para la migración, usa el siguiente enfoque:

  1. Verifica si los archivos de trabajo de tu app se encuentran en el directorio /sdcard/ o en alguno de sus subdirectorios.
  2. Transfiere cualquier archivo privado de la app desde su ubicación actual en /sdcard/ al directorio que muestra el método getExternalFilesDir().
  3. Transfiere cualquier archivo no multimedia compartido desde su ubicación actual en /sdcard/ a un subdirectorio, específico de la app, del directorio Downloads/.
  4. Quita los directorios de almacenamiento heredado de tu app del directorio /sdcard/.

Cómo compartir contenido con otras apps

Para compartir los archivos de tu app con otra app, usa un FileProvider. En el caso de las apps que necesitan compartir archivos entre sí, recomendamos que uses un proveedor de contenido para cada app y, luego, que sincronices los datos a medida que se agregan a la colección.

Cómo almacenar en caché archivos que no son multimedia

El enfoque que debes usar depende del tipo de archivos que necesitas almacenar en caché.

Cómo inhabilitar temporalmente el almacenamiento específico

Antes de que tu app sea totalmente compatible con el almacenamiento específico, puedes inhabilitarla de forma temporal con uno de los siguientes métodos:

  • Orienta la app a Android 9 (nivel 28 de API) o versiones anteriores.
  • Si la orientas a Android 10 (nivel 29 de API) o versiones posteriores, establece el valor de requestLegacyExternalStorage en true, en el archivo de manifiesto de tu app:

    <manifest ... >
    <!-- This attribute is "false" by default on apps targeting
         Android 10 or higher. -->
      <application android:requestLegacyExternalStorage="true" ... >
        ...
      </application>
    </manifest>
    

Si deseas probar cómo se comporta una app que se orienta a Android 9 o versiones anteriores cuando usas almacenamiento específico, puedes establecer el valor de requestLegacyExternalStorage en false. Si realizas pruebas en un dispositivo Android 11, también puedes usar marcas de compatibilidad de apps para probar el comportamiento de tu app con o sin almacenamiento específico.