如何在Android中保存文件到外部存储?


简介

在Android设备中,最实用的功能是存储和读取设备存储或外部存储中的文件。这允许用户扩展其设备存储容量,以便能够根据需要存储和检索文件,并相应地使用它们。本文将探讨如何在Android中将文件保存到外部存储。

实现

我们将创建一个简单的应用程序,其中我们将创建一个TextView来显示应用程序的标题。然后,我们将创建一个EditText字段,从中读取用户想要存储到外部存储中的数据。接下来,我们将添加一个按钮,用于将此数据以文件的形式存储到设备的外部存储或SD卡中。之后,我们将显示一个TextView和另一个按钮,用于读取数据。当用户点击此“读取数据”按钮时,我们将从外部存储读取文件,并将该文件中的数据设置到我们的TextView中。现在让我们转向Android Studio创建一个新项目。

步骤1:在Android Studio中创建一个新项目

导航到Android Studio,如下面的屏幕截图所示。在下面的屏幕中,点击“新建项目”以创建一个新的Android Studio项目。

点击“新建项目”后,您将看到下面的屏幕。

在这个屏幕中,我们只需选择“Empty Activity”并点击“Next”。点击“Next”后,您将看到下面的屏幕。

在这个屏幕中,我们只需指定项目名称。然后包名将自动生成。

注意:确保选择Java作为编程语言。

指定所有详细信息后,点击“Finish”以创建一个新的Android Studio项目。

项目创建完成后,我们将看到两个打开的文件:activity_main.xml和MainActivity.java文件。

步骤2:使用activity_main.xml

导航到activity_main.xml。如果此文件不可见,请在左侧面板中导航到app>res>layout>activity_main.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">
   <!-- on below line creating the heading of our application -->
   <TextView
       android:id="@+id/idTVHeading"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_margin="10dp"
       android:layout_marginTop="90dp"
       android:padding="8dp"
       android:text="Save File in External Storage in Android"
       android:textAlignment="center"
       android:textColor="@color/black"
       android:textSize="20sp"
       android:textStyle="bold" />
   <!-- on below line creating an edit text for storing the data in the file -->
   <EditText
       android:id="@+id/idEdtMessage"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idTVHeading"
       android:layout_margin="10dp"
       android:hint="Enter the data to be saved in the file.."
       android:lines="4" />
   <!-- on below line creating a button to save this image view in external storage-->
   <Button
       android:id="@+id/idBtnSave"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idEdtMessage"
       android:layout_margin="10dp"
       android:text="Save File To External Storage"
       android:textAllCaps="false" />
   <!-- on below line creating a text view for displaying the file data -->
   <TextView
       android:id="@+id/idTVFileData"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idBtnSave"
       android:layout_centerHorizontal="true"
       android:layout_margin="10dp"
       android:padding="4dp"
       android:text="File Data will appear here"
       android:textAlignment="center"
       android:textColor="@color/black"
       android:textSize="18sp" />
   <!-- on below line creating a button to view the file stored in external storage-->
   <Button
       android:id="@+id/idBtnView"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idTVFileData"
       android:layout_margin="10dp"
       android:text="View File Data"
       android:textAllCaps="false" />
</RelativeLayout>

说明:在上面的代码中,我们创建了一个根布局作为相对布局。在这个布局中,我们创建了一个TextView来显示应用程序的标题。之后,我们创建了一个EditText字段,用于获取要存储到文件中的用户输入。然后,我们创建一个按钮,用于生成文件并将文本输入字段中的数据存储到SD卡或外部存储中。之后,我们创建了一个TextView和一个按钮。我们将使用一个按钮从外部存储读取文件,并将该文件中的数据显示在我们创建的TextView中。

步骤3:在AndroidManifest.xml文件中添加权限

导航到app>AndroidManifest.xml文件,并在manifest标签中添加以下权限以读取外部存储。

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

步骤4:使用MainActivity.java文件

导航到MainActivity.java。如果此文件不可见,请在左侧面板中导航到app>java>您的包名>MainActivity.java打开此文件。打开此文件后,将以下代码添加到其中。代码中添加了注释以便详细了解。

package com.example.java_test_application;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.IntentSender;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Telephony;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.auth.api.credentials.CredentialPickerConfig;
import com.google.android.gms.auth.api.credentials.CredentialRequest;
import com.google.android.gms.auth.api.credentials.CredentialRequestResult;
import com.google.android.gms.auth.api.credentials.Credentials;
import com.google.android.gms.auth.api.credentials.CredentialsClient;
import com.google.android.gms.auth.api.credentials.CredentialsOptions;
import com.google.android.gms.auth.api.credentials.HintRequest;
import com.google.android.gms.auth.api.credentials.IdentityProviders;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import org.w3c.dom.Text;
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 java.util.Date;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
   // creating variable for edit text on below line.
   private EditText msgEdt;
   // creating variables for button on below line.
   private Button saveFileBtn, viewFileBtn;
   // creating variable for text view on below line to display the data from the file.
   private TextView dataTV;
   File externalFile;
   private String filename = "file.txt";
   private String filepath = "files";
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       // initializing variables for text view on below line.
       saveFileBtn = findViewById(R.id.idBtnSave);
       viewFileBtn = findViewById(R.id.idBtnView);
       msgEdt = findViewById(R.id.idEdtMessage);
       dataTV = findViewById(R.id.idTVFileData);
       // on below line we are checking if the external storage is available on the device and the external storage is not read only.
       if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
           // if the external storage is not avialable then we are displaying the toast message on below line.
           Toast.makeText(this, "External storage not available on the device..", Toast.LENGTH_SHORT).show();
       } else {
           // on below line we are initializing external file variable and specifying the file path along with file name.
           externalFile = new File(getExternalFilesDir(filepath), filename);
       }
       // on below line adding click listener for save file button.
       saveFileBtn.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               // on below line we are checking if the edit text is empty or not.
               if (msgEdt.getText().toString().isEmpty()) {
                   // if the edit text is empty we are displaying a toast message.
                   Toast.makeText(MainActivity.this, "Please enter your message..", Toast.LENGTH_SHORT).show();
               } else {
                   // on below line checking for the file output stream.
                   try {
                       // on below line creating a file output stream.
                       FileOutputStream fos = new FileOutputStream(externalFile);
                       // on below line writing the data from edit text in file output stream/
                       fos.write(msgEdt.getText().toString().getBytes());
                       // on below line closing the file output stream.
                       fos.close();
                       // on below line displaying toast message as file has been saved.
                       Toast.makeText(MainActivity.this, "File saved to External Storage..", Toast.LENGTH_SHORT).show();
                       // on below line handling the exception.
                   } catch (IOException e) {
                       e.printStackTrace();
                   }
               }
           }
       });
       // on below line adding click listener for view file button.
       viewFileBtn.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               // on below line creating a string variable named as file data.
               String fileData = "";
               try {
                   // on below line creating a variable for file input stream and passing the file path to it.
                   FileInputStream fis = new FileInputStream(externalFile);
                   // on below line creating and initializing variable for data input stream.
                   DataInputStream in = new DataInputStream(fis);
                   // on below line creating and initializing variable for buffer reader.
                   BufferedReader br = new BufferedReader(new InputStreamReader(in));
                   // on below line reading the data from file and appending it to the file data variable.
                   String strLine;
                   while ((strLine = br.readLine()) != null) {
                       fileData = fileData + strLine;
                   }
                   // on below line setting data from variable to our text view.
                   dataTV.setText(fileData);
                   in.close();
                   // on below line handling the exception.
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       });
   }
   // on below line creating a method to checking weather external storage is read only.
   private static boolean isExternalStorageReadOnly() {
       // on below line getting external storage and checking if it is media mounted read only.
       String extStorageState = Environment.getExternalStorageState();
       if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
           return true;
       }
       return false;
   }
   // on below line creating a method to check weather external storage is available or not.
   private static boolean isExternalStorageAvailable() {
       // on below line checking external storage weather it is available or not.
       String extStorageState = Environment.getExternalStorageState();
       if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
           return true;
       }
       return false;
   }
}

说明:在上面的代码中,首先我们为我们的EditText、按钮和TextView创建变量。然后,我们创建一个变量来存储外部文件、文件名和文件路径作为字符串变量。现在我们将看到onCreate方法。这是每个Android应用程序的默认方法。当应用程序视图创建时,将调用此方法。在此方法中,我们设置内容视图,即名为activity_main.xml的布局文件,以设置该文件中的UI。在onCreate方法中,我们使用我们在activity_main.xml文件中给出的ID来初始化按钮、TextView和EditText变量。

之后,我们检查设备中是否存在外部存储,以及我们是否具有读取和写入数据的权限。如果用户在设备中存在外部存储,则我们将使用文件路径和文件名初始化外部文件变量。之后,我们为“保存文件”按钮添加一个点击监听器,在onClick方法中,我们检查EditText字段是否为空。如果EditText字段不为空,则我们创建一个文件输出流并将文本输入字段中的数据存储到该文件中。

之后,我们为“查看文件”按钮添加一个点击监听器。在点击监听器方法中,我们调用文件输入流来读取我们存储的文件中的数据,并将该文件中的数据设置到我们创建的TextView中。最后,我们创建了两个方法,用于检查外部存储是否可用,以及我们是否可以读取外部存储。

添加上述代码后,我们只需点击顶部栏中的绿色图标即可在移动设备上运行我们的应用程序。

注意:确保您已连接到您的真实设备或模拟器。

输出

结论

在本文中,我们探讨了如何在Android中将文件保存到外部存储。

更新于:2023年5月9日

3K+ 浏览量

启动您的职业生涯

完成课程获得认证

开始学习
广告
© . All rights reserved.