Konfigurowanie funkcji PIP w aplikacji

W tagu aktywności pliku AndroidManifest.xml:

  1. Dodaj element supportsPictureInPicture i ustaw go na true, aby zadeklarować, że w aplikacji będziesz używać trybu Picture-in-Picture.
  2. Dodaj zmienną configChanges i ustaw ją na orientation|screenLayout|screenSize|smallestScreenSize, aby określić, że Twoja aktywność obsługuje zmiany konfiguracji układu. Dzięki temu aktywność nie będzie się uruchamiać ponownie, gdy nastąpi zmiana układu podczas przełączania się między trybami.

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

W kodzie usługi Compose wykonaj te czynności:

  1. Dodaj to rozszerzenie w witrynie Context. W tym przewodniku wielokrotnie będziesz używać tego rozszerzenia, aby uzyskać dostęp do aktywności.
    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")
    }

Dodawanie PiP w przypadku aplikacji, które nie obsługują Androida 12

Aby dodać PiP na urządzeniach z Androidem w wersji 12 lub starszej, użyj addOnUserLeaveHintProvider. Aby dodać PiP w przypadku wersji Androida 12 lub starszych:

  1. Dodaj bramkę wersji, aby ten kod był dostępny tylko w wersjach od O do R.
  2. Użyj DisposableEffect z kluczem Context.
  3. W elemencie DisposableEffect określ zachowanie, które ma być wykonywane, gdy element onUserLeaveHintProvider zostanie wywołany za pomocą funkcji lambda. W funkcji lambda wywołaj funkcję enterPictureInPictureMode() w obiekcie findActivity() i przekaż parametr PictureInPictureParams.Builder().build().
  4. Dodaj addOnUserLeaveHintListener za pomocą findActivity() i przekaż wyrażenie lambda.
  5. W funkcji onDispose dodaj funkcję removeOnUserLeaveHintListener za pomocą funkcji findActivity() i przekaż ją do funkcji 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")
}

Dodawanie PiP w aplikacji Leave na Androidzie 12 i nowszych

W Androidzie 12 i nowszych PictureInPictureParams.Builder jest dodawane za pomocą modyfikatora przekazywanego do odtwarzacza wideo aplikacji.

  1. Utwórz modifier i na nim wywołaj funkcję onGloballyPositioned. współrzędnych układu, które będą używane w dalszym kroku.
  2. Utwórz zmienną dla PictureInPictureParams.Builder().
  3. Dodaj instrukcję if, aby sprawdzić, czy pakiet SDK ma wersję S lub nowszą. Jeśli tak, dodaj setAutoEnterEnabled do kreatora i ustaw je na true, aby włączyć tryb PiP po przesunięciu palcem. Dzięki temu animacja będzie płynniejsza niż w przypadku korzystania z enterPictureInPictureMode.
  4. Aby zadzwonić do setPictureInPictureParams(), użyj aplikacji findActivity(). Zadzwoń pod numer build() na builder i przekaż informacje.

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)

Użyj setAspectRatio, aby ustawić proporcje okna PiP

Aby ustawić format obrazu okna PiP, możesz wybrać określony format obrazu lub użyć szerokości i wysokości rozmiaru filmu w odtwarzaczu. Jeśli używasz odtwarzacza media3, przed ustawieniem formatu obrazu sprawdź, czy odtwarzacz nie jest pusty i czy rozmiar filmu nie jest równy [VideoSize.UNKNOWN][6].

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)

Jeśli używasz odtwarzacza niestandardowego, ustaw jego proporcje wysokości i szerokości za pomocą składni właściwej dla tego odtwarzacza. Pamiętaj, że jeśli podczas inicjowania odtwarzacz zmieni rozmiar i wyjdzie poza dopuszczalne granice formatu obrazu, aplikacja ulegnie awarii. Może być konieczne dodanie kontroli, gdy można obliczyć współczynnik proporcji, podobnie jak w przypadku odtwarzacza media3.