
Панель выбора фотографий предоставляет интерактивный интерфейс, отображающий пользователю его медиатеку, отсортированную по дате от самой новой к самой старой. Как показано в руководстве по лучшим практикам обеспечения конфиденциальности , панель выбора фотографий предоставляет безопасный встроенный способ для пользователей предоставлять вашему приложению доступ только к выбранным изображениям и видео, а не ко всей медиатеке.
Пользователи, у которых на устройстве установлены подходящие облачные медиапровайдеры, также могут выбирать фотографии и видео, хранящиеся удаленно. Узнайте больше об облачных медиапровайдерах .
Инструмент обновляется автоматически, предоставляя пользователям вашего приложения расширенные функциональные возможности с течением времени без необходимости внесения каких-либо изменений в код.
Используйте контракты Jetpack Activity.
Для упрощения интеграции средства выбора фотографий необходимо включить библиотеку androidx.activity версии 1.7.0 или выше.
Для запуска средства выбора фотографий используйте следующие контракты результатов действий:
-
PickVisualMedia, чтобы выбрать отдельное изображение или видео . -
PickMultipleVisualMedia, чтобы выбрать несколько изображений или видео .
Если средство выбора фотографий недоступно на устройстве, библиотека автоматически вызывает вместо него действие интента 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());
Сочинить
// 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());
Сочинить
// 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 11 (уровень API 30) или выше.
- Получайте изменения в модульных компонентах системы через обновления системы Google.
На более старых устройствах под управлением Android 4.4 (уровень API 19) до Android 10 (уровень API 29), а также на устройствах Android Go под управлением Android 11 или 12, поддерживающих сервисы Google Play, можно установить адаптированную версию модуля выбора фотографий. Чтобы включить автоматическую установку адаптированного модуля выбора фотографий через сервисы 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() :
Котлин
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);
Обработка HDR-видео с транскодированием
В Android 13 (API 33) появилась возможность записывать видео с расширенным динамическим диапазоном (HDR) . Хотя HDR обеспечивает более насыщенное изображение, некоторые старые приложения могут быть не готовы к обработке этих новых форматов, что приводит к таким проблемам, как неестественная цветопередача во время воспроизведения (например, лица с зеленоватым оттенком). Для решения этой проблемы совместимости в меню выбора фотографий реализована функция транскодирования, которая может автоматически преобразовывать HDR-видео в формат стандартного динамического диапазона (SDR) перед передачей их запрашивающему приложению.
Основная цель транскодирования в Photo Picker — обеспечить единообразное и визуально точное отображение медиаконтента в более широком спектре приложений, даже тех, которые еще не имеют явной поддержки HDR. Транскодируя HDR-видео в SDR, Photo Picker стремится улучшить совместимость приложений и обеспечить бесперебойную работу пользователя.
Как работает транскодирование при выборе фотографий
Функция транскодирования HDR в окне выбора фотографий по умолчанию отключена. Чтобы включить эту функцию, ваше приложение должно явно указать свои возможности обработки медиаформатов при запуске окна выбора фотографий.
Ваше приложение предоставляет средства обработки мультимедиа для средства выбора фотографий. Это происходит при запуске средства выбора фотографий с использованием библиотеки AndroidX Activity путем добавления mediaCapabilities в PickVisualMediaRequest.Builder . Для упрощения этого процесса в PickVisualMediaRequest.Builder добавлен новый API-интерфейс setMediaCapabilitiesForTranscoding(capabilities: MediaCapabilities?) .
Вы можете управлять поведением транскодирования HDR с помощью класса MediaCapabilities . Предоставьте объект MediaCapabilities точно указывающий, какие типы HDR поддерживает ваше приложение (например, TYPE_HLG10 , TYPE_HDR10 , TYPE_HDR10_PLUS , TYPE_DOLBY_VISION ).
Чтобы полностью отключить транскодирование, передайте null для MediaCapabilities . Любой тип HDR , не указанный явно в предоставленных вами возможностях, будет считаться неподдерживаемым. Этот API поддерживается на Android 13 (уровень API 33) и выше и аннотирован @RequiresApi(Build.VERSION_CODES.TIRAMISU) .
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
import androidx.annotation.RequiresApi
import android.os.Build
import android.util.Log
import android.provider.MediaStore
// Registers a photo picker activity launcher.
val pickMedia = registerForActivityResult(PickVisualMedia()) { uri ->
// Callback invoked after media selected or picker activity closed.
if (uri != null) {
Log.d("photo picker", "Selected URI: $uri")
} else {
Log.d("photo picker", "No media selected")
}
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
fun launchPhotoPickerWithTranscodingSupport() {
val mediaCapabilities = MediaCapabilities.Builder()
.addSupportedHdrType(MediaCapabilities.HdrType.TYPE_HLG10)
.build()
// Launch the photo picker and let the user choose only videos with
// transcoding enabled.
pickMedia.launch(PickVisualMediaRequest.Builder()
.setMediaType(PickVisualMedia.VideoOnly)
.setMediaCapabilitiesForTranscoding(mediaCapabilities)
.build())
}
Транскодирование с помощью инструмента выбора фотографий основано как на возможностях приложения в работе с медиафайлами, так и на выбранном видео. Если транскодирование выполнено, возвращается URI транскодированного видео.
Важные моменты, которые следует учитывать при транскодировании HDR.
- Производительность и хранение: транскодирование требует времени на обработку и создает новый файл, что занимает место на диске.
- Ограничение по длительности видео: для обеспечения баланса между удобством использования и ограничениями по объему памяти, продолжительность видео ограничена 1 минутой.
- Управление кэшированными файлами: кэшированные транскодированные файлы периодически очищаются во время простоя и технического обслуживания, чтобы предотвратить чрезмерное использование памяти.
- Доступность на устройстве: Транскодирование при выборе фотографий поддерживается на Android 13 (уровень API 33) и более поздних версиях .
- Интеграция AndroidX Activity: Убедитесь, что вы используете версию 1.11.0-alpha01 или более позднюю альфа/бета/RC/стабильную версию библиотеки AndroidX Activity, поскольку она включает необходимый API
setMediaCapabilitiesForTranscoding.