Hello. Continuing from Last time, we will explain Android storage operations. This time, the content is to save / load images to the external storage, but I will try to realize it in a way as close as possible to the previous saving / reading of files to the external storage.
As I mentioned every time, the content of each article about Android commentary is 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
The story of saving to external storage previous has been described in detail, so I will omit it. This time as well, we will deal with reading and writing to the application-specific area of the external storage.
The explanation is based on the assumption that an asset folder is created under the main directory of Android and picture.jpg is placed. The asset folder is created by right-clicking ** [main] → [New] → [Folder] → [Assets Folder] **.
Now, get the path to the folder you want to save in the external storage and create the path including the file name.
this.imgName = "picture.jpg ";
this.path = getExternalFilesDir(Environment.DIRECTORY_PICTURES).toString();
this.file = this.path + "/" + this.fileName;
As a result, the character string "/sdcard/Android/data/package name/files/PICTURES/picture.jpg " is assigned to the file variable.
Next, read the image file from the Asset folder.
AssetManager assetManager = getResources().getAssets();
InputStream inputStream = assetManager.open(imgName);
Save the read image file in the external storage. The byte array of the image file is acquired by ```inputStream.read (buffer) `` `. The byte array is written to a file that saves 1024 bytes in external storage.
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
while (true){
int len = inputStream.read(buffer);
if (len < 0){
break;
}
fileOutputStream.write(buffer, 0, len);
}
fileOutputStream.flush();
To load an image, open the stream with the InputStream
type. Then, use `BitmapFactory.decodeStream ()`
to get the image as `Bitmap``` type. After that, set it to ```imageView``` with
setImageBitmap ()
``.
InputStream inputStream = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
imageView.setImageBitmap(bitmap);
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_marginTop="200dp"
android:text="Save File"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="Read File"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button1" />
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.2"/>
</android.support.constraint.ConstraintLayout>
MainActivity.java
package com.example.keita.myapplication;
import android.Manifest;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
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.ImageView;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
private String file;
private String path;
public String state;
private String imgName = "picture.jpg ";
private Button button1;
private Button button2;
public ImageView imageView;
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.button1 = findViewById(R.id.button1);
this.button2 = findViewById(R.id.button2);
this.imageView = findViewById(R.id.imageView);
this.path = getExternalFilesDir(Environment.DIRECTORY_PICTURES).toString();
this.file = this.path + "/" + this.imgName;
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) {
state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)){
saveFile(file);
}
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)){
readFile(file);
}
}
});
}
private void saveFile(String file){
try {
AssetManager assetManager = getResources().getAssets();
InputStream inputStream = assetManager.open(imgName);
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
while (true){
int len = inputStream.read(buffer);
if (len < 0){
break;
}
fileOutputStream.write(buffer, 0, len);
}
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void readFile(String file){
try {
InputStream inputStream = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Recommended Posts