Diferença entre getExternalFilesDir e getExternalStorageDirectory ()

88

Eu entendo que ExternalFiles deve ser usado na API 8 e superior e getExternalStorageDirectory é para 7 e inferior. Porém estou um pouco confuso quanto ao uso. Por exemplo, eu queria verificar se existe uma pasta e anteriormente você usaria algo como:

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

No entanto, todos os exemplos que vejo dizem para usar getExternalFilesDir (null), File.ext. Como estou acima da API 8, desejo usar este método, mas como faço para verificar se há uma pasta? Vou verificar a existência de arquivos em outro ponto, mas por enquanto só quero ver se as pastas existem ??

GPGVM
fonte

Respostas:

132
getExternalFilesDir()

Ele retorna o caminho para a pasta de arquivos dentro de Android / data / data / your_package / em seu cartão SD. Ele é usado para armazenar todos os arquivos necessários para o seu aplicativo (por exemplo, imagens baixadas da web ou arquivos de cache). Depois que o aplicativo é desinstalado, todos os dados armazenados nesta pasta também desaparecem.

getExternalStorageDirectory()

Ele retorna o caminho raiz para o seu cartão SD (por exemplo, mnt / sdcard / ). Se você salvar dados neste caminho e desinstalar o aplicativo, esses dados não serão perdidos.

waqaslam
fonte
4
O Google Android deseja que você use tudo o que eles fornecem na estrutura. Portanto, depende da sua escolha e dos requisitos de design. Se você não quiser que os arquivos permaneçam quando o aplicativo for desinstalado, recomendamos usar getExternalFilesDir () ou getExternalCacheDir ()
waqaslam
5
É porque na API 8, eles introduziram recursos avançados de varredura de mídia que permitem escanear dados de pastas como músicas, imagens, tons de toque, etc. Esses diretórios são criados automaticamente apenas se você usar getExternalFilesDir () . Agora, como esse recurso não estava disponível na API 7, é por isso que eles recomendaram usar getExternalStorageDirectory () . Simples ...
waqaslam
2
tudo bem,
espere
3
É importante saber que getExternalStorageDirectory()não não necessariamente - talvez até mesmo geralmente não - "caminho para o seu cartão SD" devolver o Em vez disso, ele retorna o "diretório de armazenamento externo primário". Os documentos ( developer.android.com/reference/android/os/… ) dizem:
LarsH
2
'Nota: não se confunda com a palavra "externo" aqui. Este diretório pode ser melhor considerado como mídia / armazenamento compartilhado. É um sistema de arquivos que pode conter uma quantidade relativamente grande de dados e que é compartilhado por todos os aplicativos (não impõe permissões). Tradicionalmente, este é um cartão SD , mas também pode ser implementado como armazenamento embutido em um dispositivo que é diferente do armazenamento interno protegido e pode ser montado como um sistema de arquivos em um computador. '
LarsH
69

Em primeiro lugar, precisamos entender qual é a diferença entre armazenamento interno, armazenamento externo (também conhecido como armazenamento externo primário) e armazenamento externo secundário.

Armazenamento interno: é o armazenamento que não pode ser acessado pelo usuário, exceto por meio de aplicativos instalados (ou através do enraizamento do dispositivo). Exemplo: data / data / app_packageName

Armazenamento externo primário: Em armazenamento compartilhado integrado que é "acessível ao usuário conectando um cabo USB e montando-o como uma unidade em um computador host". Exemplo: quando dizemos Nexus 5 de 32 GB.

Armazenamento externo secundário: armazenamento removível. Exemplo: cartão SD.

getExternalFilesDir (String type)

Ele retorna o caminho para a pasta de arquivos dentro de Android / data / data / your_package / no armazenamento externo primário. Que é o armazenamento embutido.

Environment.getExternalStorageDirectory(type)

Ele retornará o caminho do diretório de armazenamento externo secundário

Vikasdeep Singh
fonte
Obrigado por explicar os diferentes tipos de armazenamento. No entanto, talvez edite o item de armazenamento interno para mencionar que a chamada do método para obter esse valor é getFilesDir (). Bem, acho que esse método realmente retorna data / data / app_packageName / files, mas ainda é um armazenamento interno.
raddevus de
3
@VicJordan Por favor, escreva sobre File getExternalStoragePublicDirectory (String type)e File getFilesDir ()também
AnV
2
Obrigado, Vic. Environment.getExternalStorageDirectory () outputs / storage / emulado / 0
gimmegimme
Você tem alguma documentação para a declaração de que o armazenamento externo primário é sempre integrado, enquanto o secundário é sempre removível? Achei que fossem questões independentes ... alguns telefones não têm armazenamento "externo" integrado, caso em que o armazenamento externo primário pode ser o cartão SD removível.
LarsH
@LarsH, de acordo com meu conhecimento atualmente não há nenhum telefone no mercado ou em um futuro próximo que não tenha armazenamento externo primário integrado. Havia telefones na época do pão de mel, quando esses telefones existiam, mas não agora. Você poderia citar "alguns" telefones que não têm "armazenamento externo primário" integrado?
Vikasdeep Singh
17

! ATUALIZAÇÃO IMPORTANTE ! para quem se depara com esta questão.

Como esta é uma questão um tanto antiga, só queria fornecer algumas informações adicionais. Desde o KitKat, mesmo os aplicativos que têm permissão WRITE_EXTERNAL_STORAGE têm permissão para gravar em Android / data / data / your_package / em armazenamento externo, também conhecido como getExternalFilesDir()

Se você tentar escrever para getExternalStorageDirectory() + "/somefolder/anotherfolder/", obterá uma SecurityException na maioria dos dispositivos

SGal
fonte
9
De acordo com os documentos, os aplicativos que têm a permissão WRITE_EXTERNAL_STORAGE PODEM gravar no armazenamento externo de outros pacotes, não apenas no seu. São aplicativos que NÃO têm permissão que só podem gravar em seu próprio diretório: developer.android.com/reference/android/content/… "A partir do KITKAT, nenhuma permissão é necessária para ler ou gravar no caminho retornado; é sempre acessível ao aplicativo de chamada ... Para acessar caminhos pertencentes a outros pacotes, WRITE_EXTERNAL_STORAGE e / ou READ_EXTERNAL_STORAGE são necessários. "
Oded de
É aqui que "na maioria dos dispositivos" começa a importar, à medida que os documentos do Android generalizam a ideia, mas os fabricantes às vezes têm coisas como InternalStorage (armazenamento integrado para dados de aplicativos), ExternalStorage-Primary ( também armazenamento integrado com um escopo de acesso maior) e ExternalStorage-Secondary (seriam coisas montadas como cartões SD). Agora você pode adivinhar qual caminho o External StorageDirectory retorna
SGal
7
Isso não resolve as informações incorretas em sua resposta. "Desde o KitKat, mesmo os aplicativos que têm permissão WRITE_EXTERNAL_STORAGE só têm permissão para gravar em Android / data / data / your_package / em armazenamento externo, também conhecido como getExternalFilesDir ()". De acordo com os documentos, isso está errado. Com WRITE_EXTERNAL_STORAGE, os aplicativos podem gravar em todo o armazenamento externo.
Oded de
1
@Oded, você testou isso? Meu entendimento dos documentos e minha experiência com o KitKat e dispositivos posteriores são diferentes dos seus. (Gostaria de ter tempo para discutir todos os detalhes agora. Talvez mais tarde.) Minha experiência é que SGal está certo. E também tem o Lollipop que é um pouco diferente.
LarsH
2
Essa resposta é flagrantemente falsa, de acordo com a documentação do Android. Consulte developer.android.com/reference/android/… "A partir da API de nível 19, esta permissão não é necessária para ler / gravar arquivos em seus diretórios específicos do aplicativo retornados por getExternalFilesDir (String) e getExternalCacheDir ()." (Observe que nível de API 19 = KitKat.) Não tenho ideia de como ele obteve tantos votos positivos.
Ajedi32
6

!! IMPORTANTE !!

Environment.getExternalStorageDirectory()está obsoleto e Context # getExternalFilesDir (String), MediaStore ou Intent # ACTION_OPEN_DOCUMENT deve ser usado em seu lugar.

Este método foi descontinuado na API de nível 29. Para melhorar a privacidade do usuário, o acesso direto a dispositivos de armazenamento externo / compartilhado foi descontinuado. Quando um aplicativo é direcionado a Build.VERSION_CODES.Q, o caminho retornado desse método não é mais acessível diretamente aos aplicativos. Os aplicativos podem continuar a acessar o conteúdo armazenado em armazenamento compartilhado / externo migrando para alternativas como Context # getExternalFilesDir (String), MediaStore ou Intent # ACTION_OPEN_DOCUMENT.

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

Também começando pelo Android.M, os desenvolvedores precisam pedir permissões em tempo de execução.

Veja mais detalhes na documentação aqui e esta questão

Environment.getExternalStorageDirectory () obsoleto na API de nível 29 java

mayank1513
fonte
se alguém estiver procurando por um link de estouro de pilha e não algo copiado colado do google docs, olhe aqui stackoverflow.com/questions/57116335/…
Rowan Berry
1
A partir do Android 11, os aplicativos não podem criar seu próprio diretório específico do aplicativo no armazenamento externo.
Darksymphony