Konfigurowanie funkcji PIP w aplikacji

W tagu aktywności w pliku AndroidManifest.xml wykonaj te czynności:

  1. Dodaj supportsPictureInPicture i ustaw wartość true, aby zadeklarować, że będziesz używać w aplikacji trybu obraz w obrazie.
  2. Dodaj configChanges i ustaw wartość orientation|screenLayout|screenSize|smallestScreenSize, aby określić, że aktywność obsługuje zmiany konfiguracji układu. Dzięki temu aktywność nie zostanie ponownie uruchomiona, gdy podczas przejścia do trybu PIP nastąpią zmiany układu.
<activity
    android:name=".SnippetsActivity"
    android:exported="true"
    android:supportsPictureInPicture="true"
    android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
    android:theme="@style/Theme.Snippets">

W kodzie Compose wykonaj te czynności:

  1. Dodaj to rozszerzenie w witrynie Context. Aby uzyskać dostęp do aktywności, będziesz wielokrotnie korzystać z tego rozszerzenia.
    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 aplikacji do obsługi wniosków o urlop w przypadku wersji Androida starszych niż 12

Aby dodać obraz w obrazie na urządzeniu z Androidem starszym niż 12, użyj addOnUserLeaveHintProvider. Aby dodać tryb obrazu w obrazie w wersjach Androida starszych niż 12:

  1. Dodaj bramę wersji, aby ten kod był dostępny tylko w wersjach od O do R.
  2. Użyj DisposableEffect z kluczem Context.
  3. Wewnątrz DisposableEffect zdefiniuj działanie, które ma być wykonywane po uruchomieniu onUserLeaveHintProvider, za pomocą funkcji lambda. W funkcji lambda wywołaj enterPictureInPictureMode() na findActivity() i przekaż PictureInPictureParams.Builder().build().
  4. Dodaj addOnUserLeaveHintListener za pomocą findActivity() i przekaż lambdę.
  5. onDispose dodaj removeOnUserLeaveHintListener za pomocą findActivity() i przekaż wyrażenie 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")
}

Dodawanie trybu obrazu w obrazie w aplikacji urlopowej na urządzeniach z Androidem w wersji 12 lub nowszej

W przypadku Androida 12 i nowszych wersji parametr PictureInPictureParams.Builder jest dodawany za pomocą modyfikatora przekazywanego do odtwarzacza wideo aplikacji.

  1. Utwórz modifier i zadzwoń na numer onGloballyPositioned. Współrzędne układu zostaną użyte w późniejszym 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 do narzędzia do tworzenia parametr setAutoEnterEnabled i ustaw go na true, aby po przesunięciu palcem włączyć tryb obrazu w obrazie. Zapewnia to płynniejszą animację niż przechodzenie przez enterPictureInPictureMode.
  4. Użyj numeru findActivity(), aby zadzwonić na numer setPictureInPictureParams(). Zadzwoń pod numer build() na builder i przekaż go.

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 obrazu w obrazie.

Aby ustawić format obrazu okna PiP, możesz wybrać konkretny format lub użyć szerokości i wysokości odtwarzanego filmu. Jeśli używasz odtwarzacza media3, przed ustawieniem współczynnika proporcji sprawdź, czy odtwarzacz nie ma wartości null i czy rozmiar filmu w odtwarzaczu nie jest równy VideoSize.UNKNOWN.

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 niestandardowego odtwarzacza, ustaw współczynnik proporcji wysokości i szerokości odtwarzacza za pomocą składni właściwej dla Twojego odtwarzacza. Pamiętaj, że jeśli odtwarzacz zmieni rozmiar podczas inicjowania i wyjdzie poza prawidłowe granice współczynnika proporcji, aplikacja ulegnie awarii. Może być konieczne dodanie kontroli dotyczących tego, kiedy można obliczyć współczynnik proporcji, podobnie jak w przypadku odtwarzacza Media3.