Встроенный инструмент выбора фотографий

Анимация, показывающая процесс выбора фотографий

Встроенный инструмент выбора фотографий – это другой способ выбора фотографий, позволяющий взаимодействовать с ними непосредственно в пользовательских интерфейсах приложений. По сравнению с классическим инструментом выбора фотографий он предлагает расширенные возможности интеграции и настройки. Поскольку он отображается в SurfaceView с помощью метода setChildSurfacePackage, он сохраняет те же функции безопасности и конфиденциальности, что и невстроенная версия.

Благодаря встроенному инструменту выбора фотографий пользователи могут непрерывно выбирать фотографии и видео как со своего устройства, так и из облачной библиотеки фотографий, не теряя фокуса в клиентском приложении. Клиентское приложение остается активным, его активность находится в возобновленном состоянии и может реагировать на выбор пользователя в режиме реального времени.

Встроенное окно выбора фотографий обеспечивает более удобную интеграцию с интерфейсом, но сохраняет те же функции безопасности и конфиденциальности, что и стандартное окно выбора фотографий, поскольку оно отображается в специальном SurfaceView.

Поддерживаемые устройства

Встроенное окно выбора фотографий поддерживается на устройствах с Android 14 (уровень API 34) и SDK Extensions версии 15 или более поздней.

На устройствах, которые не соответствуют этим требованиям, можно использовать классический инструмент выбора фотографий или его бэкпорт-версию, работающую на основе сервисов Google Play.

Зависимость библиотеки Jetpack

Добавьте библиотеку выбора фотографий Jetpack в качестве зависимости:

// For apps using Jetpack Compose
implementation("androidx.photopicker:photopicker-compose:1.0.0-alpha01")

// For apps using Views
implementation("androidx.photopicker:photopicker:1.0.0-alpha01")

Встроить инструмент выбора фотографий можно с помощью Jetpack Compose (рекомендуется) или Views.

Интеграция с Jetpack Compose

Компонуемая функция EmbeddedPhotoPicker позволяет встроить интерфейс выбора фотографий непосредственно в экран Jetpack Compose. Эта composable-функция создает объект SurfaceView, в котором размещается интерфейс встроенного инструмента выбора фотографий. Он управляет подключением к сервису EmbeddedPhotoPicker, обрабатывает действия пользователя и передает URI выбранных медиафайлов вызывающему приложению. Для работы ему требуется несколько параметров:

val coroutineScope = rememberCoroutineScope()
val pickerState = rememberEmbeddedPhotoPickerState()

EmbeddedPhotoPicker(
    state = pickerState,
    onUriPermissionGranted = { uris ->
        _attachments.value += uris
    },
    onUriPermissionRevoked = { uris ->
        _attachments.value -= uris
    },
    onSelectionComplete = {
        // Hide the embedded photo picker as the user is done with the
        // photo/video selection
    },
)

Непрерывный выбор

Анимация, показывающая процесс выбора фотографий

Встроенный инструмент выбора фотографий позволяет пользователям непрерывно выбирать и отменять выбор элементов из библиотеки фотографий, не закрывая инструмент выбора. Объекты, выбранные и отмененные в интерфейсе приложения, синхронизируются с инструментом выбора фотографий, что обеспечивает удобство работы пользователей.

Отмените выбор Uri с помощью метода deselectUri или deselectUris из pickerState, чтобы уведомить встроенный инструмент выбора о том, что пользователь отменил выбор объекта в интерфейсе приложения. Обновлять состояние пользовательского интерфейса приложения вручную необходимо, поскольку вызов этих методов не уведомляет приложение о новых отозванных URI через обратный вызов onUriPermissionRevoked.

coroutineScope.launch {
    // Signal unselected media to the picker
    pickerState.deselectUris(uris)
    // Remove them from the list of selected media to be reflected in the app's UI
    _attachments.value -= uris
}

Как настроить инструмент выбора фотографий

Встроенный инструмент выбора фотографий предлагает варианты персонализации, позволяя вам настраивать его внешний вид и поведение, чтобы лучше интегрировать его с дизайном вашего приложения и пользовательским интерфейсом.

Цвет элементов

По умолчанию встроенный инструмент выбора фотографий использует динамические цвета, предоставляемые системой, которые пользователь может задать для всех приложений в настройках темы устройства. Цвет акцента будет использоваться для различных основных элементов в инструменте выбора фотографий. Все остальные цвета будут заданы в соответствии с рекомендациями по дизайну Android. Чтобы настроить цвет акцента в окне выбора, задайте параметр EmbeddedPhotoPickerFeatureInfo:

val info = EmbeddedPhotoPickerFeatureInfo.Builder().setAccentColor(0xFF0000).build()

EmbeddedPhotoPicker(
    embeddedPhotoPickerFeatureInfo = info,
    ...
)
Без цвета акцента С цветом акцента (пик) С цветом акцента (развернутое)
Скриншот окна выбора фотографий без настройки цвета акцента Скриншот выбора фотографий с цветом акцента (пик) Скриншот окна выбора фотографий с цветом акцента (развернуто)

Цвет акцента должен быть полностью непрозрачным. Значение альфа-канала (прозрачности) игнорируется. Допускаются только цвета со значением яркости от 0,05 до 0,9.

Размеры

По умолчанию размер встроенного окна выбора не ограничен, но вы можете указать модификатор, чтобы ограничить его:

EmbeddedPhotoPicker(
    modifier = Modifier.height(500.dp),
    ...
)
Без ограничений (развернуто) С ограничением 500 dp (развернутый)
Скриншот инструмента выбора фотографий Скриншот инструмента выбора фотографий

Интеграция с представлениями

Чтобы добавить встроенный инструмент выбора фотографий с помощью Views, добавьте запись в файл макета:

<view class="androidx.photopicker.EmbeddedPhotoPickerView"
    android:id="@+id/photopicker"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Затем инициализируйте инструмент выбора фотографий в методе onCreate своего объекта activity, выполнив следующие действия:

  1. Получите ссылку на EmbeddedPhotoPickerView из макета.
  2. Добавьте EmbeddedPhotoPickerStateChangeListener для обработки событий выбора
  3. Настройте инструмент выбора фотографий с помощью EmbeddedPhotoPickerFeatureInfo, включая любые пользовательские настройки, например цвет акцента.
// Keep track of the selected media
private val _attachments = MutableStateFlow(emptyList<Uri>())
val attachments = _attachments.asStateFlow()

private lateinit var picker: EmbeddedPhotoPickerView
private var openSession: EmbeddedPhotoPickerSession? = null

val pickerListener = object : EmbeddedPhotoPickerStateChangeListener {
    override fun onSessionOpened(newSession: EmbeddedPhotoPickerSession) {
        // Keep reference to the session to notify the embedded picker of user
        // interactions on the calling app
        openSession = newSession
    }

    override fun onSessionError(throwable: Throwable) {}

    override fun onUriPermissionGranted(uris: List<Uri>) {
        // Add newly selected media to our tracked list
        _attachments += uris
    }

    override fun onUriPermissionRevoked(uris: List<Uri>) {
        // Remove newly unselected media from our tracked list
        _attachments -= uris
    }

    override fun onSelectionComplete() {
        // Hide the embedded photo picker as the user is done with the
        // photo/video selection
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.main_view)
    picker = findViewById(R.id.photopicker)

    // Attach the embedded picker event listener to update the app's UI
    picker.addEmbeddedPhotoPickerStateChangeListener(pickerListener)

    // Customize embedded picker's features: accent color, max selectable items,
    // pre-selected URIs, filter out mime types
    picker.setEmbeddedPhotoPickerFeatureInfo(
        // Set a custom accent color
        EmbeddedPhotoPickerFeatureInfo.Builder().setAccentColor(0xFF0000).build()
    )
}

Вы можете вызывать различные методы EmbeddedPhotoPickerSession для взаимодействия со встроенным инструментом выбора:

// Notify the embedded picker of a configuration change
openSession.notifyConfigurationChanged(newConfig)

// Update the embedded picker to expand following a user interaction
openSession.notifyPhotoPickerExpanded(/* expanded: */ true)

// Resize the embedded picker
openSession.notifyResized(/* width: */ 512, /* height: */ 256)

// Show/hide the embedded picker (after a form has been submitted)
openSession.notifyVisibilityChanged(/* visible: */ false)

// Remove unselected media from the embedded picker after they have been
// unselected from the host app's UI
openSession.requestRevokeUriPermission(removedUris)