사진 선택 도구

기기의 미디어 파일과 함께 표시되는 사진 선택 도구 대화상자 앱에 공유할 사진 선택
그림 1. 앱에 사진을 공유할 수 있는 직관적인 UI를 제공하는 사진 선택 도구

사진 선택 도구는 사용자에게 미디어 라이브러리를 표시하는 탐색 가능한 인터페이스를 제공하며, 이러한 인터페이스는 최근 날짜부터 오래된 날짜순으로 정렬됩니다. 개인 정보 보호 권장사항 Codelab에서 볼 수 있듯이 사진 선택 도구는 사용자가 앱에 미디어 라이브러리 전체가 아닌 선택한 이미지 및 동영상에 대해서만 액세스 권한을 부여하도록 내장된 안전한 방법을 제공합니다.

기기에 적격한 클라우드 미디어 제공업체가 있는 사용자는 원격으로 저장된 사진과 동영상에서 선택할 수도 있습니다. 클라우드 미디어 제공업체 자세히 알아보기

이 도구는 자동으로 업데이트되므로 코드를 변경할 필요 없이 시간이 지남에 따라 앱 사용자에게 확장된 기능을 제공합니다.

Jetpack 활동 계약 사용

사진 선택 도구 통합을 간소화하려면 androidx.activity 라이브러리 버전 1.7.0 이상을 포함해야 합니다.

다음 활동 결과 계약을 사용하여 사진 선택 도구를 실행합니다.

기기에서 사진 선택 도구를 사용할 수 없는 경우 라이브러리는 자동으로 ACTION_OPEN_DOCUMENT 인텐트 작업을 호출합니다. 이 인텐트는 Android 4.4(API 수준 19) 이상을 실행하는 기기에서 지원됩니다. isPhotoPickerAvailable()을 호출하여 특정 기기에서 사진 선택 도구를 사용할 수 있는지 확인할 수 있습니다.

단일 미디어 항목 선택

단일 미디어 항목을 선택하려면 다음 코드 스니펫에 표시된 것과 같이 PickVisualMedia 활동 결과 계약을 사용하세요.

// Registers a photo picker activity launcher in single-select mode.
val pickMedia = registerForActivityResult(PickVisualMedia()) { uri ->
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: $uri")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

// Launch the photo picker and let the user choose only images.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly))

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.VideoOnly))

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
val mimeType = "image/gif"
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.SingleMimeType(mimeType)))

// Registers a photo picker activity launcher in single-select mode.
ActivityResultLauncher<PickVisualMediaRequest> pickMedia =
        registerForActivityResult(new PickVisualMedia(), uri -> {
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: " + uri);
    } else {
        Log.d("PhotoPicker", "No media selected");
    }
});

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only images.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageOnly.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.VideoOnly.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
String mimeType = "image/gif";
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(new PickVisualMedia.SingleMimeType(mimeType))
        .build());

Compose

// Registers a photo picker activity launcher in single-select mode.
val pickMedia = rememberLauncherForActivityResult(PickVisualMedia()) { uri ->
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: $uri")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

// Launch the photo picker and let the user choose only images.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly))

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.VideoOnly))

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
val mimeType = "image/gif"
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.SingleMimeType(mimeType)))

여러 미디어 항목 선택

여러 미디어 항목을 선택하려면 다음 코드 스니펫에 표시된 것과 같이 선택 가능한 최대 미디어 파일 수를 설정하세요.

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
val pickMultipleMedia =
        registerForActivityResult(PickMultipleVisualMedia(5)) { uris ->
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (uris.isNotEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: ${uris.size}")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
ActivityResultLauncher<PickVisualMediaRequest> pickMultipleMedia =
        registerForActivityResult(new PickMultipleVisualMedia(5), uris -> {
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (!uris.isEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: " + uris.size());
    } else {
        Log.d("PhotoPicker", "No media selected");
    }
});

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

Compose

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
val pickMultipleMedia =
        rememberLauncherForActivityResult(PickMultipleVisualMedia(5)) { uris ->
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (uris.isNotEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: ${uris.size}")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

플랫폼은 개발자가 사용자에게 사진 선택 도구에서 선택하도록 요청할 수 있는 최대 파일 수를 제한합니다. 이 제한에 액세스하려면 getPickImagesMaxLimit()를 호출하세요. 사진 선택 도구가 지원되지 않는 기기에서는 이 제한이 무시됩니다.

대상 기기

사진 선택 도구는 다음 기준을 충족하는 기기에서 사용할 수 있습니다.

Android 4.4(API 수준 19)~Android 10(API 수준 29)을 실행하는 이전 기기와 Google Play 서비스를 지원하는 Android 11 또는 12를 실행하는 Android Go 기기에는 사진 선택 도구의 백포팅 버전을 설치하면 됩니다. Google Play 서비스를 통해, 백포팅된 사진 선택 도구 모듈의 자동 설치를 사용 설정하려면 앱의 매니페스트 파일에서 <application> 태그에 다음 항목을 추가하세요.

<!-- Trigger Google Play services to install the backported photo picker module. -->
<service android:name="com.google.android.gms.metadata.ModuleDependencies"
         android:enabled="false"
         android:exported="false"
         tools:ignore="MissingClass">
    <intent-filter>
        <action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
    </intent-filter>
    <meta-data android:name="photopicker_activity:0:required" android:value="" />
</service>

미디어 파일 액세스 유지

기본적으로 시스템은 기기가 다시 시작되거나 앱이 중지될 때까지 미디어 파일 액세스 권한을 앱에 부여합니다. 앱이 백그라운드에서 대용량 파일을 업로드하는 것과 같이 장기 실행 작업을 실행하는 경우 이러한 액세스를 더 오래 유지해야 할 수 있습니다. takePersistableUriPermission() 메서드를 호출하면 됩니다.

Kotlin

val flag = Intent.FLAG_GRANT_READ_URI_PERMISSION
context.contentResolver.takePersistableUriPermission(uri, flag)

Java

int flag = Intent.FLAG_GRANT_READ_URI_PERMISSION;
context.contentResolver.takePersistableUriPermission(uri, flag);