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 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. De cette façon, votre activité ne se relance 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 fois 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 en quittant l'application pour les versions antérieures à Android 12

Pour ajouter la fonctionnalité PIP pour les versions antérieures à Android 12, utilisez addOnUserLeaveHintProvider. Pour ajouter le mode PiP pour les versions antérieures à Android 12, procédez comme suit:

  1. Ajoutez une porte de version afin 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: () -> 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")
}

Ajouter le mode PiP lorsque l'utilisateur quitte l'application pour Android 12 et versions ultérieures

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 mise en page seront utilisées dans une prochaine étape.
  2. Créez une variable pour le 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 générateur et définissez-le sur true pour passer en mode PiP lors du balayage. Cela offre une animation plus fluide que d'utiliser 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 le format de la fenêtre PiP

Pour définir le format de la fenêtre PiP, vous pouvez choisir un format spécifique ou utiliser la largeur et la hauteur de la taille vidéo du lecteur. Si vous utilisez un lecteur media3, vérifiez que le lecteur n'est pas nul et que sa taille vidéo n'est pas égale à [VideoSize.UNKNOWN][6] 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 dépasse les limites valides du format, votre application plantera. Vous devrez peut-être ajouter des vérifications pour savoir quand le format peut être calculé, comme c'est le cas pour un lecteur media3.