SW 공부노트
[안드로이드/Kotlin]Photo Picker(갤러리에서 이미지 불러오기) 본문
Photo Picker
Android 13에서 새롭게 공개된 Photo Picker는 앱에 전체 미디어 라이브러리에 대한 액세스 권한을 부여하지 않고도 사용자가 미디어 파일을 선택할 수 있는 안전한 방법을 제공합니다.
사용자가 사진 또는 비디오만 볼 수 있도록 지정할 수 있으며, 이미지 단일 및 다중 선택이 가능합니다.
이 라이브러리는 Android 11 이상의 기기에서만 지원됩니다.
Photo Picker는 간단히 다음과 같은 과정을 통해 실행됩니다.
- registerForActivityResult(ActivityResultContract, Callback) -> ActivityResultLauncher 반환
- ActivityResultLauncher.launch() 실행
Photo Picker를 구현하는 방법은 ActivityResultContract 구현 여부에 따라 두 가지로 나뉩니다.
- 수동적으로 Intent 생성 및 결과 핸들링 -> ActivityResultContract 직접 구현
- ActivityResultContract(androidx.activity 라이브러리 제공) 사용
커스텀 및 라이브러리에서 제공되는 ActivityResultContract 클래스를 사용해 Photo Picker를 구현하였습니다 :)
커스텀 ActivityResultContracts 사용
이미지 단일 및 다중선택을 위해 ActivityResultContract를 상속받아 구현할 예정입니다.
Photo Picker의 동작을 커스터마이징하기 위해 ActivityResultContract를 구현하는 과정입니다.
원본 글에는 두 경우를 모두 다루지만 여기서는 단일 선택 경우만 작성하였습니다.
1. isPhotoPickerAvailable() 작성
위에서 말한대로 Photo Picker는 Andriod 11 이상의 기기에서만 지원되므로
현재 기기가 Photo Picker를 지원하는지 확인하기 위한 함수를 작성해야 합니다.
+) Android 11 버전의 경우, SDK 확장버전이 사용 가능한 경우도 확인해야 함.
fun isPhotoPickerAvailable(): Boolean {
return when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> true
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
getExtensionVersion(Build.VERSION_CODES.R) >= ANDROID_R_REQUIRED_EXTENSION_VERSION
}
else -> false
}
}
2. ActivityResultContract 클래스 생성
ActivityResultContract 클래스는 createIntent, praseResult 두 메서드를 오버라이드해야합니다.
해당 ActivityResultContract는 단일 이미지 선택에 사용되는 클래스입니다.
private const val MIME_TYPE_IMAGE = "image/*"
class PickSinglePhotoContract : ActivityResultContract<Void?, Uri?>() {
override fun createIntent(context: Context, input: Void?): Intent {
return Intent(if (PhotoPickerAvailabilityChecker.isPhotoPickerAvailable()) {
Intent(MediaStore.ACTION_PICK_IMAGES)
} else {
Intent(Intent.ACTION_OPEN_DOCUMENT)
}).apply { type = MIME_TYPE_IMAGE }
}
override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
return intent.takeIf { resultCode == Activity.RESULT_OK }?.data
}
}
createIntent는 이미지 선택을 위한 인텐트를 생성하는 함수이고,
parseResult는 이미지 선택 후 인텐트에서 이미지 Uri를 받아오는 함수입니다.
만약, 이미지가 선택되지 않았을 경우에 Uri값은 null이 됩니다.
+) 추가적으로 Photo Picker가 지원되지 않는 경우, 일반적인 방식으로 구현해야 하고 이미지를 선택하기 위해 시스템의 파일 브라우저를 시작하는 Intent.ACTION_OPEN_DOCUMENT를 사용해야 합니다.
3. Photo Picker Contract Launch
2단계에서 작성한 Contract를 가지고 ActivityResultLauncher를 반환하는 registerForActivityResult 메서드를 실행한다. registerForActivityResult 에 Contract와 콜백 람다 함수를 인수로 넣습니다..
콜백 함수 안에는 선택한 이미지 Uri 처리 코드를 작성해줍니다.
launch() 메서드를 통해 ActivityResultLauncher 작업을 실행합니다.
private val singlePhotoPickerLauncher = registerForActivityResult(PickSinglePhotoContract()) { imageUri: Uri? ->
imageUri?.let(viewModel::setImageUri)
}
private fun pickPhoto() = singlePhotoPickerLauncher.launch()
* setImageUri 함수는 Uri를 비트맵으로 변환하는 함수
앱 세션에서 Uri 권한을 유지하려면 저장소 액세스 프레임워크에 명시적으로 의존해야 하므로 Intent.ACTION_OPEN_DOCUMENT를 대신 사용한다. 각 Uri 및 필수권한 플래그와 함께 contentResolver.takePersistableUriPermission(..)을 호출하여 수신 Uri에 대한 액세스를 유지할 수 있다.
자세한 내용은 아래 첨부된 글을 확인하길 바란다.
미리 정의된 ActivityResultContract 사용
ActivityResultContract는 androidx.activity 라이브러리에서 제공합니다.
1. build.gradle(앱 모듈)
버전은 공식 사이트에서 최신 버전을 확인해주세요!
커스텀 과정에서 작성한 isPhotoPickerAvailable() 함수 또한 해당 라이브러리에 정의되어 있습니다.
dependencies {
..
implementation "androidx.activity:activity-ktx:$latest_version"
}
2. Single Photo Selection
단일 이미지 선택에 사용되는 contract는 PickVisualMedia 입니다.
해당 Contract를 Launch할 때 MIME 유형을 정의하는 옵션이 제공됩니다.
contract가 자동적으로 호환성을 확인하므로 간단하게 Launcher를 실행하기만 하면 됩니다.
* 해당 기기가 Photo Picker를 지원하지 않을 경우 fallback은 ACTION_OPEN_DOCUMENT 인텐트
private val singlePhotoPickerLauncher = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { imageUri: Uri? ->
imageUri?.let(viewModel::setImageUri)
}
private fun pickPhoto() {
singlePhotoPickerLauncher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
launch 메서드의 인수로 PickVisualMediaRequest 인스턴스와 PickVisualMedia 타입을 추가해 커스터마이징할 수 있으며, 가능한 타입은 다음과 같습니다.
- Select image and video: PickVisualMedia.ImageAndVideo
- Select image only: PickVisualMedia.ImageOnly
- Select video only: PickVisualMedia.VideoOnly
- Select other MIME types: PickVisualMedia.SingleMimeType("YourMimeType")
👍https://medium.com/tech-takeaways/android-13-photo-picker-with-the-activity-result-api-b4a74572e354
Android 13 Photo Picker With The Activity Result API
About All Possible Options To Implement The New Photo Picker With Easy Access And Backward Compatibility
medium.com
https://developer.android.com/training/data-storage/shared/photopicker?hl=ko
사진 선택 도구 | Android 개발자 | Android Developers
DataStore는 로컬 데이터를 저장하는 최신 방법을 제공합니다. SharedPreferences 대신 DataStore를 사용해야 합니다. 자세한 내용은 DataStore 가이드를 참고하세요. 사진 선택 도구 컬렉션을 사용해 정리하
developer.android.com
No matching ... gradle 8.0.0 관련 에러
File -> Settings -> Build, Execution, Deployment -> Build Tools -> Gradle 들어가 JDK를 11로 변경
https://github.com/Dhaval2404/ImagePicker
GitHub - Dhaval2404/ImagePicker: 📸Image Picker for Android, Pick an image from Gallery or Capture a new image with Camera
📸Image Picker for Android, Pick an image from Gallery or Capture a new image with Camera - GitHub - Dhaval2404/ImagePicker: 📸Image Picker for Android, Pick an image from Gallery or Capture a new im...
github.com
https://rccode.tistory.com/288
[Kotlin] Android Custom Gallery Image Picker 만들기
배경 안드로이드에서 Multiple Image Picker를 구현하려면 직접 구현해야만 합니다. TedPicker 같이 매우 좋은 라이브러리가 이미 나와있으나, 저 같은 경우에는 진행중인 프로젝트의 디자인 통일성을
rccode.tistory.com
[안드로이드/코틀린] 카메라/갤러리 사진 이미지뷰에 로딩하기
0.기본 변수 private lateinit var binding: ActivityIdRegisterBinding private var picture_flag = 0 private var fileAbsolutePath: String? = null 1.카메라에서 사진을 찍은 후 갤러리에 저장 후 이미지뷰에 로딩하기 1)Gradle 설정 //
aal-izz-well.tistory.com
'안드로이드 > 안드로이드 실습' 카테고리의 다른 글
[안드로이드/Kotlin] Jetpack Compose 레이아웃 실습 (0) | 2023.04.17 |
---|---|
[안드로이드]앱 아이콘 변경하기 (0) | 2023.02.03 |
[안드로이드/자바] RecyclerView 구현하기 (0) | 2022.07.21 |
[안드로이드/자바] Custom Toolbar에 메뉴기능 추가하기 (0) | 2022.07.21 |
[안드로이드/자바] 기본 Toolbar Custom하기 (0) | 2022.07.21 |