En la etiqueta de actividad de tu archivo AndroidManifest.xml
, haz lo siguiente:
- Agrega
supportsPictureInPicture
y configúralo comotrue
para declarar que usarás PiP en tu app. Agrega
configChanges
y configúralo comoorientation|screenLayout|screenSize|smallestScreenSize
para especificar que tu actividad controla los cambios de configuración de diseño. De esta manera, tu actividad no se reinicia cuando se realizan cambios de diseño durante las transiciones del modo de PIP.<activity android:name=".SnippetsActivity" android:exported="true" android:supportsPictureInPicture="true" android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize" android:theme="@style/Theme.Snippets">
En tu código de Compose, haz lo siguiente:
- Agrega esta extensión en
Context
. Usarás esta extensión varias veces a lo largo de la guía para acceder a la actividad.internal fun Context.findActivity(): ComponentActivity { var context = this while (context is ContextWrapper) { if (context is ComponentActivity) return context context = context.baseContext } throw IllegalStateException("Picture in picture should be called in the context of an Activity") }
Agrega el modo PIP en la app para salir en versiones anteriores a Android 12
Para agregar PiP para versiones anteriores a Android 12, usa addOnUserLeaveHintProvider
. Sigue estos pasos para agregar PiP a versiones anteriores a Android 12:
- Agrega una puerta de versión para que solo se pueda acceder a este código en las versiones O hasta R.
- Usa un
DisposableEffect
conContext
como clave. - Dentro de
DisposableEffect
, define el comportamiento para cuando se activeonUserLeaveHintProvider
con una lambda. En la expresión lambda, llama aenterPictureInPictureMode()
enfindActivity()
y pasaPictureInPictureParams.Builder().build()
. - Agrega
addOnUserLeaveHintListener
confindActivity()
y pasa la lambda. - En
onDispose
, agregaremoveOnUserLeaveHintListener
confindActivity()
y pasa la lambda.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.S ) { val context = LocalContext.current DisposableEffect(context) { val onUserLeaveBehavior: () -> Unit = { context.findActivity() .enterPictureInPictureMode(PictureInPictureParams.Builder().build()) } context.findActivity().addOnUserLeaveHintListener( onUserLeaveBehavior ) onDispose { context.findActivity().removeOnUserLeaveHintListener( onUserLeaveBehavior ) } } } else { Log.i("PiP info", "API does not support PiP") }
Se agregó el modo PIP en la app de salir para versiones posteriores a Android 12.
Después de Android 12, PictureInPictureParams.Builder
se agrega a través de un modificador que se pasa al reproductor de video de la app.
- Crea un
modifier
y llama aonGloballyPositioned
. Las coordenadas del diseño se usarán en un paso posterior. - Crea una variable para el
PictureInPictureParams.Builder()
. - Agrega una sentencia
if
para verificar si el SDK es S o una versión posterior. Si es así, agregasetAutoEnterEnabled
al compilador y configúralo comotrue
para ingresar al modo PiP cuando se deslice el dedo. Esto proporciona una animación más fluida que pasar porenterPictureInPictureMode
. - Usa
findActivity()
para llamar asetPictureInPictureParams()
. Llama abuild()
en elbuilder
y pásalo.
val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(true) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
Usa setAspectRatio
para establecer la relación de aspecto de la ventana de PiP
Para establecer la relación de aspecto de la ventana de PiP, puedes elegir una relación de aspecto específica o usar el ancho y la altura del tamaño del video del reproductor. Si usas un reproductor media3, verifica que no sea nulo y que el tamaño del video no sea igual a [VideoSize.UNKNOWN
][6] antes de establecer la relación de aspecto.
val context = LocalContext.current val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) { val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect() builder.setSourceRectHint(sourceRect) builder.setAspectRatio( Rational(player.videoSize.width, player.videoSize.height) ) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(shouldEnterPipMode) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
Si usas un reproductor personalizado, establece la relación de aspecto en la altura y el ancho del reproductor con la sintaxis específica de tu reproductor. Ten en cuenta que, si el reproductor cambia de tamaño durante la inicialización y se encuentra fuera de los límites válidos de la relación de aspecto, tu app fallará. Es posible que debas agregar verificaciones sobre cuándo se puede calcular la relación de aspecto, de manera similar a como se hace para un reproductor media3.