En la etiqueta de actividad de tu archivo AndroidManifest.xml, haz lo siguiente:
- Agrega
supportsPictureInPicturey configúralo comotruepara declarar que usarás el modo de pantalla en pantalla (PIP) en tu app. - Agrega
configChangesy configúralo comoorientation|screenLayout|screenSize|smallestScreenSizepara especificar que tu actividad controla los cambios de configuración de diseño. De esta manera, tu actividad no se reinicia cuando se producen 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 PIP en la app de Leave para versiones anteriores a Android 12
Para agregar PIP en versiones anteriores a Android 12, usa addOnUserLeaveHintProvider. Sigue estos pasos para agregar PiP en versiones anteriores a Android 12:
- Agrega una puerta de versión para que solo se acceda a este código en las versiones de O a R.
- Usa un
DisposableEffectconContextcomo clave. - Dentro de
DisposableEffect, define el comportamiento para cuando se activeonUserLeaveHintProvidercon una lambda. En la expresión lambda, llama aenterPictureInPictureMode()enfindActivity()y pasaPictureInPictureParams.Builder().build(). - Agrega
addOnUserLeaveHintListenerconfindActivity()y pasa la expresión lambda. - En
onDispose, agregaremoveOnUserLeaveHintListenerconfindActivity()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 = Runnable { 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ó PIP en la app de Leave para versiones posteriores a Android 12
Después de Android 12, se agrega PictureInPictureParams.Builder a través de un modificador que se pasa al reproductor de video de la app.
- Crea un
modifiery llama aonGloballyPositioneden él. Las coordenadas de diseño se usarán en un paso posterior. - Crea una variable para
PictureInPictureParams.Builder(). - Agrega una sentencia
ifpara verificar si el SDK es S o posterior. Si es así, agregasetAutoEnterEnabledal compilador y configúralo comotruepara ingresar al modo PIP cuando se deslice el dedo. Esto proporciona una animación más fluida que la que se obtiene conenterPictureInPictureMode. - Usa
findActivity()para llamar asetPictureInPictureParams(). Llama abuild()en elbuildery 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 de media3, verifica que el reproductor no sea nulo y que el tamaño del video del reproductor no sea igual a VideoSize.UNKNOWN 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 sale de los límites válidos del aspecto que puede tener la relación de aspecto, la 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 de media3.