Android 14(API 수준 34)에서는 멀티태스킹을 지원하기 위해 PIP 모드 API를 개선합니다. PIP 지원은 Android 8.0 (API 수준 26)에서 도입되었지만 Android TV에서는 널리 지원되지 않았으며 Android 13 이전의 Google TV에서는 전혀 지원되지 않았습니다. TV용 멀티태스킹은 PIP 모드를 사용하여 두 개의 별도 앱이 화면에 공존하도록 합니다. 하나는 전체 화면으로 실행되고 다른 하나는 PIP 모드로 실행됩니다. 이러한 모드에서 실행되는 앱에는 서로 다른 요구사항이 있습니다.
기본 동작은 PIP 앱이 전체 화면 앱을 오버레이하는 것입니다. 이는 표준 Android PIP 모드 동작과 매우 유사합니다.
이 작업은 기기에 시스템 기능 FEATURE_PICTURE_IN_PICTURE이 있는 경우에만 추가됩니다. 또한 작업이 트리거되면 재생 중인 동영상의 가로세로 비율과 일치하도록 PIP 모드의 가로세로 비율이 설정됩니다.
이 PIP가 일반적으로 사용되는 용도에 관한 정보를 사용자에게 제공하려면 제목과 부제목을 추가해야 합니다.
PIP 모드로 실행되는 앱과 공존
앱이 전체 화면 앱으로 실행되는 경우 PIP 모드로 실행되는 다른 앱에 맞게 조정해야 할 수 있습니다.
Keep-clear API
경우에 따라 PiP 앱이 전체 화면 앱 내에서 중요한 UI 구성요소를 오버레이할 수 있습니다. 이를 완화하기 위해 앱이 오버레이해서는 안 되는 중요한 UI 구성요소를 식별하는 데 사용할 수 있는 keep-clear API가 있습니다. 시스템은 PiP 창의 위치를 변경하여 이러한 구성요소를 가리지 않도록 요청을 처리하려고 시도합니다.
뷰를 오버레이하지 않도록 지정하려면 다음 예와 같이 XML 레이아웃에서 preferKeepClear를 사용하세요.
전체 View를 지울 필요는 없고 일부만 지워도 되는 경우가 있습니다. setPreferKeepClearRects()를 사용하여 오버레이해서는 안 되는 View 영역을 지정할 수 있습니다. Flutter, Jetpack Compose, WebView와 같이 View를 네이티브로 사용하지 않는 UI에는 영역을 명확하게 유지해야 하는 하위 섹션이 있을 수 있습니다. 이 API는 이러한 경우에 사용할 수 있습니다.
사용량 유형
앱은 PIP 모드의 기본 유형 또는 사용 유형에 해당하는 com.google.android.tv.pip.category의 메타데이터 값 속성을 선언해야 합니다. android:supportsPictureInPicture="true"을 설정한 <activity>는 아래 표의 관련 값으로 이 속성을 선언해야 합니다.
이러한 카테고리에 속하지 않는 사용 유형, 특히 미디어 콘텐츠 재생은 TV의 PIP 모드에서 허용되지 않습니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 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,["Android 14 (API level 34) introduces some enhancements to the\n[picture-in-picture](/guide/topics/ui/picture-in-picture) (PiP) APIs to allow for multitasking. While PiP\nsupport was introduced in Android 8.0 (API level 26), it was not widely\nsupported on Android TV, and not supported at all on Google TV prior to Android\n13. Multitasking for TV uses PiP mode to allow two\nseparate apps to coexist on the screen: one running in full\nscreen, with a second running in PiP mode. There are\ndifferent requirements for apps running in either of these modes.\n\nThe default behavior is that the PiP app overlays the full-screen app. This is\nmuch the same as standard [Android picture-in-picture](/guide/topics/ui/picture-in-picture) behavior.\n\nNote that when integrating multitasking, your application must declare its\n[usage types](#usage-types) in\n[accordance with the TV app quality guidelines](/docs/quality-guidelines/tv-app-quality#TV-IC).\n\nRun your app in PiP mode\n\nFor TV devices running Android 14 (API level 34) or higher, run your app in PiP\nmode by calling [`enterPictureInPictureMode()`](/reference/android/app/Activity#enterPictureInPictureMode(android.app.PictureInPictureParams)). TV devices running earlier\nversions of Android don't support PiP mode.\n| **Note:** There is a deprecated `enterPictureInPictureMode()` method for API level 26 and earlier that does not use `PictureInPictureParams.Builder`. Avoid using it, because it's not supported on TV devices.\n\nHere is an example of how to implement the logic of a button to enter\nPiP mode: \n\nKotlin \n\n```kotlin\noverride fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n super.onViewCreated(view, savedInstanceState)\n pictureInPictureButton.visibility =\n if (requireActivity().packageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {\n pictureInPictureButton.setOnClickListener {\n val aspectRatio = Rational(view.width, view.height)\n val params = PictureInPictureParams.Builder()\n .setAspectRatio(aspectRatio)\n .build()\n val result = requireActivity().enterPictureInPictureMode(params)\n }\n View.VISIBLE\n } else {\n View.GONE\n }\n}\n```\n\nJava \n\n```java\n@Override\npublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {\n super.onViewCreated(view, savedInstanceState);\n if (requireActivity().getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {\n pictureInPictureButton.setVisibility(View.VISIBLE);\n pictureInPictureButton.setOnClickListener(v -\u003e {\n Rational aspectRatio = new Rational(view.getWidth(), view.getHeight());\n PictureInPictureParams params = new PictureInPictureParams.Builder()\n .setAspectRatio(aspectRatio)\n .setTitle(\"My Streaming App\")\n .setSubtitle(\"My On-Demand Content\")\n .build();\n Boolean result = requireActivity().enterPictureInPictureMode(params);\n });\n } else {\n pictureInPictureButton.setVisibility(View.GONE);\n }\n}\n```\n\nThe action is only added if the device has the system feature\n[`FEATURE_PICTURE_IN_PICTURE`](/reference/kotlin/android/content/pm/PackageManager#feature_picture_in_picture). Also, when the action is triggered, the\naspect ratio of PiP mode is set to match the aspect ratio of the video being\nplayed.\n\nBe sure to add a [title](/reference/android/app/PictureInPictureParams.Builder#setTitle(java.lang.CharSequence)) and [subtitle](/reference/android/app/PictureInPictureParams.Builder#setSubtitle(java.lang.CharSequence)) to give the user information\nabout what this PIP is generally being used for.\n| **Note:** Entering picture-in picture mode requires explicit and intentional action by the user within the app. For details, see the [TV app quality guidelines](/docs/quality-guidelines/tv-app-quality#pip).\n\nCoexist with apps running in PiP mode\n\nWhen your app is running as a fullscreen app it may need to adapt for other\napps running in PiP mode.\n\nKeep-clear APIs\n\nIn some cases, the PiP app may overlay important UI components within the\nfullscreen app. To mitigate this, there are keep-clear APIs that apps can\nuse to identify critical UI components that shouldn't be overlaid. The system\nattempts to honor the requests to avoid covering these components by\nrepositioning the PiP window.\n\n| **Note:** The system might not honor these requests if too many UI components are marked as keep-clear, or if they take up large portions of the screen. Be mindful of this when using these APIs.\n\nTo specify that a view shouldn't be overlaid, use [`preferKeepClear`](/reference/android/R.attr#preferKeepClear) in your\nXML layout as in the following example: \n\n \u003cTextView\n android:id=\"@+id/important_text\"\n android:layout_width=\"wrap_content\"\n android:layout_height=\"wrap_content\"\n android:preferKeepClear=\"true\"\n android:text=\"@string/app_name\"/\u003e\n\nYou can also do this programmatically using [`setPreferKeepClear()`](/reference/android/view/View#setPreferKeepClear(boolean)): \n\nKotlin \n\n```kotlin\nprivate lateinit var binding: MyLayoutBinding\n\noverride fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n\n binding = MyLayoutBinding.inflate(layoutInflater)\n setContentView(binding.root)\n binding.importantText.isPreferKeepClear = true\n}\n```\n\nJava \n\n```java\nprivate MyLayoutBinding binding;\n\n@Override\nprotected void onCreate(@Nullable Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n\n binding = MyLayoutBinding.inflate(getLayoutInflater());\n setContentView(binding.getRoot());\n binding.importantText.setPreferKeepClear(true);\n}\n```\n\nThere may be times when you don't need to keep an entire [`View`](/reference/android/view/View) clear, but\nonly a section of it. The [`setPreferKeepClearRects()`](/reference/android/view/View#setPreferKeepClearRects(java.util.List%3Candroid.graphics.Rect%3E)) can be used to\nspecify regions of the `View` that shouldn't be overlaid. UIs that don't use\n`View`s natively, such as Flutter, Jetpack Compose, and WebView, may have\nsub-sections that need regions kept clear. This API can be used for those cases.\n| **Note:** If you set [`setPreferKeepClear()`](/reference/android/view/View#setPreferKeepClear(boolean)) to `true`, the entire `View` is marked as keep clear, and any regions specified using [`setPreferKeepClearRects()`](/reference/android/view/View#setPreferKeepClearRects(java.util.List%3Candroid.graphics.Rect%3E)) are ignored.\n\nUsage types\n\nYour app must declare a [meta-data value attribute](/guide/topics/manifest/meta-data-element) of\n`com.google.android.tv.pip.category` that corresponds with the primary type or\ntypes of usage for the picture-in-picture mode. Any `\u003cactivity\u003e` that has set\n`android:supportsPictureInPicture=\"true\"` should declare this attribute with a\nrelevant value from the table below.\n\nUsage types that don't fall into any of these categories, in particular any\nplayback of media content, are not allowed in picture-in-picture mode on TV.\n\n| Value | Description |\n|-------------------|-------------------------------------------------------------------------|\n| \"`communication`\" | Communications use cases, such as video or voice calls. |\n| \"`smartHome`\" | Smart home integrations, such as connected doorbells or baby monitors. |\n| \"`health`\" | Health use cases, such as fitness tracking or health monitoring. |\n| \"`ticker`\" | Ticker use cases, such as live sports scores or news and stock tickers. |\n\nMultiple values are separated by a vertical bar (`|`). For example: \n\n```xml\n\u003cmeta-data android:name=\"com.google.android.tv.pip.category\" android:value=\"smartHome|health\" /\u003e\n```\n\n\u003cbr /\u003e"]]