Android外部存储可以用来写入和保存数据,读取配置文件等。本文是Android结构化数据存储系列教程中[Android内部存储](/community/tutorials/android-internal-storage-example-tutorial)教程的延续。
Android外部存储
SD卡等外部存储也可以存储应用程序数据,您保存到外部存储的文件不会受到任何安全保护。通常,有两种类型的外部存储:
- 主外部存储 :内置共享存储,用户可以通过插入USB数据线并将其作为驱动器安装到主机上进行访问。例如:当我们说Nexus 5 32 GB时。
- 辅助外部存储 :可移动存储。示例:SD卡
所有应用程序都可以读写放置在外部存储上的文件,并且用户可以删除它们。我们需要检查SD卡是否可用,以及我们是否可以写入它。一旦我们检查了外部存储是否可用,我们就可以对其进行写入,否则保存按钮将被禁用。
Android外部存储示例项目结构
首先,我们需要确保应用程序对用户SD卡有读写权限,所以我们打开
androidManifest.xml
,添加如下权限:
1<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
此外,外部存储可由用户将其安装为USB存储设备来占用。因此,我们需要检查外部存储是否可用且不是只读的。
1if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
2 saveButton.setEnabled(false);
3 }
4
5private static boolean isExternalStorageReadOnly() {
6 String extStorageState = Environment.getExternalStorageState();
7 if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
8 return true;
9 }
10 return false;
11 }
12
13 private static boolean isExternalStorageAvailable() {
14 String extStorageState = Environment.getExternalStorageState();
15 if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
16 return true;
17 }
18 return false;
19 }
getExternalStorageState()
是Environment
的静态方法,用于判断外部存储当前是否可用。如您所见,如果条件为假,我们已经禁用了保存按钮。
Android外部存储示例代码
active_main.xml 布局定义如下:
1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
3 android:layout_width="fill_parent" android:layout_height="fill_parent"
4 android:orientation="vertical">
5
6 <TextView android:layout_width="fill_parent"
7 android:layout_height="wrap_content"
8 android:text="Reading and Writing to External Storage"
9 android:textSize="24sp"/>
10
11 <EditText android:id="@+id/myInputText"
12 android:layout_width="match_parent"
13 android:layout_height="wrap_content"
14 android:ems="10" android:lines="5"
15 android:minLines="3" android:gravity="top|left"
16 android:inputType="textMultiLine">
17
18 <requestFocus />
19 </EditText>
20
21 <LinearLayout
22 android:layout_width="match_parent" android:layout_height="wrap_content"
23 android:orientation="horizontal"
24 android:weightSum="1.0"
25 android:layout_marginTop="20dp">
26
27 <Button android:id="@+id/saveExternalStorage"
28 android:layout_width="match_parent"
29 android:layout_height="wrap_content"
30 android:text="SAVE"
31 android:layout_weight="0.5"/>
32
33 <Button android:id="@+id/getExternalStorage"
34 android:layout_width="match_parent"
35 android:layout_height="wrap_content"
36 android:layout_weight="0.5"
37 android:text="READ" />
38
39 </LinearLayout>
40
41 <TextView android:id="@+id/response"
42 android:layout_width="wrap_content"
43 android:layout_height="wrap_content" android:padding="5dp"
44 android:text=""
45 android:textAppearance="?android:attr/textAppearanceMedium" />
46
47</LinearLayout>
在这里,除了保存和从外部存储器读取按钮外,我们在文本视图中显示了对外部存储器进行保存/读取的响应,而不是在上一个教程中显示Android toast]。MainActivity.Java类如下所示:
1package com.journaldev.externalstorage;
2
3import java.io.BufferedReader;
4import java.io.DataInputStream;
5import java.io.File;
6import java.io.FileInputStream;
7import java.io.FileOutputStream;
8import java.io.IOException;
9import java.io.InputStreamReader;
10import android.os.Bundle;
11import android.app.Activity;
12import android.os.Environment;
13import android.view.View;
14import android.view.View.OnClickListener;
15import android.widget.Button;
16import android.widget.EditText;
17import android.widget.TextView;
18
19public class MainActivity extends Activity {
20 EditText inputText;
21 TextView response;
22 Button saveButton,readButton;
23
24 private String filename = "SampleFile.txt";
25 private String filepath = "MyFileStorage";
26 File myExternalFile;
27 String myData = "";
28
29 @Override
30 protected void onCreate(Bundle savedInstanceState) {
31 super.onCreate(savedInstanceState);
32 setContentView(R.layout.activity_main);
33
34 inputText = (EditText) findViewById(R.id.myInputText);
35 response = (TextView) findViewById(R.id.response);
36
37 saveButton =
38 (Button) findViewById(R.id.saveExternalStorage);
39 saveButton.setOnClickListener(new OnClickListener() {
40 @Override
41 public void onClick(View v) {
42 try {
43 FileOutputStream fos = new FileOutputStream(myExternalFile);
44 fos.write(inputText.getText().toString().getBytes());
45 fos.close();
46 } catch (IOException e) {
47 e.printStackTrace();
48 }
49 inputText.setText("");
50 response.setText("SampleFile.txt saved to External Storage...");
51 }
52 });
53
54 readButton = (Button) findViewById(R.id.getExternalStorage);
55 readButton.setOnClickListener(new OnClickListener() {
56 @Override
57 public void onClick(View v) {
58 try {
59 FileInputStream fis = new FileInputStream(myExternalFile);
60 DataInputStream in = new DataInputStream(fis);
61 BufferedReader br =
62 new BufferedReader(new InputStreamReader(in));
63 String strLine;
64 while ((strLine = br.readLine()) != null) {
65 myData = myData + strLine;
66 }
67 in.close();
68 } catch (IOException e) {
69 e.printStackTrace();
70 }
71 inputText.setText(myData);
72 response.setText("SampleFile.txt data retrieved from Internal Storage...");
73 }
74 });
75
76 if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
77 saveButton.setEnabled(false);
78 }
79 else {
80 myExternalFile = new File(getExternalFilesDir(filepath), filename);
81 }
82
83 }
84 private static boolean isExternalStorageReadOnly() {
85 String extStorageState = Environment.getExternalStorageState();
86 if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
87 return true;
88 }
89 return false;
90 }
91
92 private static boolean isExternalStorageAvailable() {
93 String extStorageState = Environment.getExternalStorageState();
94 if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
95 return true;
96 }
97 return false;
98 }
99
100}
1.Environment.getExternalStorageState() :返回内部SD挂载点的路径,如/mnt/sdcard
2.getExternalFilesDir() :返回SD卡Android/data/data/APPLICATION_PACKAGE/内文件文件夹的路径。它用于存储你的应用程序所需的任何文件(如从Web下载的图像或缓存文件)。一旦卸载该应用程序,存储在此文件夹中的任何数据也将消失。
此外,如果外部存储不可用,我们将使用本教程前面讨论的IF条件禁用保存按钮。下面是我们在Android模拟器中运行的应用程序,我们在其中将数据写入文件,然后读取它。注意: 请确保您的安卓模拟器配置为SD卡,如下面avd的图像对话框所示。进入工具->Android->Android虚拟设备,编辑配置->显示高级设置。
本教程就此结束。在下一篇教程中,我们将讨论使用共享首选项的存储。你可以从下面的链接下载最终的Android外部存储项目。