Configurare l'app per PIP

Nel tag attività del file AndroidManifest.xml:

  1. Aggiungi supportsPictureInPicture e impostalo su true per dichiarare che utilizzerai 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 in 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 PiP all'uscita dall'app per le versioni precedenti ad Android 12

Per aggiungere la modalità PiP per le versioni precedenti ad Android 12, usa addOnUserLeaveHintProvider. Segui questi passaggi per aggiungere la modalità PiP per le versioni precedenti ad Android 12:

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

Aggiungere PiP all'app di sfondo per le versioni successive ad Android 12

Dopo Android 12, PictureInPictureParams.Builder viene aggiunto tramite un modificatore che viene 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 questo caso, aggiungi setAutoEnterEnabled al generatore e impostalo su true per attivare la modalità PiP con uno scorrimento. In questo modo l'animazione sarà più fluida rispetto all'utilizzo di enterPictureInPictureMode.
  4. Usa findActivity() per chiamare setPictureInPictureParams(). Chiama build() su 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)

Usa 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 media3 player, controlla che il player non sia nullo e che le dimensioni del video del player non siano uguali a [VideoSize.UNKNOWN][6] prima di impostare il formato.

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 il formato dell'altezza e della larghezza del player utilizzando la sintassi specifica per il player. Tieni presente che se il player cambia dimensione durante l'inizializzazione e non rientra nei limiti validi per le proporzioni, l'app si arresta in modo anomalo. Potresti dover aggiungere controlli relativi al momento in cui è possibile calcolare il formato, in modo simile a quanto avviene per un media3 player.