Skip to content

Most visited

Recently visited

navigation

Como salvar arquivos

O Android usa um sistema de arquivos parecido com sistemas de arquivos em disco de outras plataformas. Esta lição explica como trabalhar com o sistema de arquivos Android para ler e gravar arquivos com as APIs File .

Um objeto File é adequado para ler ou gravar grandes quantidades de dados em ordem crescente sem saltar de um registro a outro. Por exemplo, é bom para arquivos de imagens ou qualquer troca executada em uma rede.

Esta lição demonstra como executar tarefas básicas relacionadas a arquivos em seu aplicativo. Supõe-se que você já esteja familiarizado com os fundamentos do sistema de arquivos Linux e com APIs de entrada/saída de arquivos padrão no java.io.

Escolher entre armazenamento interno e externo

Todos os dispositivos Android têm duas áreas de armazenamento de arquivos: armazenamento “interno” e “externo”. Estes nomes têm origem no início do Android, quando a maior parte dos dispositivos oferecia memória embutida não volátil (armazenamento interno), além de uma mídia de armazenamento removível, como cartões micro SD (armazenamento externo). Alguns dispositivos dividem o espaço de armazenamento permanente em partições “interna” e “externa”. Assim, mesmo sem uma mídia de armazenamento removível, sempre há dois espaços de armazenamento e o comportamento da API permanece inalterado independentemente da remoção do armazenamento externo. A lista a seguir resume as principais informações sobre cada tipo de espaço de armazenamento.

Armazenamento interno:

  • Está sempre disponível.
  • Os arquivos salvos lá são acessíveis somente pelo seu aplicativo.
  • Quando o usuário desinstala o aplicativo, o sistema exclui todos os arquivos do aplicativo salvos no armazenamento interno.

O armazenamento interno funciona melhor quando você deseja garantir que o usuário e outros aplicativos não tenham acesso aos seus arquivos.

Armazenamento externo:

  • Não está sempre disponível porque o usuário pode montar o armazenamento externo, como um armazenamento USB, e, em alguns casos, removê-lo do dispositivo.
  • É de leitura universal, ou seja, arquivos salvos aqui podem ser lidos em outros dispositivos.
  • Quando o usuário desinstala o aplicativo, o sistema exclui todos os arquivos do aplicativo salvos aqui apenas se estiverem salvos no diretório de getExternalFilesDir().

O armazenamento externo é o melhor local para arquivos que não exigem acesso restrito e para os arquivos que você deseja compartilhar com outros aplicativos ou permitir que o usuário acesse em um computador.

Observação: Antes do Android N, arquivos internos podiam tornar-se acessíveis a outros aplicativo ao relaxar as permissões do sistema de arquivos. Isso não ocorre mais. Se você deseja tornar o conteúdo de um arquivo privado acessível a outros aplicativos, o aplicativo pode usar o FileProvider. Consulte Compartilhamento de arquivos.

Dica: Embora os aplicativos estejam instalados para armazenamento interno por padrão, você pode especificar o atributo android:installLocation no seu manifesto para que seja possível instalar seu aplicativo no armazenamento externo. Os usuários se beneficiam dessa opção quando o tamanho do APK é muito grande e o espaço no armazenamento externo é maior do que no interno. Para obter mais informações, consulte Local de instalação do aplicativo.

Obter permissões para armazenamento externo

Para gravar no armazenamento externo, você deve solicitar a permissão WRITE_EXTERNAL_STORAGE no arquivo de manifesto:

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

Cuidado: atualmente, todos aplicativos podem ler o armazenamento externo sem precisar de permissão especial. No entanto, isso será alterado em lançamentos futuros. Se seu aplicativo precisar ler o armazenamento externo (mas não gravar nele), você deverá declarar a permissão. READ_EXTERNAL_STORAGE. Para garantir que o aplicativo continue a funcionar adequadamente, declare essa permissão agora antes que as mudanças entrem em vigor.

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

No entanto, se seu aplicativo usa a permissão WRITE_EXTERNAL_STORAGE , já existe uma permissão implícita para leitura do armazenamento externo.

Não é necessária permissão para salvar arquivos no armazenamento interno. Seu aplicativo sempre terá permissão para ler e gravar arquivos no diretório de armazenamento interno.

Salvar um arquivo no armazenamento interno

Ao salvar um arquivo no armazenamento interno, você pode obter o diretório adequado como um File chamando um destes dois métodos:

getFilesDir()
Retorna um File que representa um diretório interno para o aplicativo.
getCacheDir()
Retorna um File que representa um diretório interno para os arquivos de cache temporários do aplicativo. Certifique-se de excluir cada arquivo assim que não for mais necessário e estabeleça um limite de tamanho razoável para a quantidade de memória usada em um determinado período, como 1 MB. Se o sistema começar a ficar com pouco espaço de armazenamento, ele poderá excluir arquivos de cache sem avisar.

Para criar um novo arquivo em um desses diretórios, você pode usar o construtor File() passando o File fornecido por um dos métodos acima que especifica o diretório de armazenamento interno. Por exemplo:

File file = new File(context.getFilesDir(), filename);

Outra opção é chamar openFileOutput() para obter um FileOutputStream que grava em um arquivo em seu diretório interno. O exemplo a seguir mostra como gravar texto em um arquivo:

String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;

try {
  outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
  outputStream.write(string.getBytes());
  outputStream.close();
} catch (Exception e) {
  e.printStackTrace();
}

Ou, se precisar armazenar alguns arquivos em cache, você deve usar createTempFile(). Por exemplo, o método a seguir extrai o nome do arquivo de um URL e cria um arquivo com o mesmo nome no diretório de cache interno do aplicativo.

public File getTempFile(Context context, String url) {
    File file;
    try {
        String fileName = Uri.parse(url).getLastPathSegment();
        file = File.createTempFile(fileName, null, context.getCacheDir());
    } catch (IOException e) {
        // Error while creating file
    }
    return file;
}

Observação: o diretório de armazenamento interno do aplicativo é especificado pelo nome do pacote do aplicativo em um local específico do sistema de arquivos Android. Teoricamente, outros aplicativos poderão ler seus arquivos internos se você definir o arquivo para modo leitura. No entanto, o outro aplicativo também precisa conhecer o nome do pacote do seu aplicativo e os nomes dos arquivos. Outros aplicativos não podem navegar nos diretórios internos e não têm permissão para ler nem gravar, a menos que os arquivos sejam explicitamente definidos para permitir tais ações. Portanto, desde que você use MODE_PRIVATE para seus arquivos no armazenamento interno, eles nunca ficarão acessíveis para outros aplicativos.

Salvar um arquivo no armazenamento externo

Como o armazenamento externo pode ficar indisponível — como quando o usuário monta o armazenamento em um PC ou remove o cartão SD que fornece o armazenamento externo — você deve sempre verificar se o volume está disponível antes de acessá-lo. Consulte o estado de armazenamento externo chamando getExternalStorageState(). Se o estado retornado for igual a MEDIA_MOUNTED, os arquivos poderão ser lidos e gravados. Os métodos a seguir ajudam a determinar a disponibilidade de armazenamento:

/* 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;
}

Embora o usuário e outros aplicativos possam modificar o armazenamento externo, há duas categorias de arquivos que poderão ser salvas aqui:

Arquivos públicos
Arquivos que precisam estar livremente disponíveis para o usuário e outros aplicativos. Ao desinstalar o aplicativo, o usuário deve continuar a ter acesso a esses arquivos.

Por exemplo, fotos capturadas pelo aplicativo ou outros arquivos baixados.

Arquivos privados
Arquivos que pertencem ao seu aplicativo e devem ser excluídos na desinstalação. Embora esses arquivos sejam tecnicamente acessíveis pelo usuário e outros aplicativo por estarem no armazenamento externo, eles são, na verdade, arquivos que não têm valor para o usuário fora do aplicativo. Ao desinstalar o aplicativo, o sistema exclui todos os arquivos do diretório privado externo do aplicativo.

Por exemplo, recursos adicionais baixados através do aplicativo ou arquivos de mídia temporários.

Para salvar arquivos públicos no armazenamento externo, use o método getExternalStoragePublicDirectory() para obter um File que representa o diretório correto no armazenamento externo. O método usa um argumento que especifica o tipo de arquivo que você deseja salvar para que eles se organizem de maneira lógica com outros arquivos públicos, como DIRECTORY_MUSIC ou DIRECTORY_PICTURES. Por exemplo:

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;
}

Se deseja salvar os arquivos que são privados para o seu aplicativo, você pode adquirir o diretório adequado chamando getExternalFilesDir() e passando um nome que indique o tipo de diretório que deseja. Cada diretório criado dessa forma é adicionado ao diretório principal que contém todos os arquivos do armazenamento externo do aplicativo que o sistema exclui quando o usuário faz a desinstalação.

Por exemplo, este é um método que pode ser usado para criar um diretório para um álbum de fotos individual:

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

Se nenhum dos nomes predefinidos de subdiretórios atender seus arquivos, você pode, em vez disso, chamar getExternalFilesDir() e passar null. Isso retorna o diretório raiz para o diretório privado do aplicativo no armazenamento externo.

Lembre-se de que getExternalFilesDir() cria um diretório dentro de um diretório que é excluído quando o usuário desinstala o aplicativo. Se os arquivos salvos precisarem estar disponíveis após a desinstalação do aplicativo — como quando seu aplicativo é uma câmera e o usuário deseja manter as fotos — use getExternalStoragePublicDirectory().

Independentemente de você usar getExternalStoragePublicDirectory() para arquivos que são compartilhados ou getExternalFilesDir() para arquivos que são privados do seu aplicativo, é importante que use nomes de diretório fornecidos por constantes da API, como DIRECTORY_PICTURES. Esses nomes de diretório garantem que os arquivos sejam tratados de forma adequada pelo sistema. Por exemplo, arquivos salvos em DIRECTORY_RINGTONES são categorizados pelo scanner de mídia do sistema como toques de telefone em vez de música.

Consultar espaço livre

Se souber de antemão a quantidade de dados a salvar, você pode chamar getFreeSpace() ou getTotalSpace() para descobrir se há espaço suficiente disponível sem causar uma IOException. Esses métodos informam o espaço disponível atual e o espaço total no volume de armazenamento, respectivamente. Essas informações também são úteis para evitar o preenchimento do volume de armazenamento além de um determinado limite.

No entanto, o sistema não garante que será possível gravar a quantidade de bytes indicada por getFreeSpace(). Se o número retornado tiver alguns MB além do tamanho dos dados que deseja salvar ou se o sistema de arquivos estiver abaixo de 90% cheio, é possível continuar com segurança. Caso contrário, não grave no armazenamento.

Observação: Não é obrigatório verificar a quantidade de espaço disponível antes de salvar o arquivo. É possível tentar gravar o arquivo imediatamente e capturar uma IOException, se ocorrer. Essa ação é recomendada caso você não saiba exatamente quanto espaço será necessário. Por exemplo, se você alterar a codificação do arquivo antes de salvá-lo convertendo uma imagem PNG em JPEG, não saberá o tamanho do arquivo antecipadamente.

Excluir um arquivo

Sempre exclua arquivos que não sejam mais necessários. A forma mais simples de excluir um arquivo é fazer com que o arquivo de referência aberto chame delete() por conta própria.

myFile.delete();

Se o arquivo está salvo em armazenamento interno, é possível solicitar ao Context para localizar e excluir o arquivo chamando deleteFile():

myContext.deleteFile(fileName);

Observação: Quando o usuário desinstala o aplicativo, o sistema Android também exclui:

  • Todos os arquivos salvos no armazenamento interno
  • Todos os arquivos que você salvou no armazenamento externo usando getExternalFilesDir().

No entanto, recomenda-se excluir manualmente todos os arquivos em cache criados com getCacheDir() regularmente, bem como excluir regularmente outros arquivos que não sejam mais necessários.

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

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

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.