Android 外部存储 – 读取、写入、保存文件

Android 外部存储可以用于写入和保存数据、读取配置文件等。本文是在 Android 内部存储教程系列中关于结构化数据存储的延续。

安卓外部存储

外部存储设备,如SD卡,也可以存储应用程序数据,对于保存在外部存储中的文件,没有强制实施的安全措施。一般来说,有两种类型的外部存储。

  • Primary External Storage: In built shared storage which is “accessible by the user by plugging in a USB cable and mounting it as a drive on a host computer”. Example: When we say Nexus 5 32 GB.
  • Secondary External Storage: Removable storage. Example: SD Card

所有应用程序都可以读取和写入放置在外部存储器上的文件,用户可以删除它们。我们需要检查SD卡是否可用以及是否可以对其进行写入。只有在我们确认外部存储器可用后,才可以对其进行写入,否则保存按钮将被禁用。

Android外部存储示例项目结构

首先,我们需要确保应用程序具有读写用户SD卡的权限,所以让我们打开AndroidManifest.xml并添加以下权限:

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

此外,外部存储可能被用户挂载为USB存储设备。因此,我们需要检查外部存储是否可用且非只读。

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()是环境的静态方法,用于确定外部存储是否可用。如您所见,如果条件为假,我们将禁用保存按钮。

Android 外部存储示例代码

activity_main.xml布局的定义如下:

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

除保存和读取外部存储按钮外,我们在一个文本视图中显示保存/读取外部存储的响应,而不像之前的教程中显示 Android toast。以下是MainActivity.java类。

package com.Olivia.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():返回内部SD卡挂载点的路径,如“/mnt/sdcard”

 

    getExternalFilesDir():它返回SD卡上Android/data/data/application_package/内的文件夹路径。它用于存储应用程序所需的任何文件(例如从网络下载的图像或缓存文件)。一旦卸载应用程序,存储在此文件夹中的任何数据也将被删除。

如果外部存储不可用,我们将使用前面在本教程中讨论过的if条件来禁用保存按钮。下面是我们的应用在Android模拟器上运行,我们正在将数据写入文件,然后读取它。注意:请确保您的Android模拟器配置为具有SD卡,如下图所示的AVD对话框。转到“工具”->“Android”->“Android虚拟设备”,编辑配置->“显示高级设置”。本教程到此结束。我们将在下一个教程中讨论使用共享首选项来存储。您可以从以下链接下载最终的Android外部存储项目。

下载Android外部存储示例工程。

发表回复 0

Your email address will not be published. Required fields are marked *


广告
将在 10 秒后关闭
bannerAds