Almacenamiento externo en Android con ejemplo

Android ofrece varias opciones para almacenar datos de aplicaciones que utilizan un sistema de archivos similar al sistema basado en disco en plataformas informáticas

  • Almacenamiento específico de la aplicación: almacene archivos de datos en directorios de volúmenes internos o externos. Estos archivos de datos están destinados solo para el uso de la aplicación. Utiliza directorios de almacenamiento interno para guardar información confidencial, como un nombre de usuario y una contraseña, a los que otras aplicaciones no deben acceder.
  • Almacenamiento compartido: almacena archivos de datos como imágenes, audio, video, documentos, etc. que la aplicación puede necesitar compartir con otras aplicaciones.
  • Preferencias compartidas: almacene tipos de datos primitivos como enteros, flotantes, booleanos, strings, largos en pares clave-valor.
  • Bases de datos: almacene datos estructurados, como información del usuario (nombre, edad, teléfono, correo electrónico, dirección, etc.) en bases de datos privadas.

Se recomienda a los desarrolladores que utilicen las opciones disponibles para almacenar datos según el espacio requerido , el acceso confiable a los datos y la privacidad de los datos . Los archivos de datos guardados en dispositivos de almacenamiento externo son de acceso público en el almacenamiento externo compartido mediante la transferencia de almacenamiento masivo USB. Los archivos de datos almacenados en almacenamiento externo mediante un objeto FileOutputStream y se pueden leer mediante un objeto FileInputStream .

Disponibilidad de almacenamiento externo

Para evitar bloquear la aplicación primero, debemos verificar que la tarjeta SD de almacenamiento esté disponible para operaciones de lectura y escritura. El método getExternalStorageState() se usa para determinar el estado de los medios de almacenamiento montados, como si falta la tarjeta SD, es de solo lectura o se puede leer y escribir. A continuación se muestra el fragmento de código que utilizaremos para comprobar la disponibilidad de almacenamiento externo.

Java

boolean isAvailable= false;
boolean isWritable= false;
boolean isReadable= false;
String state = Environment.getExternalStorageState();
  
if(Environment.MEDIA_MOUNTED.equals(state)) {
  // Operation possible - Read and Write
  isAvailable= true;
  isWritable= true;
  isReadable= true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
      // Operation possible - Read Only
      isAvailable= true;
      isWritable= false;
      isReadable= true;
} else {
      // SD card not available
      isAvailable = false;
      isWritable= false;
      isReadable= false; 
}

Métodos para almacenar datos en almacenamiento externo

  • getExternalStoragePublicDirectory(): este es el método recomendado actualmente para mantener los archivos públicos y estos archivos no se eliminan incluso cuando la aplicación se desinstala del sistema. Por ejemplo: las imágenes en las que la cámara hace clic todavía están disponibles incluso después de desinstalar la cámara.
  • getExternalFilesDir (tipo de string): este método se usa para almacenar datos privados que son específicos de la aplicación únicamente. Y los datos se eliminan a medida que desinstalamos la aplicación.
  • getExternalStorageDirectory(): no se recomienda este método. Ahora es absoluto y se usa para acceder al almacenamiento externo en versiones anteriores, nivel de API inferior a 7.

Ejemplo

En este ejemplo, almacenaríamos datos de texto en el almacenamiento externo y buscaríamos para ver esos datos. whatTenga en cuenta que vamos a implementar este proyecto utilizando el lenguaje Java

ExternalStorage In Android

Implementación paso a paso

Paso 1: Crear un nuevo proyecto

Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Tenga en cuenta que seleccione Java como lenguaje de programación.

Paso 2: Permiso de acceso al almacenamiento externo

Para leer y escribir datos en el almacenamiento externo, la aplicación requería el permiso del sistema WRITE_EXTERNAL_STORAGE y READ_EXTERNAL_STORAGE . Estos permisos se agregan al archivo AndroidManifest.xml . Agregue estos permisos justo después del nombre del paquete.

XML

<manifest ... >
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
    <application ... >
        <activity android:name=".MainActivity" ... >
          ...
        </activity>
    </application>
</manifest>

Paso 3: antes de crear el diseño y los archivos java correspondientes, agreguemos algunos atributos de string que estamos usando en nuestros archivos de diseño

Vaya a aplicación > res > valores > string.xml e inserte el siguiente fragmento de código

XML

<resources>
  ...
    <string name="text_view_data">Enter the Text Data</string>
    <string name="edit_text_data">Enter your information</string>
    <string name="view_button">View Information</string>
    <string name="save_button_public">Save Publicly</string>
    <string name="save_button_private">Save Privately</string>
  
    <string name="text_view_saved_data">Saved Text Data</string>
    <string name="saved_information">Click to view saved information</string>
    <string name="back_button">Go Back</string>
    <string name="show_button_public">Public Data</string>
    <string name="show_button_private">Private Data</string>
  ...
</resources>

Ahora vaya a aplicación > res > valores > colores.xml y cambie los atributos de color de la siguiente manera para que la barra de aplicaciones sea más atractiva.

XML

<resources>   
    <color name="colorPrimary">#0F9D58</color>
    <color name="colorPrimaryDark">#16E37F</color>
    <color name="colorAccent">#03DAC5</color>
  
    <color name="buttonColor">#0F9D58</color>
    <color name="textColor">#FFFFFF</color>
</resources>

Vuelva a ir a app > res > drawable y cree un nuevo archivo de recursos Drawable y asígnele el nombre button_layout . En esto, estamos modificando el estilo de nuestro botón para una mejor UX/UI.

XML

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
  
    <corners
        android:bottomLeftRadius="25dp"
        android:bottomRightRadius="25dp"
        android:radius="50dp"
        android:topLeftRadius="25dp"
        android:topRightRadius="25dp" />
  
    <padding
        android:bottom="0dp"
        android:left="0dp"
        android:right="0dp"
        android:top="0dp" />
  
    <size
        android:width="64dp"
        android:height="16dp" />
  
    <solid android:color="@color/buttonColor" />
  
</shape>

Paso 4: trabajar con el archivo activity_main.xml

Vaya a res > diseño > actividad_principal.xml y escriba el siguiente código. En este archivo de diseño, estamos creando una vista EditText de varias líneas para obtener los datos de los usuarios y los botones para guardar esos datos en medios de almacenamiento internos y externos.

XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
  
    <Button
        android:id="@+id/saveButton_public"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_below="@+id/editText_data"
        android:layout_marginEnd="48dp"
        android:layout_marginTop="8dp"
        android:background="@drawable/button_layout"
        android:onClick="savePublicly"
        android:padding="8dp"
        android:text="@string/save_button_public"
        android:textAllCaps="false"
        android:textColor="@color/textColor" />
  
    <Button
        android:id="@+id/saveButton_private"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/editText_data"
        android:layout_marginStart="48dp"
        android:layout_marginTop="8dp"
        android:layout_toEndOf="@+id/saveButton_public"
        android:background="@drawable/button_layout"
        android:onClick="savePrivately"
        android:padding="8dp"
        android:text="@string/save_button_private"
        android:textAllCaps="false"
        android:textColor="@color/textColor" />
  
    <Button
        android:id="@+id/viewButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/saveButton_public"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16dp"
        android:background="@drawable/button_layout"
        android:onClick="viewInformation"
        android:padding="8dp"
        android:text="@string/view_button"
        android:textAllCaps="false"
        android:textColor="@color/textColor" />
  
    <EditText
        android:id="@+id/editText_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView_data"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:autofillHints=""
        android:hint="@string/edit_text_data"
        android:inputType="textMultiLine" />
  
    <TextView
        android:id="@+id/textView_data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:text="@string/text_view_data"
        android:textAllCaps="true"
        android:textStyle="bold" />
  
</RelativeLayout>

Paso 5: trabajar con el archivo MainActivity.java

En MainActivity definimos las funciones que manejaron el comportamiento onClick de los botones. Y obtenga los datos de EditText y guárdelos en un almacenamiento externo de forma pública y privada. También mostramos un mensaje Toast de la ruta donde se almacenan los datos.

Java

import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
  
public class MainActivity extends AppCompatActivity {
  
    // After API 23 the permission request for accessing external storage is changed
    // Before API 23 permission request is asked by the user during installation of app
    // After API 23 permission request is asked at runtime
    private int EXTERNAL_STORAGE_PERMISSION_CODE = 23;
    EditText editText;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
          
        // findViewById return a view, we need to cast it to EditText View
        editText = (EditText) findViewById(R.id.editText_data);
    }
  
    public void savePublicly(View view) {
        // Requesting Permission to access External Storage
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
                EXTERNAL_STORAGE_PERMISSION_CODE);
        String editTextData = editText.getText().toString();
          
        // getExternalStoragePublicDirectory() represents root of external storage, we are using DOWNLOADS
        // We can use following directories: MUSIC, PODCASTS, ALARMS, RINGTONES, NOTIFICATIONS, PICTURES, MOVIES
        File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
          
        // Storing the data in file with name as geeksData.txt
        File file = new File(folder, "geeksData.txt");
        writeTextData(file, editTextData);
        editText.setText("");
    }
  
    public void savePrivately(View view) {
        String editTextData = editText.getText().toString();
          
        // Creating folder with name GeekForGeeks
        File folder = getExternalFilesDir("GeeksForGeeks");
          
        // Creating file with name gfg.txt
        File file = new File(folder, "gfg.txt");
        writeTextData(file, editTextData);
        editText.setText("");
    }
  
    public void viewInformation(View view) {
        // Creating an intent to start a new activity
        Intent intent = new Intent(MainActivity.this, ViewInformationActivity.class);
        startActivity(intent);
    }
  
    // writeTextData() method save the data into the file in byte format
    // It also toast a message "Done/filepath_where_the_file_is_saved"
    private void writeTextData(File file, String data) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(data.getBytes());
            Toast.makeText(this, "Done" + file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Paso 6: crea una nueva actividad vacía

Crearemos una nueva actividad y la llamaremos ViewInformationActivity . Usamos esta actividad para mostrar los datos guardados del almacenamiento externo. Entonces, primero, creamos un diseño para esta actividad similar al diseño MainActivity. fragmento de código de diseño activity_view_information.xml :

XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
       xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ViewInformationActivity">
  
    <Button
        android:id="@+id/showButton_public"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_below="@+id/textView_get_saved_data"
        android:layout_marginEnd="48dp"
        android:layout_marginTop="8dp"
        android:background="@drawable/button_layout"
        android:onClick="showPublicData"
        android:padding="8dp"
        android:text="@string/show_button_public"
        android:textAllCaps="false"
        android:textColor="@color/textColor" />
  
    <Button
        android:id="@+id/showButton_private"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/textView_get_saved_data"
        android:layout_marginStart="48dp"
        android:layout_marginTop="8dp"
        android:layout_toEndOf="@+id/showButton_public"
        android:background="@drawable/button_layout"
        android:onClick="showPrivateData"
        android:padding="8dp"
        android:text="@string/show_button_private"
        android:textAllCaps="false"
        android:textColor="@color/textColor" />
  
    <Button
        android:id="@+id/goBackButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/showButton_public"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16dp"
        android:background="@drawable/button_layout"
        android:onClick="back"
        android:padding="8dp"
        android:text="@string/back_button"
        android:textAllCaps="false"
        android:textColor="@color/textColor" />
  
    <TextView
        android:id="@+id/textView_get_saved_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView_saved_data"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:hint="@string/saved_information" />
  
    <TextView
        android:id="@+id/textView_saved_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:text="@string/text_view_saved_data"
        android:textAllCaps="true"
        android:textStyle="bold" />
  
</RelativeLayout>

Ahora, crearemos un código java correspondiente para ViewInformationActivity . En esto, definimos los métodos showPublicData() y showPrivateData() sobre botones que obtendrán los datos de los archivos guardados en el almacenamiento externo y agregarán los datos al búfer, y luego completarán los datos en TextView para mostrarlos. Fragmento de código de ViewInformationAcity.java :

Java

import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
  
public class ViewInformationActivity extends AppCompatActivity {
  
    TextView textView;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_information);
          
        // findViewById returns a view, we need to cast it into TextView
        textView = (TextView) findViewById(R.id.textView_get_saved_data);
    }
  
    public void showPublicData(View view) {
        // Accessing the saved data from the downloads folder
        File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
          
        // geeksData represent the file data that is saved publicly
        File file = new File(folder, "geeksData.txt");
        String data = getdata(file);
        if (data != null) {
            textView.setText(data);
        } else {
            textView.setText("No Data Found");
        }
    }
  
    public void showPrivateData(View view) {
          
        // GeeksForGeeks represent the folder name to access privately saved data
        File folder = getExternalFilesDir("GeeksForGeeks");
          
        // gft.txt is the file that is saved privately
        File file = new File(folder, "gfg.txt");
        String data = getdata(file);
        if (data != null) {
            textView.setText(data);
        } else {
            textView.setText("No Data Found");
        }
    }
  
    public void back(View view) {
        Intent intent = new Intent(ViewInformationActivity.this, MainActivity.class);
        startActivity(intent);
    }
  
    // getdata() is the method which reads the data
    // the data that is saved in byte format in the file
    private String getdata(File myfile) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(myfile);
            int i = -1;
            StringBuffer buffer = new StringBuffer();
            while ((i = fileInputStream.read()) != -1) {
                buffer.append((char) i);
            }
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

Salida: ejecutar en el emulador

Publicación traducida automáticamente

Artículo escrito por ankur035 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *