PiP zur richtigen Zeit starten

Ihre App sollte in den folgenden Situationen nicht in den BiB-Modus wechseln:

  • Ob das Video angehalten oder beendet wurde.
  • Wenn Sie sich in der App auf einer anderen Seite als dem Videoplayer befinden.

Wenn Sie steuern möchten, wann Ihre App in den BiB-Modus wechselt, fügen Sie eine Variable hinzu, die den Status des Videoplayers mithilfe eines mutableStateOf verfolgt.

Status je nach Videowiedergabe umschalten

Wenn Sie den Status basierend darauf umschalten möchten, ob der Videoplayer gerade eine Wiedergabe ausführt, fügen Sie dem Videoplayer einen Listener hinzu. Ändern Sie den Status der Statusvariablen je nachdem, ob der Player gerade spielt oder nicht:

player.addListener(object : Player.Listener {
    override fun onIsPlayingChanged(isPlaying: Boolean) {
        shouldEnterPipMode = isPlaying
    }
})

Status basierend darauf umschalten, ob der Player freigegeben ist

Wenn der Player freigegeben wird, legen Sie die Statusvariable auf false fest:

fun releasePlayer() {
    shouldEnterPipMode = false
}

Mit dem Status definieren, ob der BiB-Modus aufgerufen wird (vor Android 12)

  1. Da beim Hinzufügen von BiB vor Android 12 ein DisposableEffect verwendet wird, müssen Sie eine neue Variable mit rememberUpdatedState erstellen, wobei newValue als Statusvariable festgelegt ist. So wird sichergestellt, dass die aktualisierte Version in der DisposableEffect verwendet wird.
  2. Fügen Sie in der Lambda-Funktion, die das Verhalten beim Auslösen von OnUserLeaveHintListener definiert, eine if-Anweisung mit der Statusvariablen um den Aufruf von enterPictureInPictureMode() herum ein:

    val currentShouldEnterPipMode by rememberUpdatedState(newValue = shouldEnterPipMode)
    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 {
                if (currentShouldEnterPipMode) {
                    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")
    }

Mit dem Status wird definiert, ob der BiB-Modus aufgerufen wird (ab Android 12).

Übergeben Sie Ihre Statusvariable an setAutoEnterEnabled, damit Ihre App nur zum richtigen Zeitpunkt in den BiB-Modus wechselt:

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()

    // Add autoEnterEnabled for versions S and up
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)

setSourceRectHint für eine flüssige Animation verwenden

Die setSourceRectHint API sorgt für eine flüssigere Animation beim Wechsel in den BiB-Modus. Unter Android 12 und höher wird außerdem eine flüssigere Animation für das Beenden des BiB-Modus erstellt. Fügen Sie diese API dem PiP-Builder hinzu, um den Bereich der Aktivität anzugeben, der nach dem Übergang in den PiP-Modus sichtbar ist.

  1. Fügen Sie setSourceRectHint() nur dann der builder hinzu, wenn der Status angibt, dass die App in den PiP-Modus wechseln soll. So wird die Berechnung von sourceRect vermieden, wenn die App nicht in den BiB-Modus wechseln muss.
  2. Verwenden Sie die layoutCoordinates, die von der Funktion onGloballyPositioned für den Modifier angegeben werden, um den sourceRect-Wert festzulegen.
  3. Rufen Sie setSourceRectHint() für builder auf und übergeben Sie die Variable sourceRect.

val context = LocalContext.current

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()
    if (shouldEnterPipMode) {
        val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()
        builder.setSourceRectHint(sourceRect)
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)