Настройте свое приложение для PiP

В теге активности файла AndroidManifest.xml выполните следующие действия:

  1. Добавьте supportsPictureInPicture и установите для него значение true чтобы заявить, что вы будете использовать PiP в своем приложении.
  2. Добавьте configChanges и установите для него значение orientation|screenLayout|screenSize|smallestScreenSize , чтобы указать, что ваша активность обрабатывает изменения конфигурации макета. Таким образом, ваша деятельность не перезапускается при изменении макета во время перехода в режим PiP.

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

В коде Compose выполните следующие действия:

  1. Добавьте это расширение в Context . Вы будете использовать это расширение несколько раз на протяжении всего руководства для доступа к упражнению.
    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")
    }

Добавьте приложение «PiP при выходе» для версий до Android 12.

Чтобы добавить PiP для версий до Android 12, используйте addOnUserLeaveHintProvider . Выполните следующие действия, чтобы добавить PiP для версий до Android 12:

  1. Добавьте шлюз версии, чтобы доступ к этому коду был возможен только в версиях от O до R.
  2. Используйте DisposableEffect с Context в качестве ключа.
  3. Внутри DisposableEffect определите поведение, когда onUserLeaveHintProvider запускается с помощью лямбда-выражения. В лямбде вызовите enterPictureInPictureMode() в findActivity() и передайте PictureInPictureParams.Builder().build() .
  4. Добавьте addOnUserLeaveHintListener с помощью findActivity() и передайте лямбду.
  5. В onDispose добавьте removeOnUserLeaveHintListener с помощью findActivity() и передайте лямбда-выражение.

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")
}

Добавьте приложение «PiP при выходе из отпуска» для версии после Android 12.

В версии после Android 12 PictureInPictureParams.Builder добавляется с помощью модификатора, который передается видеопроигрывателю приложения.

  1. Создайте modifier и вызовите для него onGloballyPositioned . Координаты макета будут использоваться на более позднем этапе.
  2. Создайте переменную для PictureInPictureParams.Builder() .
  3. Добавьте оператор if , чтобы проверить, является ли SDK версией S или выше. Если да, добавьте setAutoEnterEnabled в конструктор и установите для него значение true , чтобы переходить в режим PiP при пролистывании. Это обеспечивает более плавную анимацию, чем при использовании enterPictureInPictureMode .
  4. Используйте findActivity() для вызова setPictureInPictureParams() . Вызовите build() в builder и передайте его.

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)

Используйте setAspectRatio , чтобы установить соотношение сторон окна PiP.

Чтобы установить соотношение сторон окна PiP, вы можете выбрать определенное соотношение сторон или использовать ширину и высоту размера видео плеера. Если вы используете проигрыватель media3, перед установкой соотношения сторон убедитесь, что значение проигрывателя не равно нулю и размер видео проигрывателя не равен [ 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)

Если вы используете собственный проигрыватель, установите соотношение сторон по высоте и ширине проигрывателя, используя синтаксис, специфичный для вашего проигрывателя. Имейте в виду, что если ваш плеер изменит размер во время инициализации, если он выйдет за допустимые границы возможного соотношения сторон, ваше приложение выйдет из строя. Возможно, вам придется добавить проверки того, когда можно вычислить соотношение сторон, аналогично тому, как это делается для проигрывателя media3.