В теге activity файла AndroidManifest.xml выполните следующие действия:
- Добавьте
supportsPictureInPictureи задайте значениеtrue, чтобы указать, что в приложении будет использоваться режим "картинка в картинке". - Добавьте
configChangesи задайте для него значениеorientation|screenLayout|screenSize|smallestScreenSize, чтобы указать, что ваше действие обрабатывает изменения конфигурации макета. Это позволит избежать перезапуска действия при изменении макета во время перехода в режим "Картинка в картинке".
<activity
android:name=".SnippetsActivity"
android:exported="true"
android:supportsPictureInPicture="true"
android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
android:theme="@style/Theme.Snippets">
В коде Compose выполните следующие действия:
- Добавьте это расширение на сайте
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") }
Как добавить режим "Картинка в картинке" при выходе из приложения на устройствах с Android 11 и более ранними версиями
Чтобы добавить режим "Картинка в картинке" для версий до Android 12, используйте addOnUserLeaveHintProvider. Чтобы добавить режим "Картинка в картинке" в Android 11 и более ранних версиях, выполните следующие действия:
- Добавьте проверку версии, чтобы этот код выполнялся только в версиях от O до R.
- Используйте
DisposableEffectс ключомContext. - Внутри
DisposableEffectопределите поведение при активацииonUserLeaveHintProviderс помощью лямбда-выражения. В лямбда-выражении вызовите методenterPictureInPictureMode()дляfindActivity()и передайтеPictureInPictureParams.Builder().build(). - Добавьте
addOnUserLeaveHintListenerс помощьюfindActivity()и передайте лямбда-выражение. - В
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 = 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") }
Как добавить режим "Картинка в картинке" при выходе из приложения в Android 12 и более поздних версиях
В Android 12 и более поздних версиях PictureInPictureParams.Builder добавляется с помощью модификатора, который передается в видеопроигрыватель приложения.
- Создайте объект
modifierи вызовите для него методonGloballyPositioned. Координаты макета понадобятся вам на следующем шаге. - Создайте переменную для
PictureInPictureParams.Builder(). - Добавьте оператор
if, чтобы проверить, используется ли SDK версии S или более поздней. Если да, добавьте в конструкторsetAutoEnterEnabledи задайте значениеtrue, чтобы при проведении по экрану включался режим "Картинка в картинке". Это обеспечивает более плавную анимацию, чем при использованииenterPictureInPictureMode. - Используйте
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, чтобы задать соотношение сторон окна в режиме "картинка в картинке".
Чтобы задать соотношение сторон окна картинки в картинке, вы можете выбрать определенное соотношение сторон или использовать ширину и высоту видео в проигрывателе. Если вы используете проигрыватель media3, перед настройкой соотношения сторон убедитесь, что проигрыватель не равен null и размер видео в нем не равен 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)
Если вы используете собственный проигрыватель, задайте соотношение сторон, указав высоту и ширину проигрывателя с помощью синтаксиса, который поддерживается вашим проигрывателем. Если размер проигрывателя изменится во время инициализации и соотношение сторон выйдет за допустимые пределы, приложение завершит работу со сбоем. Возможно, вам потребуется добавить проверки, чтобы определить, когда можно рассчитать соотношение сторон, как это делается для проигрывателя media3.