LoginSignup
6
8

More than 1 year has passed since last update.

【Android】画像を選択して、ImageViewに表示 in Kotlin

Last updated at Posted at 2021-09-05

➊ はじめに

画像を選択して、ImageViewに表示する方法」として「startActivityForResultonActivityResult」で実装していたのですが、Androidは日進月歩しているらしく、この方法で実装するのは非推奨になってしまいました。

基盤となる startActivityForResult() API と onActivityResult() API はあらゆる API レベルの Activity クラスで使用できますが、AndroidX Activity と Fragment で導入された Activity Result API を使用することを強くおすすめします。

とのことなので、推奨方法をここ👉「アクティビティの結果を取得する」で調べつつ、実装してみたいと思います。

➋ どんな感じ?

百聞は一見にしかずということで、こんな感じ~になります。
SELECT IMAGE」ボタンを押下すると、カメラで撮った画像を選択するアクティビティに切り替わります。画像を選択すると、選択した画像がアプリのImageViewに表示されます。

➌ お勉強ポイント

  • ギャラリーアクティビティの起動
  • アクティビティ結果の受け取り

※推奨されている「AndroidX Activity と Fragment で導入された Activity Result API」を使用。

➍ アクティビティの起動と結果取得

(1) アクティビティの結果に対するコールバックの登録

  • アクティビティ結果のコールバックを登録するため、registerForActivityResult()を用います。
  • StartActivityForResultコントラクトは、任意のIntentを入力として受け取ってActivityResultを返す汎用コントラクトです。このコントラクトを使用すると、コールバックの一部としてresultCodeとIntentを抽出できます。
snippet
    // アクティビティの結果に対するコールバックの登録
    private val launcher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        Log.d("registerForActivityResult(result)", result.toString())

        if (result.resultCode != RESULT_OK) {
            // アクティビティ結果NG 
        } else {
            // アクティビティ結果OK
            // ・・・
        }
    }

※アクティビティの結果関連の詳細ドキュメントは、こちら👉「アクティビティの結果を取得する」をご参照ください。

(2) アクティビティの起動

  • launch()でアクティビティ(画像選択画面)を起動します。
snippet
        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "image/*"
        }
        launcher.launch(intent)

※インテント関連の詳細ドキュメントは、こちら👉「ファイル ストレージ」をご参照ください。

➎ 実装

仕組みが分かったところで、上記をまとめ、諸々実装していきます。
言語は、「Kotlin」で実装します。

(1) activity_main.xml

app/src/main/res/layout/activity_main.xml

UIはこんな感じになります。

コードはこちら。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">


    <ImageView
        android:id="@+id/imageView"
        android:layout_width="409dp"
        android:layout_height="260dp"
        android:contentDescription="image view"
        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.161" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Select Image"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.814" />

</androidx.constraintlayout.widget.ConstraintLayout>

(2) MainActivity.kt

app/src/main/java/com/poodlemaster/app4/MainActivity.kt

MainActivity.kt
package com.poodlemaster.app4

import android.content.Intent
import android.graphics.BitmapFactory
import androidx.appcompat.app.AppCompatActivity
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import android.widget.Button
import android.widget.ImageView
import androidx.activity.result.contract.ActivityResultContracts

class MainActivity : AppCompatActivity(), View.OnClickListener {

    //-------------------------------------------------------------------------
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("status", "onCreate")
        setContentView(R.layout.activity_main)

        val button: Button = findViewById(R.id.button)
        button.setOnClickListener(this)
    }

    //-------------------------------------------------------------------------
    override fun onClick(view: View){
        when (view.id) {
            R.id.button -> {
                selectPhoto()
            }
        }
    }

    //-------------------------------------------------------------------------
    private val launcher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        Log.d("registerForActivityResult(result)", result.toString())

        if (result.resultCode != RESULT_OK) {
            return@registerForActivityResult
        } else {
            try {
                result.data?.data?.also { uri : Uri ->
                    val inputStream = contentResolver?.openInputStream(uri)
                    val image = BitmapFactory.decodeStream(inputStream)
                    val imageView: ImageView = findViewById(R.id.imageView)
                    imageView.setImageBitmap(image)
                }
            } catch (e: Exception) {
                Toast.makeText(this, "エラーが発生しました", Toast.LENGTH_LONG).show()
            }
        }
    }

    //-------------------------------------------------------------------------
    private fun selectPhoto() {
        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "image/*"
        }
        launcher.launch(intent)
    }
}

➏ 以上

最近、Androidアプリの基礎を勉強してみようと、重い腰を上げようやく「Android Studio」をインストールしました。kotlinという言語も初めて使いました。JAVAも触ったことなかったので、まずは見様見真似と自己流改造で色々と学べたらと思っています。

お疲れ様でした😊

6
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
6
8