configChanges를 추가하고 orientation|screenLayout|screenSize|smallestScreenSize로 설정하여 활동이 레이아웃 구성 변경을 처리하도록 지정합니다. 이렇게 하면 PIP 모드 전환 중에 레이아웃이 변경될 때 활동이 다시 시작되지 않습니다.
Context에 이 확장 프로그램을 추가합니다. 가이드에서 활동에 액세스하기 위해 이 확장 프로그램을 여러 번 사용합니다.
internalfunContext.findActivity():ComponentActivity{varcontext=thiswhile(contextisContextWrapper){if(contextisComponentActivity)returncontextcontext=context.baseContext}throwIllegalStateException("Picture in picture should be called in the context of an Activity")}
findActivity()를 사용하여 addOnUserLeaveHintListener를 추가하고 람다를 전달합니다.
onDispose에서 findActivity()를 사용하여 removeOnUserLeaveHintListener를 추가하고 람다를 전달합니다.
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O&&
Build.VERSION.SDK_INT < Build.VERSION_CODES.S){valcontext=LocalContext.currentDisposableEffect(context){valonUserLeaveBehavior:()->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 창의 가로세로 비율을 설정하려면 특정 가로세로 비율을 선택하거나 플레이어의 동영상 크기 너비와 높이를 사용하면 됩니다. media3 플레이어를 사용하는 경우 가로세로 비율을 설정하기 전에 플레이어가 null이 아니고 플레이어의 동영상 크기가 [VideoSize.UNKNOWN][6] 과 같지 않은지 확인합니다.
맞춤 플레이어를 사용하는 경우 플레이어별 문법을 사용하여 플레이어의 높이와 너비에 가로세로 비율을 설정합니다. 초기화 중에 플레이어 크기가 조정되면 가로세로 비율이 허용되는 유효 범위를 벗어나면 앱이 비정상 종료됩니다. media3 플레이어에서 하는 것처럼 가로세로 비율을 계산할 수 있는 시점에 관한 검사를 추가해야 할 수 있습니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-08-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-08-27(UTC)"],[],[],null,["In the activity tag of your `AndroidManifest.xml` file, do the following:\n\n1. Add `supportsPictureInPicture` and set it to `true` to declare you'll be using PiP in your app.\n2. Add `configChanges` and set it to\n `orientation|screenLayout|screenSize|smallestScreenSize` to specify that\n your activity handles layout configuration changes. This way, your activity\n doesn't relaunch when layout changes occur during PiP mode transitions.\n\n ```kotlin\n \u003cactivity\n android:name=\".SnippetsActivity\"\n android:exported=\"true\"\n android:supportsPictureInPicture=\"true\"\n android:configChanges=\"orientation|screenLayout|screenSize|smallestScreenSize\"\n android:theme=\"@style/Theme.Snippets\"\u003e\n ```\n | **Note:** To learn more about configuration changes, how to restrict activity recreation, and how to react to those configuration changes, see the [Handle\n | configuration changes](/guide/topics/resources/runtime-changes) page.\n\nIn your Compose code, do the following:\n\n1. Add this extension on `Context`. You'll use this extension multiple times throughout the guide to access the activity. \n\n ```kotlin\n internal fun Context.findActivity(): ComponentActivity {\n var context = this\n while (context is ContextWrapper) {\n if (context is ComponentActivity) return context\n context = context.baseContext\n }\n throw IllegalStateException(\"Picture in picture should be called in the context of an Activity\")\n }https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L90-L97\n ```\n\nAdd PiP on leave app for pre-Android 12\n\nTo add PiP for pre-Android 12, use [`addOnUserLeaveHintProvider`](/reference/androidx/core/app/OnUserLeaveHintProvider). Follow\nthese steps to add PiP for pre-Android 12:\n\n1. Add a version gate so that this code is only accessed in versions O until R.\n2. Use a `DisposableEffect` with `Context` as the key.\n3. Inside the `DisposableEffect`, define the behavior for when the `onUserLeaveHintProvider` is triggered using a lambda. In the lambda, call [`enterPictureInPictureMode()`](/reference/android/app/Activity#enterPictureInPictureMode(android.app.PictureInPictureParams)) on `findActivity()` and pass in [`PictureInPictureParams.Builder().build()`](/reference/android/app/PictureInPictureParams.Builder).\n4. Add `addOnUserLeaveHintListener` using `findActivity()` and pass in the lambda.\n5. In `onDispose`, add `removeOnUserLeaveHintListener` using `findActivity()` and pass in the lambda.\n\n\n```kotlin\nif (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.O &&\n Build.VERSION.SDK_INT \u003c Build.VERSION_CODES.S\n) {\n val context = LocalContext.current\n DisposableEffect(context) {\n val onUserLeaveBehavior: () -\u003e Unit = {\n context.findActivity()\n .enterPictureInPictureMode(PictureInPictureParams.Builder().build())\n }\n context.findActivity().addOnUserLeaveHintListener(\n onUserLeaveBehavior\n )\n onDispose {\n context.findActivity().removeOnUserLeaveHintListener(\n onUserLeaveBehavior\n )\n }\n }\n} else {\n Log.i(\"PiP info\", \"API does not support PiP\")\n}https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L354-L374\n```\n\n\u003cbr /\u003e\n\nAdd PiP on leave app for post-Android 12\n\nPost-Android 12, the [`PictureInPictureParams.Builder`](/reference/android/app/PictureInPictureParams.Builder) is added through a\nmodifier that is passed to the app's video player.\n\n1. Create a `modifier` and call [`onGloballyPositioned`](/reference/kotlin/androidx/compose/ui/layout/OnGloballyPositionedModifier) on it. The layout coordinates will be used in a later step.\n2. Create a variable for the `PictureInPictureParams.Builder()`.\n3. Add an `if` statement to check if the SDK is S or above. If so, add [`setAutoEnterEnabled`](/reference/android/app/PictureInPictureParams.Builder#setAutoEnterEnabled(boolean)) to the builder and set it to `true` to enter PiP mode upon swipe. This provides a smoother animation than going through [`enterPictureInPictureMode`](/reference/android/app/Activity#enterPictureInPictureMode(android.app.PictureInPictureParams))().\n4. Use `findActivity()` to call `setPictureInPictureParams()`. Call `build()` on the `builder` and pass it in.\n\n\n```kotlin\nval pipModifier = modifier.onGloballyPositioned { layoutCoordinates -\u003e\n val builder = PictureInPictureParams.Builder()\n\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.S) {\n builder.setAutoEnterEnabled(true)\n }\n context.findActivity().setPictureInPictureParams(builder.build())\n}\nVideoPlayer(pipModifier)https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L74-L82\n```\n\n\u003cbr /\u003e\n\nUse `setAspectRatio` to set PiP window's aspect ratio\n\nTo set the aspect ratio of the PiP window, you can either choose a specific\naspect ratio or use the width and height of the player's video size. If you are\nusing a media3 player, check that the player is not null and that the player's\nvideo size is not equal to \\[`VideoSize.UNKNOWN`\\]\\[6\\] before setting the aspect\nratio.\n\n\n```kotlin\nval context = LocalContext.current\n\nval pipModifier = modifier.onGloballyPositioned { layoutCoordinates -\u003e\n val builder = PictureInPictureParams.Builder()\n if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) {\n val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()\n builder.setSourceRectHint(sourceRect)\n builder.setAspectRatio(\n Rational(player.videoSize.width, player.videoSize.height)\n )\n }\n\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.S) {\n builder.setAutoEnterEnabled(shouldEnterPipMode)\n }\n context.findActivity().setPictureInPictureParams(builder.build())\n}\n\nVideoPlayer(pipModifier)https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/pictureinpicture/PictureInPictureSnippets.kt#L248-L266\n```\n\n\u003cbr /\u003e\n\n| **Warning:** The bounds of what the aspect ratio can be are between 2.39:1 and 1:2.39 (inclusive). If your aspect ratio does not fall between these values, your app will crash.\n\nIf you are using a custom player, set the aspect ratio on the player's height\nand width using the syntax specific to your player. Be aware that if your player\nresizes during initialization, if it falls outside of the valid bounds of what\nthe aspect ratio can be, your app will crash. You may need to add checks around\nwhen the aspect ratio can be calculated, similar to how it is done for a media3\nplayer."]]