Armazenamento Externo no Android – Ler, Escrever, Salvar Arquivo

O armazenamento externo do Android pode ser usado para escrever e salvar dados, ler arquivos de configuração etc. Este artigo é uma continuação do tutorial sobre o Armazenamento Interno do Android na série de tutoriais sobre armazenamento de dados estruturados no Android.

Armazenamento Externo do Android

O armazenamento externo, como o cartão SD, também pode armazenar dados do aplicativo, sem segurança aplicada aos arquivos que você salva no armazenamento externo. Em geral, existem dois tipos de armazenamento externo:

  • Armazenamento Externo Primário: Armazenamento compartilhado integrado que é “acessível pelo usuário conectando um cabo USB e montando-o como uma unidade em um computador host”. Exemplo: Quando dizemos Nexus 5 32 GB.
  • Armazenamento Externo Secundário: Armazenamento removível. Exemplo: Cartão SD

Todos os aplicativos podem ler e escrever arquivos colocados no armazenamento externo e o usuário pode removê-los. Precisamos verificar se o cartão SD está disponível e se podemos escrever nele. Somente após verificarmos que o armazenamento externo está disponível, podemos escrever nele, caso contrário, o botão de salvar será desativado.

Exemplo de Estrutura de Projeto de Armazenamento Externo do Android

Primeiramente, precisamos garantir que o aplicativo tenha permissão para ler e gravar dados no cartão SD do usuário, então vamos abrir o AndroidManifest.xml e adicionar as seguintes permissões:

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

Também, o armazenamento externo pode estar ocupado pelo usuário, pois pode estar montado como um dispositivo de armazenamento USB. Portanto, precisamos verificar se o armazenamento externo está disponível e não é somente leitura.

if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {  
   saveButton.setEnabled(false);
  }  

private static boolean isExternalStorageReadOnly() {  
  String extStorageState = Environment.getExternalStorageState();  
  if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {  
   return true;  
  }  
  return false;  
 }  
 
 private static boolean isExternalStorageAvailable() {  
  String extStorageState = Environment.getExternalStorageState();  
  if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {  
   return true;  
  }  
  return false;  
 }  

getExternalStorageState() é um método estático de Environment para determinar se o armazenamento externo está atualmente disponível ou não. Como você pode ver, se a condição for falsa, desativamos o botão de salvar.

Código de Exemplo de Armazenamento Externo do Android

O layout activity_main.xml é definido da seguinte forma:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:orientation="vertical">

    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Reading and Writing to External Storage"
        android:textSize="24sp"/>

    <EditText android:id="@+id/myInputText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" android:lines="5"
        android:minLines="3" android:gravity="top|left"
        android:inputType="textMultiLine">

        <requestFocus />
    </EditText>

    <LinearLayout
    android:layout_width="match_parent" android:layout_height="wrap_content"
    android:orientation="horizontal"
        android:weightSum="1.0"
        android:layout_marginTop="20dp">

    <Button android:id="@+id/saveExternalStorage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="SAVE"
        android:layout_weight="0.5"/>

    <Button android:id="@+id/getExternalStorage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.5"
        android:text="READ" />

    </LinearLayout>

    <TextView android:id="@+id/response"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:padding="5dp"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceMedium" />

</LinearLayout>

Aqui, além dos botões de salvar e ler do armazenamento externo, exibimos a resposta de salvar/ler para/de um armazenamento externo em um TextView, ao contrário do tutorial anterior, onde o Android Toast era exibido. A classe MainActivity.java é fornecida abaixo:

package com.journaldev.externalstorage;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import android.os.Bundle;
import android.app.Activity;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;


public class MainActivity extends Activity {
    EditText inputText;
    TextView response;
    Button saveButton,readButton;

    private String filename = "SampleFile.txt";
    private String filepath = "MyFileStorage";
    File myExternalFile;
    String myData = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        inputText = (EditText) findViewById(R.id.myInputText);
        response = (TextView) findViewById(R.id.response);


         saveButton =
                (Button) findViewById(R.id.saveExternalStorage);
        saveButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    FileOutputStream fos = new FileOutputStream(myExternalFile);
                    fos.write(inputText.getText().toString().getBytes());
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                inputText.setText("");
                response.setText("SampleFile.txt saved to External Storage...");
            }
        });

        readButton = (Button) findViewById(R.id.getExternalStorage);
        readButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    FileInputStream fis = new FileInputStream(myExternalFile);
                    DataInputStream in = new DataInputStream(fis);
                    BufferedReader br =
                            new BufferedReader(new InputStreamReader(in));
                    String strLine;
                    while ((strLine = br.readLine()) != null) {
                        myData = myData + strLine;
                    }
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                inputText.setText(myData);
                response.setText("SampleFile.txt data retrieved from Internal Storage...");
            }
        });

        if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
            saveButton.setEnabled(false);
        }
        else {
            myExternalFile = new File(getExternalFilesDir(filepath), filename);
        }


    }
    private static boolean isExternalStorageReadOnly() {
        String extStorageState = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
            return true;
        }
        return false;
    }

    private static boolean isExternalStorageAvailable() {
        String extStorageState = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
            return true;
        }
        return false;
    }


}
  1. Environment.getExternalStorageState(): retorna o caminho para o ponto de montagem do SD interno, como “/mnt/sdcard”
  2. getExternalFilesDir(): Retorna o caminho para a pasta de arquivos dentro de Android/data/data/application_package/ no cartão SD. É usado para armazenar quaisquer arquivos necessários para o seu aplicativo (como imagens baixadas da web ou arquivos de cache). Uma vez que o aplicativo é desinstalado, qualquer dado armazenado nesta pasta também é excluído.

Também, se o armazenamento externo não estiver disponível, desabilitamos o botão de salvar usando a condição if que foi discutida anteriormente neste tutorial. Abaixo está nossa aplicação rodando no emulador Android, onde estamos escrevendo dados no arquivo e então lendo-os. Observação: Certifique-se de que seu Emulador Android esteja configurado de forma que tenha um cartão SD, conforme mostrado na caixa de diálogo da AVD abaixo. Vá para Ferramentas -> Android -> Dispositivo Virtual Android, edite as configurações -> Mostrar Configurações Avançadas. Isso encerra este tutorial. Vamos discutir o armazenamento usando Preferências Compartilhadas no próximo tutorial. Você pode baixar o Projeto de Exemplo Final de Armazenamento Externo do Android no link abaixo.

Baixar Projeto de Exemplo de Armazenamento Externo Android

Source:
https://www.digitalocean.com/community/tutorials/android-external-storage-read-write-save-file