App für BiB einrichten

Führen Sie im Aktivitäts-Tag Ihrer AndroidManifest.xml-Datei folgende Schritte aus:

  1. Fügen Sie supportsPictureInPicture hinzu und setzen Sie es auf true, um anzugeben, dass Sie PiP in Ihrer App verwenden.
  2. Fügen Sie configChanges hinzu und setzen Sie es auf orientation|screenLayout|screenSize|smallestScreenSize, um anzugeben, dass Ihre Aktivität Änderungen an der Layoutkonfiguration verarbeitet. So wird die Aktivität nicht neu gestartet, wenn das Layout während des Wechsels in den PiP-Modus geändert wird.

      <activity
        android:name=".SnippetsActivity"
        android:exported="true"
        android:supportsPictureInPicture="true"
        android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
        android:theme="@style/Theme.Snippets">

Gehen Sie in Ihrem Compose-Code so vor:

  1. Fügen Sie diese Erweiterung auf Context hinzu. Sie verwenden diese Erweiterung im Laufe des Leitfadens mehrmals, um auf die Aktivität zuzugreifen.
    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")
    }

PiP-Unterstützung für Apps hinzufügen, die vor Android 12 veröffentlicht wurden

Wenn Sie BiB auf Geräten mit einer älteren Android-Version hinzufügen möchten, verwenden Sie addOnUserLeaveHintProvider. So fügst du PiP für Versionen vor Android 12 hinzu:

  1. Fügen Sie ein Versions-Gate hinzu, damit auf diesen Code nur in den Versionen O bis R zugegriffen wird.
  2. Verwenden Sie eine DisposableEffect mit Context als Schlüssel.
  3. Definieren Sie innerhalb des DisposableEffect das Verhalten, das ausgeführt werden soll, wenn die onUserLeaveHintProvider mithilfe eines Lambda ausgelöst wird. Rufen Sie im Lambda enterPictureInPictureMode() auf findActivity() auf und übergeben Sie PictureInPictureParams.Builder().build().
  4. Fügen Sie addOnUserLeaveHintListener mit findActivity() hinzu und übergeben Sie das Lambda.
  5. Fügen Sie in onDispose removeOnUserLeaveHintListener mit findActivity() hinzu und übergeben Sie das 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")
}

PiP-Unterstützung für den App-Hintergrund für Android 12 und höher hinzufügen

Ab Android 12 wird der PictureInPictureParams.Builder über einen Modifikator hinzugefügt, der an den Videoplayer der App übergeben wird.

  1. Erstellen Sie einen modifier und rufen Sie onGloballyPositioned darauf auf. Die Layoutkoordinaten werden in einem späteren Schritt verwendet.
  2. Erstellen Sie eine Variable für die PictureInPictureParams.Builder().
  3. Fügen Sie eine if-Anweisung hinzu, um zu prüfen, ob das SDK die Version S oder höher hat. Wenn ja, fügen Sie dem Builder setAutoEnterEnabled hinzu und legen Sie als Wert true fest, damit der PiP-Modus durch Wischen aktiviert wird. Das führt zu einer flüssigeren Animation als bei der Verwendung von enterPictureInPictureMode.
  4. Mit findActivity() setPictureInPictureParams() anrufen Rufen Sie build() auf dem builder auf und übergeben Sie es.

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)

Mit setAspectRatio das Seitenverhältnis des PiP-Fensters festlegen

Du kannst das Seitenverhältnis des PiP-Fensters entweder festlegen oder die Breite und Höhe der Videogröße des Players verwenden. Wenn du einen media3-Player verwendest, prüfe, ob der Player nicht null ist und die Videogröße des Players nicht [VideoSize.UNKNOWN][6] entspricht, bevor du das Seitenverhältnis festlegst.

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)

Wenn du einen benutzerdefinierten Player verwendest, lege das Seitenverhältnis für die Höhe und Breite des Players mit der für deinen Player spezifischen Syntax fest. Wenn der Player während der Initialisierung seine Größe ändert und außerhalb der zulässigen Grenzen für das Seitenverhältnis fällt, stürzt deine App ab. Möglicherweise musst du prüfen, wann das Seitenverhältnis berechnet werden kann, ähnlich wie bei einem media3-Player.