Almacenamiento delimitado de Android y almacenamiento externo.
Tengo una aplicación que desea tener la capacidad de descargar archivos localmente. Un usuario puede descargar un archivo (sin restricciones de tipo de archivo) y debería poder guardarlo en el dispositivo para luego poder utilizarlo con otros propósitos. También me gustaría que el usuario pueda eliminar el archivo desde la aplicación (sabrían qué archivo se descargó y cuál no, una marca indicaría si está respaldado localmente). Si se trata de un archivo pdf, el usuario querría abrirlo con diferentes aplicaciones o editarlo si tiene la capacidad, o simplemente compartirlo por correo electrónico. Teniendo en cuenta que ya no podemos optar por el almacenamiento acotado (requisito para el objetivo 30), tengo un par de preguntas.
He intentado usar Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()
y también getExternalFilesDirPath(ctx, Environment.DIRECTORY_DOWNLOADS)
. Si bien el primero está obsoleto, funciona para mí en el sentido de que la aplicación Files se puede usar para navegar hasta el archivo en cuestión (y posiblemente abrirlo/eliminarlo). Por otro lado, no puedo eliminar este archivo desde mi aplicación debido a la falta de permisos. Obviamente, la segunda ruta no se puede navegar desde otra aplicación (¿o sí? No he encontrado una forma, de ahí la pregunta).
Lo otro que he considerado usar es la API MediaStore, pero estoy luchando por ver cómo esto es una mejora respecto a los métodos antiguos en términos de funcionalidad. Sin tener en cuenta volver al resolvedor de contenidos manual y el uso de cursores, ¿cómo se deberían ordenar los archivos arbitrarios? ¿Debería ordenar manualmente por tipos MIME y tener diferentes métodos para guardar para tipos de medios específicos? Suena excepcionalmente tedioso y poco intuitivo. Si este es el camino, así sea, lo implementaré, pero no parece ser la mejor opción. Por el lado positivo, al menos suena como una solución debido a las capacidades CRUD del resolvedor de contenidos.
Estoy trabajando en una aplicación RN que utiliza una biblioteca de terceros para las rutas de descarga, las cuales, en las versiones antiguas y nuevas, usan rutas diferentes (rn-fetch-blob y rn-fetch-blob-util). Además, la API MediaStore aún no tiene una implementación para RN en este momento, por lo que todo tendría que hacerse desde cero, también.
¿Cuáles son mis opciones? A corto plazo, estoy considerando deshabilitar la función de borrado de la aplicación (al menos por ahora). ¿Existe algo que me esté perdiendo y deba considerar? Gracias de antemano.
davy.ai
Descarga y almacenamiento de archivos locales en aplicaciones de Android
Antecedentes
Como experto en TI especializado en Android, React Native, MediaStore, Android ContentResolver y Android Download Manager, entiendo las limitaciones del almacenamiento de aplicaciones en dispositivos Android, especialmente con la función de almacenamiento con alcance optativo introducida en el nivel de API 30. En este contexto, estoy abordando la siguiente pregunta:
El problema
“Tengo una aplicación que desea tener la capacidad de descargar archivos de forma local. Un usuario puede descargar un archivo (sin restricciones de tipo de archivo) y debería poder guardarlo en el dispositivo para poder utilizarlo con otros fines. También me gustaría que el usuario pueda eliminar el archivo desde la aplicación (sabrían qué archivo se ha descargado y cuál no, un marcador indicaría si está respaldado localmente). Supongamos que es un archivo PDF: el usuario querría abrirlo con diferentes aplicaciones o editarlo si tiene la capacidad de hacerlo, o simplemente compartirlo por correo electrónico. Teniendo en cuenta que ya no podemos optar por no utilizar el almacenamiento con alcance optativo (requisito para el nivel de objetivo 30), tengo un par de preguntas”.
Análisis y opciones
El autor ha intentado utilizar
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath())
y tambiéngetExternalFilesDirPath(ctx, Environment.DIRECTORY_DOWNLOADS))
. El primero está obsoleto, pero aún funciona para la navegación y eliminación de archivos desde la aplicación. Sin embargo, la aplicación carece de permisos para eliminarlos de forma programática. El directorio último es inaccesible para otras aplicaciones. El autor también ha considerado el uso de la API MediaStore, que ofrece capacidades CRUD, pero tiene dificultades para ordenar archivos arbitrarios, especialmente por tipos MIME. Además, la aplicación de React Native (RN) en la que está trabajando no tiene una implementación de esta API, y las librerías de RN comoreact-native-fetch-blob
tienen diferentes rutas para versiones antiguas y nuevas.Recomendación
A corto plazo, el autor puede desactivar la función de borrado de la aplicación, especialmente si los archivos locales no son demasiado grandes. A largo plazo, el autor puede considerar las siguientes opciones:
En última instancia, la elección depende de los requisitos de la aplicación, las preferencias del usuario y los recursos de desarrollo. Lo importante es seguir las mejores prácticas para el manejo de archivos, almacenamiento y seguridad en Android, y probar la aplicación a fondo en diferentes dispositivos y escenarios.