Android 14(API 级别 34)对画中画(PiP) API 进行了一些增强,以允许多任务处理。虽然 PiP 支持在 Android 8.0(API 级别 26)中引入,但在 Android TV 上并未得到广泛支持,并且在 Android 13 之前,在 Google TV 上根本不支持。TV 的多任务处理使用 PiP 模式允许两个单独的应用同时存在于屏幕上:一个以全屏模式运行,另一个以 PiP 模式运行。在这两种模式下运行的应用有不同的要求。
默认行为是 PiP 应用覆盖全屏应用。这与标准的Android 画中画行为非常相似。
请注意,在集成多任务处理时,您的应用程序必须根据TV 应用质量指南声明其使用类型。
在 PiP 模式下运行您的应用
对于运行 Android 14(API 级别 34)或更高版本的电视设备,请通过调用 enterPictureInPictureMode()
在画中画 (PiP) 模式下运行您的应用。运行早期 Android 版本的电视设备不支持 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 模式下运行的应用。
保持清晰的 API
在某些情况下,PiP 应用可能会覆盖全屏应用中的重要 UI 组件。为了减轻这种情况,有一些保持清晰的 API,应用可以使用这些 API 来识别不应被覆盖的关键 UI 组件。系统尝试遵守这些请求,通过重新定位 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
的 UI(例如 Flutter、Jetpack Compose 和 WebView)可能需要保持某些区域清晰。此 API 可用于这些情况。
使用类型
您的应用必须声明 com.google.android.tv.pip.category
的 元数据值属性,该属性与画中画模式的主要使用类型或类型相对应。任何已设置 android:supportsPictureInPicture="true"
的 <activity>
都应使用下表中的相关值声明此属性。
不属于任何这些类别的使用类型,特别是任何媒体内容的播放,在电视上的画中画模式中不允许。
值 | 描述 |
---|---|
"communication " |
通信用例,例如视频或语音通话。 |
"smartHome " |
智能家居集成,例如联网门铃或婴儿监护器。 |
"health " |
健康用例,例如健身追踪或健康监测。 |
"ticker " |
信息滚动显示用例,例如实时体育比分或新闻和股票信息滚动显示。 |
多个值由竖线 (|
) 分隔。例如
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />