Configurer votre application pour le PIP

Dans la balise d'activité de votre fichier AndroidManifest.xml, procédez comme suit :

  1. Ajoutez supportsPictureInPicture et définissez-le sur true pour déclarer que vous utiliserez le mode Picture-in-picture (PIP) dans votre application.
  2. Ajoutez configChanges et définissez-le sur orientation|screenLayout|screenSize|smallestScreenSize pour spécifier que votre activité gère les modifications de configuration de la mise en page. Ainsi, votre activité ne redémarre pas lorsque des modifications de mise en page se produisent lors des transitions en mode PIP.
<activity
    android:name=".SnippetsActivity"
    android:exported="true"
    android:supportsPictureInPicture="true"
    android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
    android:theme="@style/Theme.Snippets">

Dans votre code Compose, procédez comme suit :

  1. Ajoutez cette extension sur Context. Vous utiliserez cette extension à plusieurs reprises tout au long du guide pour accéder à l'activité.
    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")
    }

Ajouter le mode PIP à l'application Leave pour les versions antérieures à Android 12

Pour ajouter le mode PIP pour les versions antérieures à Android 12, utilisez addOnUserLeaveHintProvider. Pour ajouter le mode PIP pour les versions antérieures à Android 12 :

  1. Ajoutez un version gate pour que ce code ne soit accessible que dans les versions O à R.
  2. Utilisez un DisposableEffect avec Context comme clé.
  3. Dans DisposableEffect, définissez le comportement lorsque onUserLeaveHintProvider est déclenché à l'aide d'un lambda. Dans le lambda, appelez enterPictureInPictureMode() sur findActivity() et transmettez PictureInPictureParams.Builder().build().
  4. Ajoutez addOnUserLeaveHintListener à l'aide de findActivity() et transmettez le lambda.
  5. Dans onDispose, ajoutez removeOnUserLeaveHintListener à l'aide de findActivity() et transmettez le 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")
}

Ajouter le mode PIP à l'application Leave pour les versions d'Android ultérieures à la version 12

Après Android 12, le PictureInPictureParams.Builder est ajouté via un modificateur transmis au lecteur vidéo de l'application.

  1. Créez un modifier et appelez onGloballyPositioned dessus. Les coordonnées de la mise en page seront utilisées lors d'une prochaine étape.
  2. Créez une variable pour PictureInPictureParams.Builder().
  3. Ajoutez une instruction if pour vérifier si le SDK est S ou version ultérieure. Si tel est le cas, ajoutez setAutoEnterEnabled au compilateur et définissez-le sur true pour passer en mode PIP lors du balayage. Cela permet d'obtenir une animation plus fluide que celle obtenue avec enterPictureInPictureMode.
  4. Utilisez findActivity() pour appeler setPictureInPictureParams(). Appelez build() sur builder et transmettez-le.

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)

Utiliser setAspectRatio pour définir les proportions de la fenêtre PIP

Pour définir les proportions de la fenêtre PIP, vous pouvez choisir des proportions spécifiques ou utiliser la largeur et la hauteur de la taille de la vidéo du lecteur. Si vous utilisez un lecteur Media3, vérifiez que le lecteur n'est pas nul et que la taille de la vidéo du lecteur n'est pas égale à VideoSize.UNKNOWN avant de définir le format.

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 vous utilisez un lecteur personnalisé, définissez le format sur la hauteur et la largeur du lecteur à l'aide de la syntaxe spécifique à votre lecteur. Sachez que si votre lecteur est redimensionné lors de l'initialisation et qu'il sort des limites valides du format, votre application plantera. Vous devrez peut-être ajouter des vérifications pour déterminer quand le format peut être calculé, comme c'est le cas pour un lecteur Media3.