自 2025 年 3 月 27 日起,我們建議您使用 android-latest-release
而非 aosp-main
建構及貢獻 AOSP。詳情請參閱「Android 開放原始碼計畫變更」。
子母畫面
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
Android 手持裝置的子母畫面 (PIP) 功能可讓使用者將正在執行活動的應用程式調整為小型視窗。子母畫面模式對影片應用程式特別實用,因為使用者可在內容持續播放的同時執行其他動作。使用者可以透過 SystemUI 操控這個視窗的位置,並透過應用程式提供的動作 (最多三個) 與目前處於子母畫面模式的應用程式互動。
PIP 功能需要支援的應用程式明確選擇加入,且以個別活動為單位運作。(單一應用程式可以有多個活動,但只有一個活動會在 PIP 中顯示)。活動會透過呼叫 enterPictureInPictureMode()
要求進入子母畫面模式,並以 onPictureInPictureModeChanged()
的形式接收活動回呼。
setPictureInPictureParams()
方法可讓活動在子母畫面和自訂動作中控制顯示比例,讓使用者不必展開活動,即可與活動互動。在子母畫面模式中,活動處於暫停但會算繪的狀態,且不會直接接收觸控輸入或視窗焦點。一次只能在 PIP 中顯示一個工作。
詳情請參閱 Android 開發人員的「子母畫面」說明文件。
裝置需求
如要支援 PIP,請在 /android/frameworks/base/core/java/android/content/pm/PackageManager.java
中啟用 PackageManager#FEATURE_PICTURE_IN_PICTURE
系統功能。支援 PIP 的裝置螢幕最小寬度必須大於 220 dp。與分割畫面多視窗類似,PIP 可讓多項活動同時在畫面上執行。因此,裝置應具備足夠的 CPU 和 RAM,才能支援此用途。
實作
大部分的活動生命週期管理作業都是在 ActivityManager
和 WindowManager
之間的系統中完成。參考 UI 實作項目位於 SystemUI
套件中。
系統的修改內容不應影響其內在行為,這項行為是由 Compatibility Test Suite (CTS) 測試定義。PIP 的系統邏輯主要圍繞「已固定」堆疊中的任務和活動管理。以下簡要介紹課程:
ActivityRecord
:追蹤每個活動的子母畫面狀態。如要防止使用者在特定情況下 (例如從螢幕鎖定畫面或在 VR 期間) 進入 PIP 模式,請在 checkEnterPictureInPictureState()
中新增情況。
ActivityManagerService
:活動的主要介面,用於要求進入子母畫面模式,以及用於呼叫 WindowManager
和 SystemUI
以變更子母畫面活動狀態的介面。
ActivityStackSupervisor
:從 ActivityManagerService
呼叫,用於將工作移入或移出已固定的堆疊,並視需要更新 WindowManager
。
PinnedStackWindowController
:來自 ActivityManager
的 WindowManager
介面。
PinnedStackController
:將系統中的變更項目回報給 SystemUI
,例如顯示/隱藏 IME、顯示比例變更或動作變更。
BoundsAnimationController
:以不會在調整大小時觸發設定變更的方式,為 PIP 活動視窗製作動畫。
PipSnapAlgorithm
:在系統和 SystemUI 中都使用的共用類別,用於控制 PIP 視窗靠近螢幕邊緣時的固定行為。
參考資料 SystemUI
提供完整的 PIP 實作,可向使用者呈現自訂動作和一般操作,例如展開和關閉。只要這些變更不會影響 CDD 定義的內在行為,裝置製造商就可以根據這些變更進行建構。以下簡要介紹課程:
PipManager
:開頭為 SystemUI
的 SystemUI
元件。
PipTouchHandler
:觸控處理常式,可控制操控 PIP 的手勢。這個方法只會在 PIP 的輸入消費者處於活動狀態時使用 (請參閱 InputConsumerController
)。您可以在此新增手勢。
PipMotionHelper
:方便使用的類別,可追蹤 PIP 位置和螢幕上的可用區域。透過呼叫 ActivityManagerService
更新或為 PIP 設定動畫的顯示位置和大小。
PipMenuActivityController
:啟動活動,顯示目前在 PIP 中活動提供的動作。這個活動是工作重疊活動,會移除重疊的輸入用戶端,以便進行互動。
PipMenuActivity
:實作選單活動。
PipMediaController
:當媒體工作階段的變更可能影響 PIP 的預設動作時,會更新 SystemUI
的監聽器。
PipNotificationController
:可確保使用者使用 PIP 功能時,通知處於啟用狀態的控制器。
PipDismissViewController
:當使用者開始與 PIP 互動時,系統會向使用者顯示疊加層,表示可以關閉 PIP。
預設刊登位置
有多種系統資源可控制 PIP 的預設位置:
config_defaultPictureInPictureGravity
:gravity 整數,用於控制放置 PIP 的角落,例如 BOTTOM|RIGHT
。
config_defaultPictureInPictureScreenEdgeInsets
:從螢幕兩側放置 PIP 的偏移量。
config_pictureInPictureDefaultSizePercent
和 config_pictureInPictureDefaultAspectRatio
:螢幕寬度的百分比和顯示比例組合會控制 PIP 的大小。計算的預設 PIP 大小不得小於 CTS 和 CDD 定義的 @dimen/default_minimal_size_pip_resizable_task
。
config_pictureInPictureSnapMode
:在 PipSnapAlgorithm
中定義的對齊行為。
裝置實作方式不應變更 CDD 和 CTS 中定義的最小和最大顯示比例。
權限
AppOpsManager
(main/core/java/android/app/AppOpsManager.java
) 中的個別套件「應用程式作業」(OP_PICTURE_IN_PICTURE
) 可讓使用者透過系統設定,在個別應用程式層級控制 PIP。當活動要求進入子母畫面模式時,裝置實作項目必須遵守這項檢查。
測試
如要測試 PIP 實作,請在 /cts/hostsidetests/services/activitymanager
下執行主機端 CTS 測試中的所有畫中畫相關測試,特別是 ActivityManagerPinnedStackTests.java
。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","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-07-27 (世界標準時間)。"],[],[],null,["# Picture-in-picture\n\nThe picture-in-picture (PIP) feature for Android handheld devices lets users resize an app with an\nongoing activity into a small window. PIP is especially useful for video apps because content\ncontinues to play while the user is free to perform other actions. Users can manipulate this\nwindow's position through the SystemUI and interact with the application currently\nin picture-in-picture with (up to three) app-provided actions.\n\n\nPIP requires explicit opt-in from applications that support it and works on a\nper-activity basis. (A single application can have multiple activities, only one\nof which is in PIP.) Activities request to enter picture-in-picture by calling\n`enterPictureInPictureMode()`, and receive activity callbacks in the\nform of `onPictureInPictureModeChanged()`.\n\n\nThe `setPictureInPictureParams()` method lets activities control their\naspect ratio while in PIP and custom actions, which allow users to interact with\nthe activity without having to expand it. In PIP, the activity is in a paused,\nbut rendering, state and doesn't directly receive touch input or window focus.\nOnly a single task can be in PIP at a time.\n\n\nMore information is available in the Android Developer\n[Picture-in-picture](https://developer.android.com/training/tv/playback/picture-in-picture.html)\ndocumentation.\n\nDevice requirements\n-------------------\n\n\nTo support PIP, enable the\n`PackageManager#FEATURE_PICTURE_IN_PICTURE` system feature in\n[/android/frameworks/base/core/java/android/content/pm/PackageManager.java](https://android.googlesource.com/platform/frameworks/base/+/android16-release/core/java/android/content/pm/PackageManager.java).\nDevices that support PIP must have a screen that is larger than 220dp at its\nsmallest width. Similar to split screen multi-window, PIP allows multiple\nactivities to run on-screen at the same time. Therefore, devices should have\nsufficient CPU and RAM to support this use case.\n\nImplementation\n--------------\n\n\nMost of the activity lifecycle management is done in system between\n[ActivityManager](https://android.googlesource.com/platform/frameworks/base/+/android16-release/services/core/java/com/android/server/am/) and [WindowManager](https://android.googlesource.com/platform/frameworks/base/+/android16-release/services/core/java/com/android/server/wm/).\nThe reference UI implementation is in the [SystemUI](https://android.googlesource.com/platform/frameworks/base/+/android16-release/packages/SystemUI/)\npackage.\n\n\nModifications to the system should not affect its intrinsic behavior as defined\nby the [Compatibility Test Suite (CTS) tests](#cts-tests).\nThe system logic for PIP mainly revolves around the management of tasks and\nactivities within the \"pinned\" stack. Here is a quick class overview:\n\n- **`ActivityRecord`:** tracks each activity's picture-in-picture state. To prevent users from entering PIP in certain circumstances, such as from the lock screen or during VR, add cases to `checkEnterPictureInPictureState()`.\n- **`ActivityManagerService`:** the primary interface from the activity to request entering PIP and the interface to calls from `WindowManager` and `SystemUI` to change the PIP activity state.\n- **`ActivityStackSupervisor`:** called from the `ActivityManagerService` to move tasks in or out of the pinned stack, updating the `WindowManager` as necessary.\n- **`PinnedStackWindowController`:** the `WindowManager` interface from `ActivityManager`.\n- **`PinnedStackController`:** reports changes in the system to `SystemUI`, such as IME shown/hidden, aspect ratio changed, or actions changed.\n- **`BoundsAnimationController`:** animates the PIP activity windows in a way that does not trigger a configuration change while resizing.\n- **`PipSnapAlgorithm`:** a shared class used in both the system and SystemUI that controls the snapping behaviour of the PIP window near the edges of the screen.\n\n\nThe reference [SystemUI](https://android.googlesource.com/platform/frameworks/base/+/android16-release/packages/SystemUI/)\nprovides a complete implementation of PIP that supports presenting custom\nactions to users and general manipulation, such as expansion and dismissal.\nDevice manufacturers can build upon these changes, as long as they do not affect\nthe intrinsic behaviours as defined by the CDD. Here is a quick class\noverview:\n\n- **`PipManager`:** the `SystemUI` component that is started with `SystemUI`.\n- **`PipTouchHandler`:** the touch handler, which controls the gestures that manipulate the PIP. This is only used while the input consumer for the PIP is active (see `InputConsumerController`). New gestures can be added here.\n- **`PipMotionHelper`:** a convenience class that tracks the PIP position, and allowable region on-screen. Calls through to `ActivityManagerService` to update or animate the position and size of the PIP.\n- **`PipMenuActivityController`:** starts an activity that shows the actions provided by the activity currently in PIP. This activity is a task-overlay activity, and removes the overlaying input consumer to allow it to be interactive.\n- **`PipMenuActivity`:** the implementation for the menu activity.\n- **`PipMediaController`:** the listener that updates `SystemUI` when the media session changes in a way that might affect the default actions on the PIP.\n- **`PipNotificationController`:** the controller that ensures that a notification is active while a user is using the PIP feature.\n- **`PipDismissViewController`:** the overlay shown to users when they start interacting with the PIP to indicate that it can be dismissed.\n\nDefault placement\n-----------------\n\n\nThere are various system resources that control the default placement of the\nPIP:\n\n- **`config_defaultPictureInPictureGravity`:** the [gravity](https://developer.android.com/reference/android/view/Gravity.html) integer, which controls the corner to place the PIP, such as `BOTTOM|RIGHT`.\n- **`config_defaultPictureInPictureScreenEdgeInsets`:** the offsets from the sides of the screen to place the PIP.\n- **`config_pictureInPictureDefaultSizePercent` and\n `config_pictureInPictureDefaultAspectRatio`:** the combination of percentage of the screen width and the aspect ratio controls the size of the PIP. The computed default PIP size should not be smaller than `@dimen/default_minimal_size_pip_resizable_task`, as defined by CTS and the CDD.\n- **`config_pictureInPictureSnapMode`:** the snapping behaviour as defined in `PipSnapAlgorithm`.\n\n\nDevice implementations should not change the minimum and maximum aspect ratios\nthat are defined in the CDD and CTS.\n\nPermissions\n-----------\n\n\nThe per-package \"application operation\"\n(`OP_PICTURE_IN_PICTURE`) in `AppOpsManager`\n(`main/core/java/android/app/AppOpsManager.java`), lets\nusers to control PIP on a per-application level through the system settings.\nDevice implementations need to respect this check when an activity requests to\nenter picture-in-picture mode.\n\nTesting\n-------\n\n\nTo test PIP implementations, run all picture-in-picture related tests found in\nthe host-side CTS tests under [/cts/hostsidetests/services/activitymanager](https://android.googlesource.com/platform/cts/+/android16-release/hostsidetests/services/activitymanager/src/android/server/cts),\nparticularly in `ActivityManagerPinnedStackTests.java`."]]