TAE

[Android/Kotlin] registerForActivityResult사용하여 앨범에서 사진 선택하기- 비디오 썸네일 지정(1) 본문

android/코드

[Android/Kotlin] registerForActivityResult사용하여 앨범에서 사진 선택하기- 비디오 썸네일 지정(1)

tg-world 2023. 3. 20. 09:14
반응형

전에 만들었던 커스텀 앨범에서 비디오를 선택하여 비디오에서 썸네일을 추출하는 작업을 해보려고 합니다.

비디오 업로드 기능을 사용하는 앱이라면 썸네일을 지정하는 기능이 있습니다. 예를 들어 인스타그램 영상업로드입니다.

비디오 선택 후 디폴트 썸네일이 지정되고 썸네일 지정하기 버튼을 누르면 해당 비디오의 초에 맞는 썸네일을 보여주는 기능입니다.

 

비디오 썸네일 추출 전 비디오를 선택하고 MainActivity에 선택한 비디오의 썸네일을 보여주는 기능을 먼저 구현해야 합니다.

예전에는 startActivityForResult()와 onActivityResult()를 사용했지만 deprecated 되었습니다.

그래서 registerForActivityResult()를 사용하여야 합니다.

https://developer.android.com/training/basics/intents/result#kotlin

 

활동에서 결과 가져오기  |  Android 개발자  |  Android Developers

활동에서 결과 가져오기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 개발자 앱 내의 활동이든 다른 앱의 활동이든 다른 활동을 시작하는 것이 단방향 작

developer.android.com

 

이 코드는 전에 포스팅한 커스텀 앨범에서 추가로 작업됩니다.

https://tg-world.tistory.com/8

 

[Android/Kotlin] 갤러리 접근 권한(Premission) 설정하기 - 커스텀 갤러리(1)

안드로이드 앱을 개발하다 보면 특정 권한을 얻어야지만 사용이 가능한 기능들이 있습니다. Android6.0 (API 수준 23) 마쉬멜로우 이전 버전은 메니페스트에 권한을 넣어주면 사용이 가능했지만, 마

tg-world.tistory.com


실행동작


코드

CustomAlbumActivity 실행하기(MainActivity.kt)

  private lateinit var activityForResult: ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        setContentView(R.layout.activity_main)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.goAlbumTV.setOnClickListener {
            when {
                ContextCompat.checkSelfPermission(
                    this,
                    android.Manifest.permission.READ_EXTERNAL_STORAGE
                ) == PackageManager.PERMISSION_GRANTED -> {
                    val startCustomAlbum = Intent(this, CustomAlbumActivity::class.java)
                    activityForResult.launch(startCustomAlbum)
//                    startActivity(startCustomAlbum)
                    //스토리지 읽기 권한이 허용이면 커스텀 앨범 띄워주기
                    //권한 있을 경우 : PERMISSION_GRANTED
                    //권한 없을 경우 : PERMISSION_DENIED
                }

                shouldShowRequestPermissionRationale(android.Manifest.permission.READ_EXTERNAL_STORAGE) -> {
                    //다이얼로그를 띄워 권한팝업을 허용하여야 접근 가능하다는 사실을 알려줌
                    showPermissionAlertDialog()
                }

                else -> {
                    //권한 요청
                    requestPermissions(
                        arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE),
                        PERMISSION_CODE
                    )
                }
            }
        }

        activityForResult()
    }
private lateinit var activityForResult: ActivityResultLauncher<Intent>
val startCustomAlbum = Intent(this, CustomAlbumActivity::class.java)
activityForResult.launch(startCustomAlbum)

버튼 클릭 시 권한이 승인되어 있을 경우 CustomAlbumActivity를 호출합니다.

멤버함수인 launch를 호출하며 인자로 intent를 넣어줍니다.

 

 


리스너 연결(CustomAlbumAdapter.kt)

interface OnItemClickListener{
    fun onItemClick(v: View, data: ItemGallery)
}
private var listener: OnItemClickListener? =null
fun setOnItemClickListener(listener: OnItemClickListener){
    this.listener = listener
}

adapter에서 클릭 이벤트를 Activity로 연결해 주기 위해 interface를 정의하여 줍니다.

 

binding.layoutCL.setOnClickListener {
    if (item.mediaType == 3) {
        listener?.onItemClick(itemView, item)
    } else {
        item.isSelected = !binding.selectRatioBT.isChecked
        binding.selectRatioBT.isChecked = item.isSelected
    }
}

레이아웃 클릭 시 리스터를 연결하여 줍니다.

mediaType이 3번일 경우 즉, 비디오 일 경우 리스너 onItemClick을 실행합니다.

인자로는 view와 ItemGallery를 넘겨줍니다.

 


Activity에 setOnItemClickListener 연결(CustomAlbumActivity.kt)

customAlbumAdapter.setOnItemClickListener(object : CustomAlbumAdapter.OnItemClickListener {
    override fun onItemClick(v: View, data: ItemGallery) {
        val intent = Intent(this@CustomAlbumActivity, MainActivity::class.java).apply {
            putExtra("videoData",data.mediaData)
        }
        setResult(RESULT_OK,intent)
        finish()
    }

})

어뎁터에서 아이템 클릭 시 해당 포지션에 맞는 mediaData를 putExtra로 넘겨줍니다.

키값은 videoData로 정의하였습니다.

setResult는 기존 StartActivityForResult와 동일하게 사용됩니다.


콜백 등록 (MainActivity.kt)

private fun activityForResult(){
    activityForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
        if (it.resultCode == RESULT_OK){
            binding.thumbnailIV.visibility = View.VISIBLE
            Glide.with(this@MainActivity)
                .load(it.data?.getStringExtra("videoData"))
                .into(binding.thumbnailIV)
        }
    }
}

CustomAlbumActivity에서 돌아왔을 때 콜백처리 코드입니다.

람다식 it은 결과를 나타냅니다.

it.resultCode, it.data로 결과코드, intent데이터로 접근 가능합니다.

받은 결과코드가 RESULT_OK일 경우 썸네일 이미지를 visible 시켜주고, 앞에서 설명드린 key값으로 이미지 주소를 가지고 와 Glide을 활용하여 이미지를 표시해 줍니다.

 


layout(activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <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/thumbnailIV"
            android:layout_width="150dp"
            android:layout_height="300dp"
            android:scaleType="centerCrop"
            app:layout_constraintBottom_toTopOf="@id/goAlbumTV"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:src="@drawable/ic_launcher_background" />

        <Button
            android:id="@+id/goAlbumTV"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="앨범 불러오기"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

기존 activity_main.xml에 썸네일을 표시해 줄 ImageView를 만들어 줍니다.


이상 registerForActivityResult사용하여 앨범에서 사진 선택하는 방법에 대해 알아보았습니다.

mainActivity에서 CustomAlbumActivity를 호출하고 영상을 선택하였을 때 기본 썸네일을 표시하는 기능을 만들어 보았습니다.

궁금하신 점이나 잘못된 게 있다면 댓글 달아주시면 감사하겠습니다!

반응형
Comments