Almacenamiento externo de Android – Leer, Escribir, Guardar Archivo

El almacenamiento externo de Android se puede utilizar para escribir y guardar datos, leer archivos de configuración, etc. Este artículo es una continuación del tutorial de Almacenamiento Interno de Android en la serie de tutoriales sobre almacenamiento de datos estructurados en Android.

Almacenamiento Externo de Android

El almacenamiento externo, como la tarjeta SD, también puede almacenar datos de la aplicación, no hay seguridad aplicada a los archivos que guarda en el almacenamiento externo. En general, hay dos tipos de Almacenamiento Externo:

  • Almacenamiento Externo Primario: Almacenamiento compartido integrado que es “accesible por el usuario al conectar un cable USB y montarlo como una unidad en una computadora host”. Ejemplo: Cuando decimos Nexus 5 de 32 GB.
  • Almacenamiento Externo Secundario: Almacenamiento extraíble. Ejemplo: Tarjeta SD

Todas las aplicaciones pueden leer y escribir archivos ubicados en el almacenamiento externo y el usuario puede eliminarlos. Necesitamos verificar si la tarjeta SD está disponible y si podemos escribir en ella. Una vez que hayamos comprobado que el almacenamiento externo está disponible, solo entonces podemos escribir en él; de lo contrario, el botón de guardar estaría desactivado.

Ejemplo de Estructura de Proyecto de Almacenamiento Externo en Android

En primer lugar, necesitamos asegurarnos de que la aplicación tenga permiso para leer y escribir datos en la tarjeta SD del usuario, así que abramos el archivo AndroidManifest.xml y agreguemos los siguientes permisos:

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

Además, el almacenamiento externo puede estar ocupado si el usuario lo ha montado como un dispositivo de almacenamiento USB. Así que necesitamos verificar si el almacenamiento externo está disponible y no es de solo lectura.

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() es un método estático de Environment para determinar si el almacenamiento externo está disponible en el momento o no. Como puedes ver, si la condición es falsa, hemos deshabilitado el botón de guardar.

Código de Ejemplo de Almacenamiento Externo en Android

El diseño activity_main.xml está definido de la siguiente manera:

<?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>

Aquí, además de los botones de guardar y leer desde el almacenamiento externo, mostramos la respuesta de guardar/leer en/desde un almacenamiento externo en un TextView, a diferencia del tutorial anterior donde se mostraba un android toast. La clase MainActivity.java se presenta a continuación:

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(): devuelve la ruta al punto de montaje de la tarjeta SD interna, como “/mnt/sdcard”
  2. getExternalFilesDir(): devuelve la ruta a la carpeta de archivos dentro de Android/data/data/application_package/ en la tarjeta SD. Se utiliza para almacenar cualquier archivo necesario para su aplicación (como imágenes descargadas de la web o archivos de caché). Una vez que se desinstala la aplicación, cualquier dato almacenado en esta carpeta desaparece también.

También, si el almacenamiento externo no está disponible, desactivamos el botón de guardar usando la condición if que se discutió anteriormente en este tutorial. A continuación se muestra nuestra aplicación ejecutándose en el emulador de Android, donde estamos escribiendo datos en un archivo y luego leyéndolos. Nota: Asegúrate de que tu Emulador de Android esté configurado de manera que tenga una tarjeta SD como se muestra en el cuadro de diálogo de AVD a continuación. Ve a Herramientas -> Android -> Dispositivo Virtual de Android, editar configuraciones -> Mostrar configuraciones avanzadas. Esto concluye este tutorial. Discutiremos el almacenamiento utilizando Preferencias Compartidas en el próximo tutorial. Puedes descargar el Proyecto de Ejemplo Final de Almacenamiento Externo de Android desde el siguiente enlace.

Descargar Proyecto de Ejemplo de Almacenamiento Externo de Android

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