AndroidManifest.xml
파일의 활동 태그에서 다음을 실행합니다.
supportsPictureInPicture
를 추가하고true
로 설정하여 앱에서 PiP를 사용하겠다고 선언합니다.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 코드에서 다음을 실행합니다.
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 12 이전 버전의 앱에 앱 종료 시 PIP 추가
Android 12 이전 버전의 PIP를 추가하려면 addOnUserLeaveHintProvider
를 사용하세요. Android 12 이전 버전의 PIP를 추가하려면 다음 단계를 따르세요.
- 이 코드가 O~R 버전에서만 액세스되도록 버전 게이트를 추가합니다.
Context
를 키로 사용하여DisposableEffect
를 사용합니다.DisposableEffect
내에서 람다를 사용하여onUserLeaveHintProvider
가 트리거될 때의 동작을 정의합니다. 람다에서findActivity()
에서enterPictureInPictureMode()
를 호출하고PictureInPictureParams.Builder().build()
를 전달합니다.findActivity()
를 사용하여addOnUserLeaveHintListener
를 추가하고 람다를 전달합니다.onDispose
에서findActivity()
를 사용하여removeOnUserLeaveHintListener
를 추가하고 람다를 전달합니다.
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") }
Android 12 이후 버전의 앱에 앱 종료 시 PIP 추가
Android 12 이후에는 앱의 동영상 플레이어에 전달되는 수정자를 통해 PictureInPictureParams.Builder
가 추가됩니다.
modifier
를 만들고 이modifier
에서onGloballyPositioned
를 호출합니다. 레이아웃 좌표는 이후 단계에서 사용됩니다.PictureInPictureParams.Builder()
의 변수를 만듭니다.if
문을 추가하여 SDK가 S 이상인지 확인합니다. 그렇다면 빌더에setAutoEnterEnabled
를 추가하고true
로 설정하여 스와이프 시 PiP 모드로 전환합니다. 이렇게 하면enterPictureInPictureMode
을 거치는 것보다 더 부드러운 애니메이션을 제공할 수 있습니다.findActivity()
를 사용하여setPictureInPictureParams()
를 호출합니다.builder
에서build()
를 호출하고 전달합니다.
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 플레이어를 사용하는 경우 가로세로 비율을 설정하기 전에 플레이어가 null이 아니고 플레이어의 동영상 크기가 [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 플레이어에서 하는 것처럼 가로세로 비율을 계산할 수 있는 시점에 관한 검사를 추가해야 할 수 있습니다.