
Средство выбора фотографий предоставляет пользователю удобный интерфейс, который отображает его медиатеку, отсортированную по дате создания от самых новых к самым старым. Как показано в лабораторной работе по лучшим практикам обеспечения конфиденциальности , средство выбора фотографий предоставляет пользователям безопасный встроенный способ предоставить вашему приложению доступ только к выбранным изображениям и видео, а не ко всей медиатеке.
Пользователи, у которых на устройстве есть соответствующие облачные сервисы, также могут выбирать фотографии и видео, хранящиеся удалённо. Узнайте больше о облачных сервисах .
Инструмент обновляется автоматически, со временем предлагая пользователям вашего приложения расширенные функциональные возможности без необходимости внесения каких-либо изменений в код.
Используйте контракты Jetpack Activity
Для упрощения интеграции средства выбора фотографий включите версию 1.7.0 или выше библиотеки androidx.activity
.
Для запуска средства выбора фотографий используйте следующие контракты результатов активности:
-
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)
Ява
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: убедитесь, что вы используете версию 1.11.0-alpha01 или более позднюю альфа/бета/RC/стабильную версию библиотеки активности AndroidX, так как она включает в себя необходимый API
setMediaCapabilitiesForTranscoding
.