ギャラリーから画像を選択し表示するAndoroidアプリ

この記事は、株式会社富士通システムズウェブテクノロジーが企画する「[いのべこ夏休みアドベントカレンダー 2020](https://qiita.com/jugemsan/items/5761773308fb1df0c23a)」の22日目の記事です。
 （お約束）本記事の掲載内容は私自身の見解であり、所属する組織を代表するものではありません。

#はじめに
Andoroid Studioで画像を選択し画面に表示するソースを書いたので、本記事ではそのソース、手順などを紹介します。

##背景
前回の記事（[Google Cloud Vision APIを使って食べ物の写真を判定してみる](https://qiita.com/m-yuumin/items/a679ea45053ba6395b38)）を踏まえ、選択した写真をAPIで判定するアプリを作ってみようと思い、1段階目として、ギャラリーから画像を選択する部分を記事にしました。

#事前準備
下記に関しては今回のアドベントカレンダー16日目の記事「[Androidアプリ「HelloWorld」を作って、好き勝手に弄ってみた](https://levia9071.hatenablog.com/entry/2020/08/16/095535)」で記載されているので参照していただければと思います。ここでは省略します。

・Andoroid Studioのインストール
・プロジェクトの新規作成
・エミュレーターの作成と起動

##エミュレーターの日本語化
おそらくデフォルトで英語になっているので、日本語化します。
エミュレーター上で[Settings]画面を表示し、[System]-[Languages & input]-[Languages]の順に選択します。
Englishだけ表示されていると思うので、[Language preferences]から日本語を選択すると、Englishの下に日本語が表示されるので、ドラッグで順番を入れ替えることで日本語化完了です。

<img width="300" alt="エミュレーター_日本語化.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531905/0907d224-4e93-5d47-a8a6-10b981ba6fa1.png">

##エミュレーター上に画像を保存する
画像選択をするために、画像をエミュレーターで確認できるようにします。

方法としては２つ
・エミュレーターに画像をドラッグ＆ドロップ
　　DownLoadのフォルダに画像が入ります。
・Device File Explorerでアップロード
　　[View]-[Tool Windows]-[Device File Explorer]で開きます。
　　任意のフォルダで右クリックでファイル追加可能です。

#ソース
ボタン押下でギャラリーを開き、選択した画像を画面に表示させます。

##ギャラリーを開く
```java
Intent intent = new Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 1);
```
`` Intent(アクションの種類, 対象のアプリ)``
`` startActivityForResult(インテント, リクエストコード) ``
Intentクラスで別のアプリでアクティビティを開始できます。
今回は、ギャラリー（画像一覧）を開いて選択した画像を取得しています。

Intentに関する詳細は[一般的なインテント](https://developer.android.com/guide/components/intents-common?hl=ja)を参照。

引数に指定している内容はざっくりと以下のような意味です。
・Intent.ACTION_PICK　　　　　　：データから選択したものを返すアクション
・Media.EXTERNAL_CONTENT_URI　：画像データが取得できるURI
　※「EXTERNAL_CONTENT_URI」はSDカード等の外部ストレージを参照します。内部ストレージの場合は「INTERNAL_CONTENT_URI」にすればよいみたいです。

startActivityForResultのパラメータで指定するリクエストコードは遷移元を判断するためのものです。
ここでは、1をハードコーディングで指定していますが、定数等で管理するのがいい気がします。

##選択結果を表示する
```java
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);

      if (requestCode == 1 && resultCode == RESULT_OK && null != data) {
            ImageView imgView = findViewById(R.id.imageView);
            BufferedInputStream inputStream = null;
            try {
                inputStream = new BufferedInputStream
                             (getContentResolver().openInputStream(data.getData()));
                imgView.setImageBitmap(BitmapFactory.decodeStream(inputStream));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
      }
}
```

「onActivityResult」メソッドは前段の「startActivityForResult」の実行結果を受け取ります。
選択した結果を画面のImageViewに設定します。

また、引数のrequestCodeは「startActivityForResult」メソッドで指定したリクエストコードが返ってきます。
前段で述べた通り、遷移元を判断できるので下記のような書き方ができます。

```java
public void button1_onClick(View view) {
      Intent intent = new Intent(Intent.ACTION_PICK, Media.INTERNAL_CONTENT_URI);
      startActivityForResult(intent, 1);
}

public void button2_onClick(View view) {
      Intent intent = new Intent(Intent.ACTION_PICK, Media.INTERNAL_CONTENT_URI);
      startActivityForResult(intent, 2);
}
    
@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);

      if (requestCode == 1) {
            // button1用の処理
      } else if (requestCode == 2) {
            // button2用の処理
      }
}
```

##画面
上記までのソースをエミュレーターで実行すると、当初目的の「画像を選択し画面に表示する」ができました。

①ボタンを押下する
②③画像を選択
④選択した画像を表示

<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531905/3568cd8c-dd9b-3071-4cc5-7e0781f7aa4a.png"><img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531905/6ce270e4-7d5f-810e-f18d-f3a06a859958.png">
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531905/7227bcf8-8f94-8f00-fa53-dd0606641c7b.png"><img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531905/af2fecbf-9e38-2100-8acf-05b289f3e656.png">


#最後に
Andoroid Studioを初めて使いましたが、Form系アプリとソースが似ていたので、大きく苦労はしませんでした。

次回はAndoroidアプリからCloud Vision APIを呼び出すところをやってみたいです。