➊ はじめに
「画像を選択して、ImageViewに表示する方法
」として「startActivityForResult と onActivityResult」で実装していたのですが、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を抽出できます。
// アクティビティの結果に対するコールバックの登録
private val launcher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
Log.d("registerForActivityResult(result)", result.toString())
if (result.resultCode != RESULT_OK) {
// アクティビティ結果NG
} else {
// アクティビティ結果OK
// ・・・
}
}
※アクティビティの結果関連の詳細ドキュメントは、こちら👉「アクティビティの結果を取得する」をご参照ください。
(2) アクティビティの起動
- **launch()**でアクティビティ(画像選択画面)を起動します。
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
コードはこちら。
<?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
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も触ったことなかったので、まずは見様見真似と自己流改造で色々と学べたらと思っています。
お疲れ様でした😊