Android外部存储-读取,写入,保存文件
Android外部存储可用于写入和保存数据,读取配置文件等。
本文是有关Android内部结构化数据存储的系列教程中Android内部存储教程的延续。
Android外部存储
SD卡等外部存储设备也可以存储应用程序数据,保存到外部存储设备的文件没有安全性。
通常,有两种类型的外部存储:
主要外部存储:内置的共享存储,"用户可以通过插入USB电缆并将其作为驱动器安装在主机上进行访问"。
示例:当我们说Nexus 5 32 GB时。辅助外部存储:可移动存储。
示例:SD卡
所有应用程序都可以读写放置在外部存储器上的文件,并且用户可以删除它们。
我们需要检查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.theitroad.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; } }
- Environment.getExternalStorageState():返回内部SD安装点的路径,例如"/mnt/sdcard"
- getExternalFilesDir():它返回SD卡上Android/data/data/application_package /中的files文件夹的路径。
它用于存储应用程序所需的任何文件(例如从网络下载的图像或者缓存文件)。
卸载应用后,该文件夹中存储的所有数据也将消失。
另外,如果外部存储不可用,我们将使用本教程前面讨论的if条件禁用保存按钮。
以下是我们在android模拟器中运行的应用程序,我们其中将数据写入文件,然后读取它。
注意:请确保您的Android仿真器已配置为具有SD卡,如下面AVD中的图像对话框所示。
转到工具-> Android-> Android虚拟设备,编辑配置->显示高级设置。