Selector de fotos incorporado

Animación que muestra el proceso de selección continua del selector de fotos

El selector de fotos integrado es una forma diferente de experiencia de selección de fotos, ya que permite interactuar directamente con él en las interfaces de usuario de las apps. Ofrece opciones de integración y personalización mejoradas en comparación con el selector de fotos clásico. Como se renderiza en un SurfaceView con el método setChildSurfacePackage, mantiene las mismas funciones de seguridad y privacidad que la versión no integrada.

Con el selector de fotos integrado, los usuarios pueden seleccionar fotos y videos de forma continua desde su dispositivo y su biblioteca de fotos en la nube sin perder el enfoque en la app cliente. La app cliente permanece activa, su actividad está en estado reanudado y puede responder a las selecciones del usuario en tiempo real.

El selector de fotos integrado ofrece una integración de la IU más fluida, pero mantiene las mismas funciones de seguridad y privacidad que el selector de fotos estándar, ya que se renderiza en un SurfaceView especial.

Disponibilidad de dispositivos

El selector de fotos integrado es compatible con dispositivos que ejecutan Android 14 (nivel de API 34) con la versión 15 o posterior de las extensiones del SDK.

Los dispositivos que no coinciden con estas capacidades pueden usar el selector de fotos clásico o la versión con portabilidad a versiones anteriores a través de los Servicios de Google Play.

Dependencia de la biblioteca de Jetpack

Incluye la biblioteca del selector de fotos de Jetpack como una dependencia:

// 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")

Puedes integrar el selector de fotos incorporado con Jetpack Compose (recomendado) o Views.

Integración de Jetpack Compose

La función de componibilidad EmbeddedPhotoPicker proporciona un mecanismo para incluir la IU del selector de fotos integrado directamente en la pantalla de Jetpack Compose. Este elemento componible crea un SurfaceView que aloja la IU del selector de fotos integrado. Administra la conexión al servicio EmbeddedPhotoPicker, controla las interacciones del usuario y comunica los URIs de los medios seleccionados a la aplicación que realiza la llamada con pocos parámetros para trabajar:

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
    },
)

Selección continua

Animación que muestra el proceso de selección continua del selector de fotos

El selector de fotos integrado permite a los usuarios seleccionar y anular la selección de elementos de la biblioteca de fotos de forma continua sin cerrar el selector. Los elementos seleccionados y deseleccionados en la IU de la app se sincronizan con el selector de fotos, lo que proporciona una experiencia del usuario fluida.

Anula la selección de Uri con el método deselectUri o deselectUris de pickerState para notificar al selector integrado que el usuario anuló la selección de un elemento de la IU de la app. Es necesario que actualices manualmente el estado de la IU de tu app, ya que llamar a estos métodos no notificará a tu app sobre ningún URI revocado recientemente a través de la devolución de llamada 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
}

Personaliza el selector de fotos

El selector de fotos integrado ofrece opciones de personalización, lo que te permite adaptar su apariencia y comportamiento para que se integre mejor con el diseño y la experiencia del usuario de tu app.

Color de los elementos destacados

De forma predeterminada, el selector de fotos integrado se basa en los colores dinámicos proporcionados por el sistema que el usuario puede establecer en las opciones de temas del dispositivo. El color de resalte se usará para varios elementos principales en el selector de fotos. Todos los demás colores se establecerán según los lineamientos de Material de Android. Para personalizar el color de los elementos destacados del selector, define la opción EmbeddedPhotoPickerFeatureInfo:

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

EmbeddedPhotoPicker(
    embeddedPhotoPickerFeatureInfo = info,
    ...
)
Sin configurar el color de los elementos destacados Con color de acento (máximo) Con color de los elementos destacados (expandido)
Captura de pantalla del selector de fotos sin configurar el color de los elementos destacados Captura de pantalla del selector de fotos con color de énfasis (pico) Captura de pantalla del selector de fotos con color de énfasis (expandido)

El color de énfasis debe ser completamente opaco. Se ignora el valor alfa (transparencia). Solo se permiten colores con un valor de luminancia (brillo) entre 0.05 y 0.9.

Dimensiones

De forma predeterminada, el tamaño del selector integrado no está limitado, pero puedes especificar un modificador para limitarlo:

EmbeddedPhotoPicker(
    modifier = Modifier.height(500.dp),
    ...
)
Sin límite (expandido) Con límite de 500 dp (expandido)
Captura de pantalla del selector de fotos Captura de pantalla del selector de fotos

Integración de Views

Para agregar el selector de fotos integrado con Views, agrega una entrada a tu archivo de diseño:

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

Luego, inicializa el selector de fotos en el método onCreate de tu actividad haciendo lo siguiente:

  1. Obtén una referencia a tu EmbeddedPhotoPickerView desde el diseño
  2. Agrega el EmbeddedPhotoPickerStateChangeListener para controlar los eventos de selección
  3. Configura el selector de fotos con EmbeddedPhotoPickerFeatureInfo, incluidos los parámetros de configuración personalizados, como el color de énfasis.
// 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()
    )
}

Puedes llamar con los diferentes métodos de EmbeddedPhotoPickerSession para interactuar con el selector integrado:

// 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)