Android : ActivityResultContract를 사용하여 이미지 선택 앱에서 여러 이미지 선택 (EXTRA_ALLOW_MULTIPLE)

9225 단어 안드로이드Kotlin
ActivityResultContract를 사용하여 외부 이미지 선택 앱을 실행하여 사용자가 여러 이미지를 선택하게 합니다.

단일 이미지 선택으로 상관하지 않으면 아래 문서를 참조하십시오.

Android 표준 이미지 선택 앱이 아닌 Google Photos를 실행하여 여러 이미지를 선택하려면 다음 도움말을 참조하세요.

필요한 권한



외부 이미지 선택 앱에서 이미지를 선택하고 이미지를 읽으려면 READ_EXTERNAL_STORAGE 권한이 필요하지 않습니다.

이미지 선택 앱이 기기에 저장된 이미지를 읽을 수 있는 권한을 얻었으며 사용자가 선택한 이미지가 Intent 게시자의 앱이 읽을 수 있는 경로로 반환되기 때문입니다.

전제



AndroidX 및 AndroidX Fragment가 도입되었다고 가정합니다.

구현



복수 이미지 선택에 대응한 GetContentsContract를 구현합니다.
class GetContentsContract : ActivityResultContract<String, List<String>?>() {
    override fun createIntent(context: Context, input: String): Intent {
        return Intent(Intent.ACTION_GET_CONTENT)
            .addCategory(Intent.CATEGORY_OPENABLE)
            .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
            .setType(input)
    }

    override fun parseResult(resultCode: Int, intent: Intent?): List<String>? {
        return if (resultCode == Activity.RESULT_OK) {
            intent?.clipData?.let { clipData ->
                (0 until clipData.itemCount).mapNotNull {
                    clipData.getItemAt(it).uri?.toString()
                }
            } ?: intent?.data?.toString()?.let { listOf(it) }
        } else null
    }
}

GetContentsContract를 사용하여 여러 이미지 선택을 수행합니다.
class MyFragment: Fragment() {
    private val getContentsLauncher = registerForActivityResult(
        GetContentsContract()
    ) { uris ->
        if (uris != null) {
            // 画像が選択された
            // content://com.android.providers.media.documents/...
            // のような Content Provider 形式の URI を受け取ります
        } else {
            // 画像選択がキャンセルされた
        }
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val binding = /* ... */
        binding.button.setOnClickListener {
            getContentsLauncher.launch("image/*")
        }
    }
// ...

해설



ACTION_GET_CONTENT은 여러 이미지 선택을 지원합니다.

ACTION_GET_CONTENT 이외에, EXTRA_ALLOW_MULTIPLE 에 true 를 지정하면 복수 선택이 됩니다.

다중 선택 결과는 Intent.clipData에 저장됩니다. ClipData.getItemAt() 로 ClipData.itemCount 까지 꺼낼 수 있습니다. ClipData.Item 의 uri 에 선택한 파일의 경로가 포함되어 있습니다.

이미지 선택 앱에서 사용자가 하나의 이미지를 선택하면 clipData 대신 intent.data에 파일 경로가 포함될 수 있습니다. intent.clipData 로부터 값을 취득할 수 없으면 단일 파일 선택으로 간주해, inetnet.data 로부터 파일 패스 취득하도록 하고 있습니다.

실행 결과



다음과 같이 Android 표준 이미지 선택 앱이 실행됩니다.

이미지 선택 앱의 모양과 동작은 OS 버전 및 기기 유형에 따라 다릅니다.

아래의 표준 앱에서는 여러 이미지를 선택할 수 있도록 해도 이미지를 탭하면 단일 파일을 선택하여 확정되어 버리는 것 같습니다.



사용자가 이미지를 길게 누르면 다음과 같이 다중 선택 UI가 됩니다.



표준 이미지 선택 앱은 왼쪽 드로어 메뉴에서 Google Photos 앱을 호출할 수도 있습니다.

Google Photos 앱 선택 화면은 이 화면을 연 상태로 이미 여러 이미지 선택 표시가 되어 있습니다.



주의사항



EXTRA_ALLOW_MULTIPLE을 사용한 다중 이미지 선택 Intent는 쉽게 구현할 수 있지만 다음과 같은 제한 사항이 있습니다.

다중 이미지 선택 Intent는 편리하지만 덜 융통성이 없으며 실제로 활약하는 장면은 적을 수 있습니다.

선택할 수 있는 파일 수의 상한을 지정할 수 없음



Android 표준 이미지 선택 앱이나 Google Photos에서 선택할 수 있는 최대 이미지 수를 지정할 수 없습니다. 사용자가 선택한 분이 모두 Intent에 반환됩니다.

이미지 선택 Intent 호출자의 앱에서 Intent 결과에서 파일 수를 줄이는지 아니면 무한 파일 선택을 지원할지 여부를 고려하고 해결할 수 있어야 합니다.

이미 선택한 파일 목록을 전달하여 선택한 상태에서 시작할 수 없습니다.



Android 표준 이미지 선택 앱이든 Google Photos이든 이미지 선택을 시작할 때 모든 이미지를 선택한 것처럼 표시할 수 없습니다. Intent를 발행할 때마다 모두 선택되지 않은 상태에서 시작합니다. 특정 이미지를 숨기는 기능도 없습니다.

좋은 웹페이지 즐겨찾기