1
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

*Android*外部ストレージへの画像の保存・読み込み

Posted at

はじめに

こんにちは.前回に引き続き,Androidのストレージ操作について解説します.今回は,外部ストレージへの画像の保存・読み込みという内容ですが,前回の外部ストレージへのファイル保存・読み込みとできる限り近いやり方で実現しようと思います.

毎回述べていますが,Androidの解説に関する記事は,どれも内容が少しずつ異なり,迷ってしまう方もいると思うので,標準的な方法を書くように心がけています.

前提

開発環境は以下の通りです.
*Android Studio 4.0.1
*targetSdkVersion 28
*Google Nexus 5x

外部ストレージへの画像保存・読み込み

外部ストレージへの保存の話は前回詳しく述べましたので省略します.
今回も,外部ストレージのアプリ固有の領域への読み書きについて扱います.

外部ストレージへの画像ファイルの保存

Androidのmainディレクトリ配下にassetフォルダを作り,picture.jpgを配置しているという想定で解説します.
assetフォルダは,**[main]を右クリック→[New]→[Folder]→[Assets Folder]**を選択して作成します.

では,外部ストレージの保存したいフォルダへのパスを取得し,ファイル名を含めたパスを作成します.

this.imgName = "picture.jpg";
this.path = getExternalFilesDir(Environment.DIRECTORY_PICTURES).toString();
this.file = this.path + "/" + this.fileName;

これにより,file変数には"/sdcard/Android/data/パッケージ名/files/PICTURES/picture.jpg"という文字列が代入されます.

次にAssetフォルダから画像ファイルを読み込みます.

AssetManager assetManager = getResources().getAssets();
InputStream inputStream = assetManager.open(imgName);

読み込んだ画像ファイルを外部ストレージに保存します.inputStream.read(buffer)により,画像ファイルのバイト配列を取得しています.バイト配列を1024byteずつ外部ストレージに保存するファイルに書き出しています.

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();

外部ストレージからの画像ファイルの読み込み

画像を読み込むには,InputStream型でストリームを開きます.そして,BitmapFactory.decodeStream()により画像をBitmap型で取得します.あとは,setImageBitmap()imageViewにセットします.

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++){
            //初回はPERMISSION_DENIEDが返る
            if (checkSelfPermission(PERMISSIONS[i]) != PackageManager.PERMISSION_GRANTED) {
                //一度リクエストが拒絶された場合にtrueを返す.初回,または「今後表示しない」が選択された場合,falseを返す.
                if (shouldShowRequestPermissionRationale(PERMISSIONS[i])) {
                    Toast.makeText(this, "アプリを実行するためには許可が必要です", 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();
        }
    }
}
1
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?