Engineering note · Android

갤럭시 S21 갤러리 다중 선택 오류와 호환성 해결 방법

2025년 08월 01일이현수수정 2026.07.13
태그androidkotlinwebview

안드로이드 웹뷰에서 파일 선택 시 삼성 갤러리의 다중 선택(Multiple Selection)이 동작하지 않는 원인을 파악하고, ACTION_GET_CONTENT와 삼성 비공식 옵션으로 해결하는 방법을 정리한다.

웹뷰 기반 안드로이드 앱에서 사용자가 사진을 여러 장 선택해 업로드할 수 있도록 기능을 제공했다. 그런데 갤럭시 S21, 안드로이드 15에서 기본 갤러리 앱을 사용할 때, 여러 장 선택이 불가능하고 1장만 선택되는 문제가 있었다. 다른 사진 앨범 앱에서는 다중 선택이 됐다. 코드 레벨이나 기기 문제라기보다 삼성 기본 갤러리 앱 자체의 동작 방식 차이 로 추정했다.

문제 상황

안드로이드의 웹뷰에서 WebChromeClientonShowFileChooser 콜백을 구현해 파일 선택 인텐트를 실행한다. 보통 갤러리 사진을 선택하게 유도할 때 아래와 같이 Intent.ACTION_PICK을 많이 사용한다.

kotlin
// 갤러리 인텐트 설정
val contentSelectionIntent = Intent(
    Intent.ACTION_PICK,
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI
)
contentSelectionIntent.type = MediaStore.Images.Media.CONTENT_TYPE

if (isMultiple) {
    contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
}

하지만 삼성 갤러리 앱은 ACTION_PICK 인텐트를 처리할 때 Intent.EXTRA_ALLOW_MULTIPLE 옵션을 무시하는 경우가 많다. 이로 인해 사용자는 여러 장을 드래그하거나 선택할 수 없고 단일 이미지만 선택할 수밖에 없게 된다.

ACTION_PICK 시 단일 선택만 가능한 화면

앱의 사진 선택 버튼에서 기본 갤러리로 이동할 수는 있었지만, 갤러리 화면에는 여러 항목을 고르는 상태가 나타나지 않았다. 실제 제품 화면과 사진은 제외하고 앱 선택 단계와 단일 선택 상태만 남겼다.

해결 과정

1. ACTION_GET_CONTENT 사용 권장

안드로이드 공식 문서와 커뮤니티에서는 파일 다중 선택을 위해 ACTION_PICK보다는 Intent.ACTION_GET_CONTENT를 사용할 것을 권장한다. 파일 종류나 개수에 상관없이 콘텐츠를 가져오는 안드로이드 표준 방식이기 때문에 호환성이 더 높다.

ACTION_GET_CONTENT 콘텐츠 선택기 화면

ACTION_GET_CONTENT에서는 시스템 콘텐츠 선택기를 거쳐 사진 앱이나 파일 앱을 선택할 수 있고, 선택기에서 여러 항목을 고를 수 있다. 하지만 곧바로 갤러리가 열리기보다 '파일' 앱들이 먼저 뜨는 경우가 많아 UX 측면에서 불편할 수는 있다.

2. 삼성 갤러리 비공식 옵션 적용

삼성 갤러리에서 다중 선택을 강제하기 위한 비공식 파라미터를 추가할 수 있다.

kotlin
if (isMultiple) {
    contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
    
    // 삼성 디바이스 호환성을 위한 추가 설정
    contentSelectionIntent.putExtra("multi-pick", true)
    contentSelectionIntent.putExtra("return-data", false)
}

이렇게 multi-pick 파라미터를 명시하니까 다중 선택이 가능했었다.

응답(Result) 파싱 규격 대응

여기서 주의할 점이 있다. multi-pick 옵션으로 응답을 받으면 안드로이드 표준 규격인 ClipData가 아니라, 마치 파일을 공유하는 것처럼 ACTION_SEND_MULTIPLE 형태의 독자적인 규격으로 데이터가 넘어온다.

text
// standard
😀 registerForActivityResult 콜백 ActivityResult{resultCode=RESULT_OK, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/-1/1/content://media/external/images/media/63/ORIGINAL/NONE/image/jpeg/89489492 flg=0x1 clip={text/uri-list U:content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F63/ORIGINAL/NONE/image%2Fjpeg/89489492} }}

// samsung multi pic
😀 registerForActivityResult 콜백 ActivityResult{resultCode=RESULT_OK, data=Intent { act=android.intent.action.SEND_MULTIPLE flg=0x1 (has extras) }}

10:21:06.813  D  ----------------- Extras Dump -----------------
10:21:06.814  D  Key: selectedCount, Value: 4, Value Type: java.lang.Integer
10:21:06.815  D  Key: selectedItems, Value: [content://media/external/images/media/62, ...], Value Type: java.util.ArrayList
10:21:06.815  D  ---------------------------------------------

디버깅을 위해 응답 인텐트의 extras를 덤프떠서 확인해봤다. selectedItems라는 키에 Uri 목록이 담겨서 반환되므로, onActivityResultregisterForActivityResult 콜백에서 이 분기를 별도로 처리해야 한다.

kotlin
val SAMSUNG_MULTI_PICK_KEY = "selectedItems"

// 1. 안드로이드 표준 규격 처리
if (data.clipData != null) {
    // ClipData에서 URI 추출
} 
// 2. 삼성 갤러리 독자 규격 처리
else if (data.hasExtra(SAMSUNG_MULTI_PICK_KEY)) {
    val uris = mutableListOf<Uri>()
    
    // API 33(Tiramisu) 이상과 미만 호환성 분기
    val parcelableUris = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        data.getParcelableArrayListExtra(SAMSUNG_MULTI_PICK_KEY, Uri::class.java)
    } else {
        @Suppress("DEPRECATION")
        data.getParcelableArrayListExtra(SAMSUNG_MULTI_PICK_KEY)
    }
    
    parcelableUris?.let {
        uris.addAll(it)
    }
    
    // 웹뷰 콜백으로 Uri 배열 반환
    filePathCallbackLollipop?.onReceiveValue(uris.toTypedArray())
    filePathCallbackLollipop = null
}

이와 같이 삼성 전용 파라미터와 결과 처리 로직을 추가하면 기본 갤러리 앱에서도 다중 선택 기능을 온전히 제공할 수 있다.