Android 14(API 级别 34)对 画中画 (PiP) API 进行了一些增强,以支持多任务处理。虽然 Android 8.0(API 级别 26)中引入了 PiP 支持,但 Android TV 并不广泛 支持该功能,并且在 Android 13 之前,Google TV 完全不支持该功能。TV 多任务处理使用画中画模式,允许两个单独的应用在屏幕上共存:一个以全屏模式运行,另一个以画中画模式运行。以这两种模式运行的应用有不同的要求。
默认行为是 PiP 应用叠加在全屏应用之上。这与标准 Android 画中画行为非常相似。
请注意,在集成多任务处理时,您的应用必须声明其 使用类型,并 按照 TV 应用质量指南进行。
以 PiP 模式运行应用
对于搭载 Android 14(API 级别 34)或更高版本的 TV 设备,请通过调用 enterPictureInPictureMode() 以 PiP
模式运行应用。搭载较低版本 Android 的 TV 设备不支持 PiP 模式。
以下示例展示了如何实现按钮的逻辑以进入 PiP 模式:
Kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) pictureInPictureButton.visibility = if (requireActivity().packageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { pictureInPictureButton.setOnClickListener { val aspectRatio = Rational(view.width, view.height) val params = PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .build() val result = requireActivity().enterPictureInPictureMode(params) } View.VISIBLE } else { View.GONE } }
Java
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (requireActivity().getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { pictureInPictureButton.setVisibility(View.VISIBLE); pictureInPictureButton.setOnClickListener(v -> { Rational aspectRatio = new Rational(view.getWidth(), view.getHeight()); PictureInPictureParams params = new PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .setTitle("My Streaming App") .setSubtitle("My On-Demand Content") .build(); Boolean result = requireActivity().enterPictureInPictureMode(params); }); } else { pictureInPictureButton.setVisibility(View.GONE); } }
仅当设备具有系统功能
FEATURE_PICTURE_IN_PICTURE时,才会添加该操作。此外,当触发该操作时,PiP 模式的宽高比会设置为与正在播放的视频的宽高比相匹配。
请务必添加标题和副标题,以便向用户提供有关此 PiP 的一般用途的信息 。
与以 PiP 模式运行的应用共存
当您的应用作为全屏应用运行时,可能需要针对以 PiP 模式运行的其他应用进行调整。
Keep-clear API
在某些情况下,PiP 应用可能会叠加在全屏应用中的重要界面组件之上。为了缓解这种情况,应用可以使用 keep-clear API 来识别不应叠加的关键界面组件。系统会尝试遵循这些请求,通过重新定位 PiP 窗口来避免覆盖这些组件。

如需指定不应叠加某个视图,请在
XML 布局中使用 preferKeepClear,如以下示例所示:
<TextView
android:id="@+id/important_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:preferKeepClear="true"
android:text="@string/app_name"/>
您还可以使用 setPreferKeepClear() 以编程方式执行此操作:
Kotlin
private lateinit var binding: MyLayoutBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) binding.importantText.isPreferKeepClear = true }
Java
private MyLayoutBinding binding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); binding.importantText.setPreferKeepClear(true); }
有时,您可能不需要保持整个 View 清晰,而只需要保持其中的一部分清晰。setPreferKeepClearRects() 可用于
指定不应叠加的 View 区域。不原生使用 View 的界面(例如 Flutter、Jetpack Compose 和 WebView)可能具有需要保持区域清晰的子部分。此 API 可用于这些情况。
使用类型
您的应用必须声明 元数据值属性,该属性与画中画模式的主要使用类型相对应。com.google.android.tv.pip.category任何 <activity> 已设置
android:supportsPictureInPicture="true" 都应使用
下表中的相关值声明此属性。
不属于这些类别的使用类型(尤其是任何媒体内容播放)在 TV 上的画中画模式下是不允许的。
| 值 | 说明 |
|---|---|
“communication” |
通信用例,例如视频或语音通话。 |
“smartHome” |
智能家居集成,例如联网门铃或婴儿监视器。 |
“health” |
健康用例,例如健身跟踪或健康监控。 |
“ticker” |
跑马灯用例,例如实时体育赛事比分或新闻和股票跑马灯。 |
多个值之间用竖线 (|) 分隔。例如:
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />