일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 하이퍼링크
- 네트워크 디버깅
- 네트워크 위변조
- textColorLink
- 네트워크 인스펙터
- TextView
- linksClickable
- Photo Picker
- app
- xmlns
- 안드로이드
- Android13
- DataBinding
- autolink
- network inspector
- Android
- BIND
- Today
- Total
애증의 개발일지
[Android 13] Photo Picker에 대해 알아보자 본문
Photo Picker란?
Android13부터 새롭게 등장한 Visual Media Picking Tool입니다. 쉽게 말해서 새롭게 안드로이드에서 제공하는 이미지/비디오 피커라고 생각하시면 됩니다.
Photo Picker는 이전에 Android에서 일반적으로 사용되던 문서 선택기 기능이 확장된 것입니다. 위 사진이 바로 문서 선택기입니다.(콘텐츠 파일 접근을 위해 Intent.ACTION_PICK, Intent.ACTION_GET_CONTENT등을 Activity Action으로 설정했을 때, 한 번쯤은 본 화면일 것입니다. 아님말고..)
새롭게 등장한 Photo Picker는 구글 피셜.. browsable하고 searchable한 인터페이스를 제공한다고 합니다. 개인적으로, Photo Picker의 디자인은 이전과 비교하면 꽤나 괜찮다고 생각합니다.. 확실히 Android12이상부터는 구글에서 디자인에 힘(?)을 많이 쓰는게 보이는 것 같네요.. 아무튼 Photo Picker에 대해 보다 자세히 알아봅시다..!
Photo Picker의 특징
표준화된 내장 UI를 제공한다.
built-in, standardized UI for apps, which creates a more consistent user experience.
이미지들이 날짜별로 정렬된 내장 이미지 피커를 제공합니다. 크게 Photos와 Albums 탭이 존재하고, Albums 탭에서는 카테고리(디렉토리)별로 유저가 탐색할 수 있는 UI를 제공합니다.
Photo Picker는 기본적으로 위 사진과 같이 바텀시트 기반의 UI로 구성 되어있습니다. Android11(SDK 30)까지는 Backporting을 하는 게 맞지만, Android11-12의 경우 추가적으로 다음 조건을 만족해야 위와 같은 UI의 Photo Picker가 실행됩니다.
- SDK Extensions의 버전이 2 이상일 것
그렇지 않다면(SDK 버전이 30(Android 11)미만이거나, 11이상이어도 SDK Extensions의 버전이 2미만일 경우) 기존의 문서 선택기 형태의 이미지 피커가 등장하게 됩니다.
Photo Picker를 호출하는 PickVisualMedia 클래스 내부의 createIntent 메소드를 확인하면 이 부분을 더 쉽게 이해할 수 있습니다.
해당 두 코드에서 알 수 있는 점은 아래와 같습니다.
- TIRAMISU(SDK 33)버전 이상에서는 Photo Picker가 실행된다.
- REDVELVET CAKE(SDK 30)버전 이상에서는 SDK Extension의 버전이 2 이상이어야 Photo Picker가 실행된다.
- 그 외 하위 버전에서는, Photo Picker를 호출해도 결과적으로 문서 선택기가 호출된다.
해당 부분을 참고해서 개발하면 더 좋을 것 같네요..!
별도의 권한 요청이 필요없다.
기존, 이미지와 같은 미디어 파일들에 접근할 때는 READ_EXTERNAL_STORAGE 권한 요청이 필수적이었습니다. 그러나, 유저들과 개발자들로부터 이와 관련된 항의(권한 요청 자체가 UX적으로 사용자를 귀찮게 한다. 개발이 어렵다 등등.. 참고로 이 부분 뇌피셜아니고 공식 디벨로퍼 블로그에 진짜로 이렇게 나와있습니다.)를 받은 구글은.. 이번 Android13에서는 이러한 권한 요청을 별도로 요구하지않는 Photo Picker를 출시하게 되었습니다.
그래서 가급적 이번 업데이트 이후부터는 이미지, 동영상과 같은 미디어 파일에 대한 액세스를 제공할때는. 가급적 Photo Picker를 활용하는 것을 추천한다고 합니다. 만약 Photo Picker를 활용하지 않을 경우 Android 13이상을 타겟팅 할 때 세분화된 미디어 권한을 잘 체크해주시길 바랍니다.(Android 13부터 READ_EXTERNAL_STORAGE권한은 사용하지 않습니다!)
구현이 쉽다.(aka. 커스텀이 쉽다)
아마 개발자들에겐 이 부분이 가장 매력적일 것이라 생각이 드네요.. 기존의 안드로이드에서 제공하는 문서 선택기 같은 경우 커스텀이 어렵고, 개발하는 프로젝트의 UI/UX와 맞추기 힘든 부분이 많았습니다. 커스텀 피커를 만들자니, 개발 난이도가 높은 문제가 있었고.. 서드파티를 쓰자니, 버전 대응에 있어 많은 문제가 있었습니다. 이러한 점을 이번 Photo Picker에서 상당 부분 해결하였습니다. Photo Picker에서는 아래와 같은 속성들이 커스텀 됩니다. 참고로, 피커 자체 디자인을 변경하는 것은 어려우니 이 점 주의해주세요. 팀에서 프로젝트만의 커스텀 디자인 피커를 원한다면.. RIP.. Photo Picker가 지원되지않는 버전도 RIP...
- 단일선택/다중선택
- 다중선택 시 개수 제한
- 미디어 파일 타입 지정(이미지 OR 비디오)
현재(2022. 10. 15) 기준, Photo Picker에서는 로컬 저장소에 있는 이미지와 비디오 데이터만을 지원합니다. 하지만, 향후 업데이트를 통해, CloudMediaProvider API와 혼합하여 Cloud Storage에 있는 데이터도 지원한다고 합니다.
사용 방법
1. 기초 세팅
// groovy
dependencies {
// Java language implementation
implementation "androidx.activity:activity:1.6.0"
// Kotlin
implementation "androidx.activity:activity-ktx:1.6.0"
}
// kts
dependencies {
// Java language implementation
implementation("androidx.activity:activity:1.6.0")
// Kotlin
implementation("androidx.activity:activity-ktx:1.6.0")
}
gradle에 androidx.activity 추가 (버전 1.6.0이상)
2. 단일 이미지 선택
private val pickMedia = registerForActivityResult(PickVisualMedia()) { uri ->
// 사진 선택 이후 돌아왔을 때 콜백
if (uri != null) {
// 선택된 사진이 있을 경우
} else {
// 선택된 사진이 없을 경우
}
}
단일 이미지 선택의 경우 PickVisualMedia 클래스를 활용해서 구현합니다. 갤러리에 갔다가 돌아왔을 때 사진을 가져와서 가공해야되기 때문에, registerForActivityResult를 활용해서 콜백형식으로 구현합니다.
// 이미디와 비디오 모두
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))
// 이미지만
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly))
// 비디오만
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.VideoOnly))
// MIME 타입 지원.
// ex. GIF
val mimeType = "image/gif"
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.SingleMimeType(mimeType)))
launch로 ActivityResultLauncher를 실행할 때, PickVisualMediaRequest()메소드에 VisualMediaType을 파라미터로 전달하면, 포토피커에서 해당 타입 기반으로 데이터를 필터링해주게 됩니다. 제공해주는 VisualMediaType은 아래와 같이 4가지입니다. 해당 타입들은 다중 이미지 선택시에도 동일하게 적용가능합니다.
3. 다중 이미지 선택
// 다중 선택
// PickMultipleVisualMedia 클래스의 생성자로 maxItems(사진 개수 제한)을 넘겨줄 수 있음.
val pickMultipleMedia =
registerForActivityResult(PickMultipleVisualMedia(5)) { uris ->
// 콜백
if (uris.isNotEmpty()) {
// uri 리스트에 값이 있을 경우
} else {
// uri 리스트에 값이 없을 경우
}
}
// 마찬가지로 VisualMediaType 지정가능
pickMultipleMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))
다중 이미지 선택의 경우, PickMultipleVisualMedia 클래스와 registerForActivityResult를 혼합해서 구현합니다. PickMultipleVisualMedia 클래스의 경우 생성자로 maxItems를 갖습니다. maxItems는 사진 개수 제한을 지정하는 속성입니다.(maxItems는 무조건 1보다 큰 수로 지정해야합니다. 그렇지 않으면 RuntimeException을 발생시킵니다.)
maxItems는 default value로 getMaxItems()함수의 리턴 값을 갖습니다. getMaxItems()의 경우 아래와 같은 반환값을 가집니다.
- SDK 33이상(TIRAMISU)에서는 getPickImagesMaxLimit()를 반환합니다.
- 그 이하에서는 Integer.MAX_VALUE를 반환합니다.
- 주의사항 : maxItems를 지정하더라도, Photo Picker가 지원되는 디바이스가 아니라면(즉, 문서 선택기가 뜨는 디바이스라면), 사진 개수 제한 기능이 지원되지않습니다.
실행화면은 위 gif와 같습니다. 개수 제한(해당 사진에선 5개) 넘게 사진을 선택하려고하면 스낵바 알러트가 뜹니다. 단일 선택 모드와 달리 다중 선택 모드에서는 바텀시트가 EXPANDED된 상태로 시작합니다.(단일 선택 모드는 HALF EXPANDED 형태)
4. 영구적인 파일 액세스 권한이 필요할 때
일반적으로, Android OS에서는 Application이 멈추기 전까지(혹은 재시작 전까지)만 파일에 접근할 수 있는 권한을 부여합니다. Application이 종료되고도 계속해서 파일 접근이 필요할 경우(ex. 백그라운드에서 용량이 큰 미디어 파일을 업로드하는 경우) takePersistableUriPermission()를 호출하면 됩니다.
개인적으로 Photo Picker는 Android13에서 가장 흥미로운 기능이라고 생각합니다. 별도의 권한처리를 요구하지 않는 것도 좋고.. 기존 문서 선택기에 굉장히 흠이 많아서(특히 다중 선택 개수제한이 안되는 거라던가..) Photo Picker의 등장은 굉장히 반가울 따름입니다. 하지만.. 대응되는 버전이 Android11부터(그마저도 SDK Extension 버전이 2 이상인 디바이스만 지원..)라는 점이 조금 아쉬운 것 같습니다.. 아직은 대다수 프로젝트의 minSdk가 Android11보다 낮은 경우가 많으니까요.. 물론 이 부분은 향후 업데이트가 될 수도..?(라는 행복회로..)
해당 포스트가 Android13 Photo Picker 사용에 있어 도움이 되면 좋겠습니다. 감사합니다.
참고자료
https://medium.com/androiddevelopers/permissionless-is-the-future-of-storage-on-android-3fbceeb3d70a
https://developer.android.com/training/data-storage/shared/photopicker
https://developers-kr.googleblog.com/2022/08/android-13-is-in-aosp.html
https://developer.android.com/about/versions/13/behavior-changes-13#granular-media-permissions