用于 HDMI 模式切换的 API


用于 HDMI 模式切换的 API

即使连接到 4K 超高清电视,Amazon Fire TV(第 2 代)也在 1080p (60 FPS) 模式下工作。要播放 4K 超高清内容,您必须将电视切换到 4K 超高清显示模式。HDMI 显示模式之间的这种切换(在需要播放 4K 超高清内容时由应用触发)称为 HDMI 模式切换

用于 HDMI 模式切换的 API

谷歌在 Android Marshmallow 中推出 4K Display.Mode API。Display.mode 允许应用查询物理显示尺寸并切换到不同的 HDMI 显示模式。对于基于 Android Nougat 构建的 Fire OS 6,这些 Display.Mode API 可随时使用。

对于运行 Fire OS 5 的 Fire TV 设备(基于 Lollipop,在 Display.Mode 发布之前),亚马逊实现了 Display.Mode API。因此,即使在 Fire OS 5 上,您的应用也可以使用这些 Display.Mode API 进行 HDMI 模式切换

由于这些 API 不是安卓 API 级别 21 (Lollipop) 的一部分,因此应用必须使用 “反射”来访问 API。或者,应用开发者可以使用由亚马逊开发的 4K 扩展库,该库通过反射封装这些安卓 API,并为它们提供了一个简单的界面。

您还可以显示由亚马逊开发的可选间隙,为客户准备 HDMI 模式切换。这种间隙作为亚马逊 4K 扩展库的一部分分发。

Fire OS 还将提供 sys.display-size 系统属性,以报告所连接显示器支持的最大分辨率。

使用 HDMI 模式切换的步骤

使用安卓 API 启动 HDMI 模式切换时,请按照以下常规步骤操作:

  1. 使用 Display.getSupportedModes() 查询支持的显示模式。

    Display.getSupportedModes() 返回 Display.Mode 对象的数组。此同步 API 返回 Amazon Fire TV(第 2 代)和连接的显示器支持的模式(分辨率和帧速率)。如果连接的显示器支持 4K 超高清,则列表中将包含 4K 超高清模式。

    由于帧速率转换可能无法提供最佳结果,因此亚马逊建议切换到要播放的内容的实际或最接近的帧速率(4K 24fps、4K 25fps 或 4K 30fps)。

  2. 使用 Display.getMode() 检索当前显示分辨率和帧速率。

    Display.getMode()Display.Mode 对象中返回当前显示分辨率和刷新率。

  3. 使用 WindowManager.LayoutParams.preferredDisplayModeId 属性设置显示模式。

    应用使用 WindowManager.LayoutParams.preferredDisplayModeId 属性来启动模式切换。这允许应用以全高清 (1080p) 模式启动,然后在用户开始播放 4K 超高清内容时启动模式切换以切换到 4K 超高清。请注意以下事项:

    • 如果两个活动都喜欢同一模式,则在活动过渡期间不会启动模式切换。
    • 系统和语音叠加层将不会启动模式切换。
    • 当应用或活动终止时,显示屏将切换回全高清 (1080p) 分辨率。
    • Display.Mode 类定义与 Android Marshmallow 保持一致。
  4. 模式切换协商完成时获取通知。

    通过 onDisplayChanged(int displayId) 方法,您可以在模式切换协商完成时收到通知。

    当逻辑显示属性发生更改时,DisplayManager.DisplayListener 会发送回调。模式更改完成后,将会收到此回调。请注意,在收到回调之后的几秒钟内,显示的内容可能不可见。

开发者界面

应用可以直接通过反射使用这些 API,也可以使用亚马逊提供的包装器(4K 扩展库)来访问这些 API。下面的代码示例显示了不使用扩展直接进行模式更改的情况:

WindowManager.LayoutParams mWindowAttributes = mTargetWindow.getAttributes();
try {
 if (attributeFlagField == null) {
  Class < ? > cLayoutParams = mWindowAttributes.getClass();
  attributeFlagField = cLayoutParams.getDeclaredField(sPreferredDisplayModeIdFieldName);
 }
 //尝试模式切换
 attributeFlagField.setInt(mWindowAttributes, modeId);
 mTargetWindow.setAttributes(mWindowAttributes);
} catch (Exception e) {
 Log.e(TAG, e.getLocalizedMessage());
}

下一节将介绍使用 4K 扩展库的方法。

亚马逊 4K 扩展库

Amazon Fire TV(第 2 代)中的 HDMI 模式切换 API 在 Android Lollipop SDK 中不可用。要使用它们,您必须使用反射。亚马逊构建了 4K 扩展库(以源代码形式提供),以演示如何使用安卓 API 并提供帮助程序类。 

扩展 ZIP 文件在 Test 文件夹中包含一个名为“DisplayModeCheckSample”的示例应用。 还有一个 Javadoc 文件,您可以通过展开 doc > javadoc 文件夹并打开 index.html 文件来查看它。

要构建应用,请在 Android Studio 中转到文件 > 打开,并选择 DisplayModeCheckSample 项目。然后单击运行“应用”按钮 。当您构建应用时,您会看到这样的屏幕:

当您切换模式时,会出现间隙(在超高清电视上),并且应用会切换到 4K 超高清模式。

亚马逊的 4K 扩展库包含以下部分中列出的类。此外,它还包括用于显示“亚马逊间隙”的 API,为客户准备在亚马逊 4K 设备上进行 HDMI 模式切换。以下部分介绍了这些类。

UHDHelper 类

UHDHelper 是一个封装 4K 超高清功能和模式切换 API 的便利类。它提供了以下公共方法:

setPreferredDisplayModeId()

setPreferredDisplayModeId(Window targetWindow, int modeId, boolean allowOverlayDisplay)

此方法允许您请求特定的显示模式(分辨率和刷新率)。如果显示屏当前未设置为请求的模式,则此方法在支持的设备上启动模式切换。UhdHelperListener 用于通知应用模式切换 HDMI 协商已完成。

参数 描述
targetWindow 用于设置显示和调用参数的窗口。
modeId 要切换到的所需模式。必须是平台支持的有效模式。
allowOverlayDisplay 标记请求以允许在适用设备上显示叠加层。

请注意,模式切换请求可能不会成功,您必须从 UHDHelperListener#onModeChanged(Display.Mode mode) 验证模式或调用 getMode()。您必须等待模式切换完成后才能开始播放内容。此外,此模式切换仅适用于 Amazon Fire TV(第 2 代)。

getSupportedModes()

getSupportedModes()

确定连接的设备上所有支持的模式。

返回内容
Mode 对象的数组,如果发生错误,则为 NULL。

getMode()

getMode()

返回显示屏设置为的当前模式。此方法还用于确定模式切换是否成功。当模式切换正在进行时,getMode() 的结果为未定义。

返回内容
当前在系统上设置的模式,如果发生错误,则为 NULL。

UhdHelperListener 类

UhdHelperListener 类提供 onModeChanged(Display.Mode mode) 方法。此方法用于在模式切换 HDMI 协商完成时通知应用。如果模式更改成功,它还提供当前模式(可能是请求的模式)。

参数 描述
mode 包含切换到的模式的 Mode 对象;如果更改模式时出现超时或内部错误,则为 NULL。

Display.Mode 类

Display.Mode 类镜像到 Android Marshmallow 中的 Display.Mode 类。这用于描述显示模式的分辨率和刷新率。

模式切换期间的间隙

由于客户体验在 HDMI 模式切换期间中断,因此亚马逊构建了一个间隙,可以选择显示该间隙,以便在 HDMI 模式切换之前让客户做好准备。用于触发此间隙的代码可通过亚马逊 4K 扩展库获得。

要通过扩展代码显示间隙,请调用以下命令:

setPreferredDisplayModeId(Window_targetWindow, int_modeId boolean_allowOverlayDisplay)

并将 allowOverlayDisplay 设置为 true。叠加层将在模式切换开始之前显示两秒钟。