Внешнее хранилище Android — чтение, запись, сохранение файла
Внешнее хранилище Android можно использовать для записи и сохранения данных, чтения файлов конфигурации и т. д. Эта статья является продолжением руководства по внутреннему хранилищу Android из серии руководств по хранению структурированных данных в Android.
Внешнее хранилище Android
Внешнее хранилище, такое как SD-карта, также может хранить данные приложений, безопасность файлов, которые вы сохраняете на внешнем хранилище, не обеспечивается. В целом существует два типа внешнего хранилища:
- Основное внешнее хранилище: встроенное общее хранилище, к которому пользователь может получить доступ, подключив USB-кабель и установив его в качестве накопителя на главном компьютере. Пример: когда мы говорим Nexus 5 32 ГБ.
- Дополнительное внешнее хранилище: съемное хранилище. Пример: SD-карта
Все приложения могут читать и записывать файлы, размещенные на внешнем хранилище, а пользователь может их удалять. Нам нужно проверить, доступна ли SD-карта и можем ли мы записать на нее. Только после того, как мы проверили, что внешнее хранилище доступно, мы можем записать в него, иначе кнопка сохранения будет отключена.
Структура проекта примера внешнего хранилища Android
<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()
— это статический метод Environment
для определения, доступно ли внешнее хранилище в данный момент или нет. Как видите, если условие ложно, мы отключили кнопку сохранения.
Пример кода внешнего хранилища 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. Класс MainActivity.java приведен ниже:
package com.journaldev.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(): возвращает путь к папке с файлами внутри Android/data/data/application_package/ на SD-карте. Он используется для хранения любых файлов, необходимых для вашего приложения (например, изображений, загруженных из Интернета, или файлов кеша). После удаления приложения все данные, хранящиеся в этой папке, также исчезнут.
Скачать пример проекта внешнего хранилища Android