Diferencia entre getExternalFilesDir y getExternalStorageDirectory ()

89

Entiendo que ExternalFiles se utilizará en API 8 en adelante y getExternalStorageDirectory es para 7 y menos. Sin embargo, estoy un poco confundido entre el uso. Por ejemplo, quería comprobar que existe una carpeta y anteriormente usarías algo como:

File ChildFolder = new File(Environment.getExternalStorageDirectory() + "/ParentFolder/Child");

Sin embargo, cada ejemplo que veo dice que use getExternalFilesDir (null), File.ext. Como estoy por encima de la API 8, quiero usar este método, pero ¿cómo puedo buscar una carpeta? Verificaré la existencia de archivos en otro punto, pero por ahora solo quiero ver si existen las carpetas.

GPGVM
fuente

Respuestas:

132
getExternalFilesDir()

Devuelve la ruta a la carpeta de archivos dentro de Android / data / data / your_package / en su tarjeta SD. Se utiliza para almacenar los archivos necesarios para su aplicación (por ejemplo, imágenes descargadas de la web o archivos de caché). Una vez que se desinstala la aplicación, todos los datos almacenados en esta carpeta también desaparecen.

getExternalStorageDirectory()

Devuelve la ruta raíz a su tarjeta SD (por ejemplo, mnt / sdcard / ). Si guarda datos en esta ruta y desinstala la aplicación, esos datos no se perderán.

waqaslam
fuente
4
Google Android quiere que uses todo lo que ofrecen dentro del marco. Así que depende de su elección y requisitos de diseño. Si no desea que los archivos se queden a la izquierda cuando se desinstala la aplicación, le recomendamos que use getExternalFilesDir () o getExternalCacheDir ()
waqaslam
5
Es porque en API 8, introdujeron funciones avanzadas de escáner de medios que permiten escanear datos de carpetas como música, imágenes, tonos de llamada, etc. Esos directorios se crean automáticamente solo si usa getExternalFilesDir () . Ahora que esta función no estaba disponible en API 7, es por eso que recomendaron usar getExternalStorageDirectory () . Simple ...
waqaslam
2
está bien, dale algo de tiempo, pronto habrá un momento eureka :)
waqaslam
3
Es importante saber que getExternalStorageDirectory()no no necesariamente - tal vez incluso no suele - devolver el "camino a la tarjeta SD." En su lugar, devuelve el "directorio de almacenamiento externo primario". Los documentos ( developer.android.com/reference/android/os/… ) dicen:
LarsH
2
'Nota: no se confunda con la palabra "externo" aquí. Este directorio se puede considerar mejor como medio / almacenamiento compartido. Es un sistema de archivos que puede contener una cantidad relativamente grande de datos y que se comparte entre todas las aplicaciones (no impone permisos). Tradicionalmente, se trata de una tarjeta SD , pero también se puede implementar como almacenamiento integrado en un dispositivo que es distinto del almacenamiento interno protegido y se puede montar como un sistema de archivos en una computadora '.
LarsH
69

En primer lugar, debemos comprender cuál es la diferencia entre almacenamiento interno, almacenamiento externo (también conocido como almacenamiento externo primario) y almacenamiento externo secundario.

Almacenamiento interno: es el almacenamiento al que el usuario no puede acceder, excepto a través de aplicaciones instaladas (o al rootear su dispositivo). Ejemplo: data / data / app_packageName

Almacenamiento externo primario: almacenamiento compartido integrado al que "el usuario puede acceder conectando un cable USB y montándolo como una unidad en una computadora host". Ejemplo: cuando decimos Nexus 5 32 GB.

Almacenamiento externo secundario: almacenamiento extraíble. Ejemplo: tarjeta SD.

getExternalFilesDir (String type)

Devuelve la ruta a la carpeta de archivos dentro de Android / data / data / your_package / en el almacenamiento externo primario. Que es almacenamiento incorporado.

Environment.getExternalStorageDirectory(type)

Devolverá la ruta del directorio de almacenamiento externo secundario

Vikasdeep Singh
fuente
Gracias por explicar los diferentes tipos de almacenamiento. Sin embargo, tal vez edite el elemento de almacenamiento interno para mencionar que la llamada al método para obtener ese valor es getFilesDir (). Bueno, supongo que ese método en realidad devuelve datos / datos / nombre_paquete_aplicación / archivos, pero sigue siendo un almacenamiento interno.
Raddevus
3
@VicJordan Por favor escriba sobre File getExternalStoragePublicDirectory (String type)y File getFilesDir ()también
AnV
2
Gracias Vic. Environment.getExternalStorageDirectory () salidas / almacenamiento / emulado / 0
gimmegimme
¿Tiene alguna documentación para la afirmación de que el almacenamiento externo primario siempre está integrado, mientras que el secundario siempre es extraíble? Pensé que esos eran problemas independientes ... algunos teléfonos no tienen almacenamiento "externo" incorporado, en cuyo caso el almacenamiento externo principal podría ser la tarjeta SD extraíble.
LarsH
@LarsH, según mi conocimiento, actualmente no hay ningún teléfono en el mercado o en un futuro cercano que no tenga almacenamiento externo primario incorporado. Había teléfonos en la época del pan de jengibre cuando existían tales teléfonos, pero no ahora. ¿Podría nombrar "algunos" teléfonos que no tienen "almacenamiento externo primario" integrado?
Vikasdeep Singh
17

! ACTUALIZACIÓN IMPORTANTE !para quien se encuentre con esta pregunta.

Como se trata de una pregunta algo antigua, solo quería proporcionar información adicional. Dado que KitKat, incluso las aplicaciones que tienen permiso WRITE_EXTERNAL_STORAGE solo pueden escribir en Android / data / data / your_package / en almacenamiento externo, también conocido como getExternalFilesDir()

Si intenta escribir getExternalStorageDirectory() + "/somefolder/anotherfolder/", obtendrá una SecurityException en la mayoría de los dispositivos

SGal
fuente
9
Según los documentos, las aplicaciones que tienen el permiso WRITE_EXTERNAL_STORAGE PUEDEN escribir en el almacenamiento externo de otros paquetes, no solo en el suyo. Son las aplicaciones que NO tienen el permiso que solo pueden escribir en su propio directorio: developer.android.com/reference/android/content/… "A partir de KITKAT, no se requieren permisos para leer o escribir en la ruta devuelta; siempre es accesible a la aplicación de llamada ... Para acceder a las rutas que pertenecen a otros paquetes, se requieren WRITE_EXTERNAL_STORAGE y / o READ_EXTERNAL_STORAGE ".
Oded el
Aquí es donde "en la mayoría de los dispositivos" comienza a importar, ya que los documentos de Android generalizan la idea, pero los fabricantes a veces tienen cosas como InternalStorage (almacenamiento integrado para datos de aplicaciones), ExternalStorage-Primary ( también almacenamiento integrado con un mayor alcance de acceso) y ExternalStorage-Secondary (esto sería cosas montadas como tarjetas SD). Ahora puede adivinar qué ruta obtiene las devoluciones de External StorageDirectory
SGal
7
Eso no aborda la información incorrecta en su respuesta. "Desde KitKat, incluso las aplicaciones que tienen el permiso WRITE_EXTERNAL_STORAGE solo pueden escribir en Android / data / data / your_package / en almacenamiento externo, también conocido como getExternalFilesDir ()". Según los documentos, esto está mal. Con WRITE_EXTERNAL_STORAGE, las aplicaciones pueden escribir en todo el almacenamiento externo.
Oded el
1
@Oded, ¿has probado esto? Mi comprensión de los documentos y mi experiencia con KitKat y dispositivos posteriores es diferente a la suya. (Ojalá tuviera tiempo para discutir todos los detalles ahora. Quizás más tarde.) Mi experiencia es que SGal tiene razón. Luego también está Lollipop, que es un poco diferente.
LarsH
2
Esta respuesta es descaradamente falsa, según la documentación de Android. Consulte developer.android.com/reference/android/… "A partir del nivel de API 19, este permiso no es necesario para leer / escribir archivos en los directorios específicos de su aplicación devueltos por getExternalFilesDir (String) y getExternalCacheDir ()". (Tenga en cuenta que el nivel de API 19 = KitKat). No tengo idea de cómo obtuvo tantos votos positivos.
Ajedi32
6

!! IMPORTANTE !!

Environment.getExternalStorageDirectory()está en desuso y debe usarse Context # getExternalFilesDir (String), MediaStore o Intent # ACTION_OPEN_DOCUMENT.

Este método quedó en desuso en el nivel de API 29. Para mejorar la privacidad del usuario, el acceso directo a dispositivos de almacenamiento externos / compartidos está en desuso. Cuando una aplicación tiene como destino Build.VERSION_CODES.Q, la ruta devuelta por este método ya no es directamente accesible para las aplicaciones. Las aplicaciones pueden seguir accediendo al contenido almacenado en almacenamiento compartido / externo mediante la migración a alternativas como Context # getExternalFilesDir (String), MediaStore o Intent # ACTION_OPEN_DOCUMENT.

https://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory ()

También a partir de Android.M, los desarrolladores deben solicitar permisos en tiempo de ejecución.

Vea más detalles en la documentación aquí y esta pregunta

Environment.getExternalStorageDirectory () obsoleto en API nivel 29 java

mayank1513
fuente
si alguien está buscando un enlace de desbordamiento de pila y no una copia pegada de documentos de Google, busque aquí stackoverflow.com/questions/57116335/…
Rowan Berry
1
A partir de Android 11, las aplicaciones no pueden crear su propio directorio específico de aplicaciones en el almacenamiento externo.
Darksymphony