Hello. Continuing from Last time, I will explain the storage operation of Android. This time, the content is to save / read the file to the external storage, but I will try to realize it in a way as close as possible to the previous saving / reading of the internal storage.
As I mentioned last time, all the articles about Android commentary are slightly different, and I think that some people may get lost, so I try to write a standard method.
The development environment is as follows. *Android Studio 4.0.1 *targetSdkVersion 28 *Google Nexus 5x
This time, the file is saved in the application-specific area (/ sdcard / Android / data / package name / files /) of the external storage. When it comes to saving files to external storage, it is standard to save them to this location.
Starting with Android 6.0 (API level 23), users will check Permission after launching the app, not when installing the app. Permission is required to read and write external storage.
In Android application development, Permission has two protection levels, called Normal and Dangerous, respectively. Since the protection level is determined for each Permission, it is necessary to implement the processing required for Normal and the processing required for Dangerous according to the required Permission.
All you need to do for Normal Permission is to describe the permission in AndroidManifest.xml. For example, Normal Permission is required to connect to the Internet with an Android app.
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
Just add one line like the one above and you will be able to connect to the Internet.
Dangerous Permission processing is required for reading and writing external storage this time. First, describe the permission in AndroidManifest.xml.
AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Next, you need to implement the permission check. When the app is opened, the user can display a dialog regarding permission / non-permission of Permission. Please refer to the sample program because the processing will be long.
First, get the path to the folder you want to save in the external storage, and create the path including the file name.
this.fileName = "test.txt";
this.path = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).toString();
this.file = this.path + "/" + this.fileName;
As a result, the character string "/sdcard/Android/data/package name/files/Documents/test.txt" is assigned to the file variable.
To check whether the external storage is currently readable and writable, write the following before the read / write process.
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)){
//File read / write processing
}
Next is the process of saving the file. When saving a file to the internal storage, the path to the internal storage was automatically specified by using the `openFileOutput ()`
method for the instance of
FileOutputStream. However, this time I don't use
openFileOutput ()` `` because I have to specify the path of the external storage by myself.
FileOutputStream fileOutputStream = new FileOutputStream(file, true);
** First argument **
"/path/file name"
** Second argument **
true
If is set, it will be written to the end of the file.
false
If is specified, the file will be overwritten from the beginning.
After that, convert the character string you want to write to the file to a byte type array and write it to the stream using `write ()`
.
fileOutputStream.write(str.getBytes());
When reading a file, you get an instance of FileInputStream
. This will allow you to open the stream.
FileInputStream fileInputStream = new FileInputStream(file);
Subsequent processing is the same as Last time.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.keita.myapplication">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
tools:context=".MainActivity">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginTop="100dp"
android:text="Save File"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="100dp"
android:text="Read File"
app:layout_constraintStart_toEndOf="@+id/button1"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="120dp"
android:text=""
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText" />
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
MainActivity.java
package com.example.keita.myapplication;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class MainActivity extends AppCompatActivity {
private String file;
private String path;
public String state;
private String fileName;
private TextView textView;
private Button button1;
private Button button2;
private EditText editText;
private final String[] PERMISSIONS = {
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private final int REQUEST_PERMISSION = 1000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.textView = findViewById(R.id.textView);
this.editText = findViewById(R.id.editText);
this.button1 = findViewById(R.id.button1);
this.button2 = findViewById(R.id.button2);
this.fileName = "test.txt";
this.path = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).toString();
this.file = this.path + "/" + this.fileName;
checkPermission();
}
private void checkPermission(){
if (isGranted()){
setEvent();
}
else {
requestPermissions(PERMISSIONS, REQUEST_PERMISSION);
}
}
private boolean isGranted(){
for (int i = 0; i < PERMISSIONS.length; i++){
//The first time is PERMISSION_DENIED returns
if (checkSelfPermission(PERMISSIONS[i]) != PackageManager.PERMISSION_GRANTED) {
//Returns true if the request is rejected once. Returns false for the first time or when "Do not show again" is selected.
if (shouldShowRequestPermissionRationale(PERMISSIONS[i])) {
Toast.makeText(this, "Permission required to run the app", Toast.LENGTH_LONG).show();
}
return false;
}
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION){
checkPermission();
}
}
private void setEvent(){
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String text = editText.getText().toString();
state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)){
saveFile(file, text);
}
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)){
String str = readFile(file);
textView.setText(str);
}
}
});
}
private void saveFile(String file, String str){
try {
FileOutputStream fileOutputStream = new FileOutputStream(file, true);
fileOutputStream.write(str.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
private String readFile(String file){
String text = null;
try {
FileInputStream fileInputStream = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
String lineBuffer;
while (true){
lineBuffer = reader.readLine();
if (lineBuffer != null){
text += lineBuffer;
}
else {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return text;
}
}
Recommended Posts