Configurare l'app per PIP

Nel tag attività del file AndroidManifest.xml:

  1. Aggiungi supportsPictureInPicture e impostalo su true per dichiarare che utilizzerai la modalità Picture in picture (PIP) nella tua app.
  2. Aggiungi configChanges e impostalo su orientation|screenLayout|screenSize|smallestScreenSize per specificare che la tua attività gestisce le modifiche alla configurazione del layout. In questo modo, la tua attività non viene riavviata quando si verificano modifiche al layout durante le transizioni della modalità PIP.
<activity
    android:name=".SnippetsActivity"
    android:exported="true"
    android:supportsPictureInPicture="true"
    android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
    android:theme="@style/Theme.Snippets">

Nel codice Compose:

  1. Aggiungi questa estensione su Context. Utilizzerai questa estensione più volte nella guida per accedere all'attività.
    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")
    }

Aggiungere la funzionalità PIP all'app per le ferie per le versioni precedenti di Android 12

Per aggiungere la modalità PIP per le versioni precedenti ad Android 12, utilizza addOnUserLeaveHintProvider. Segui questi passaggi per aggiungere la modalità PIP per le versioni precedenti di Android 12:

  1. Aggiungi un gate di versione in modo che questo codice sia accessibile solo nelle versioni da O a R.
  2. Utilizza un DisposableEffect con Context come chiave.
  3. All'interno di DisposableEffect, definisci il comportamento per l'attivazione di onUserLeaveHintProvider utilizzando una funzione lambda. Nella lambda, chiama enterPictureInPictureMode() su findActivity() e passa PictureInPictureParams.Builder().build().
  4. Aggiungi addOnUserLeaveHintListener utilizzando findActivity() e passa nella lambda.
  5. In onDispose, aggiungi removeOnUserLeaveHintListener utilizzando findActivity() e passa 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")
}

Aggiungere la funzionalità PIP all'app per le richieste di ferie per le versioni successive ad Android 12

Dopo Android 12, PictureInPictureParams.Builder viene aggiunto tramite un modificatore passato al video player dell'app.

  1. Crea un modifier e chiama onGloballyPositioned. Le coordinate del layout verranno utilizzate in un passaggio successivo.
  2. Crea una variabile per PictureInPictureParams.Builder().
  3. Aggiungi un'istruzione if per verificare se l'SDK è S o versioni successive. In caso affermativo, aggiungi setAutoEnterEnabled al generatore e impostalo su true per attivare la modalità PIP quando scorri. In questo modo l'animazione è più fluida rispetto a quella che si ottiene con enterPictureInPictureMode.
  4. Usa il numero findActivity() per chiamare setPictureInPictureParams(). Chiama build() al numero builder e passalo.

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)

Utilizzare setAspectRatio per impostare le proporzioni della finestra PIP

Per impostare le proporzioni della finestra PIP, puoi scegliere proporzioni specifiche o utilizzare la larghezza e l'altezza delle dimensioni del video del player. Se utilizzi un player Media3, verifica che il player non sia nullo e che le dimensioni del video del player non siano uguali a VideoSize.UNKNOWN prima di impostare le proporzioni.

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)

Se utilizzi un player personalizzato, imposta le proporzioni sull'altezza e la larghezza del player utilizzando la sintassi specifica del player. Tieni presente che se il player viene ridimensionato durante l'inizializzazione, se esce dai limiti validi di ciò che il formato può essere, l'app si arresterà in modo anomalo. Potresti dover aggiungere controlli su quando è possibile calcolare le proporzioni, in modo simile a quanto avviene per un player Media3.