开发者控制台

用于HDMI模式切换的API

用于HDMI模式切换的API

即使连接到4K超高清电视,亚马逊Fire TV(第2代)也能在1080p (60 FPS)模式下工作。要播放4K超高清内容,所连接的电视就必须切换至4K超高清显示模式。HDMI显示模式之间的切换称为HDMI模式切换(准备播放4K超高清内容时,由应用触发切换)。

用于切换HDMI模式的API

谷歌在Android Marshmallow中推出了4K Display.Mode API。通过Display.mode,应用可查询物理显示屏尺寸并切换到不同的HDMI显示模式。Fire OS 6基于Android Nougat构建,可直接使用上述Display.Mode API。

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

这些API不属于Android API Level 21 (Lollipop),因此,应用必须通过“反射”访问API。此外,应用开发者也可通过亚马逊开发的4K扩展库(该库通过反射封装Android API)访问API。扩展库提供了简易接口。

也可显示亚马逊开发的可选间隙,以便客户准备切换HDMI模式。此间隙是亚马逊4K扩展库的组成部分。

Fire OS还提供了sys.display-size系统属性,用于报告支持的连接显示屏最大分辨率。

HDMI模式切换的步骤

通过Android API启动HDMI模式切换时,请按照以下步骤进行:

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

    Display.getSupportedModes()会返回Display.Mode对象的数组。该同步API返回Fire TV设备和所连显示屏支持的模式(分辨率和帧速率)。若所连显示屏支持4K超高清,则列表中将包含4K超高清模式。

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

  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(), e);
}

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

亚马逊4K扩展库

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

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

如需构建应用,转到Android Studio中的文件 > 打开,并选择DisplayModeCheckSample项目。然后单击Run 'app'(运行“应用”)按钮。在构建应用时,可看到的屏幕如下:

切换模式时,超高清电视上会显示间隙,应用切换至4K超高清模式。

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

UHDHelper类

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

setPreferredDisplayModeId()

public void setPreferredDisplayModeId(Window targetWindow, int modeId, boolean allowOverlayDisplay)

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

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

请注意,模式切换请求可能不成功,必须通过UHDHelperListener#onModeChanged(Display.Mode mode)对模式进行验证,或调用getMode()。必须等待模式切换完成后才能开始播放内容。

getSupportedModes()

public Display.Mode[] getSupportedModes()

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

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

getMode()

public Display.Mode getMode()

返回显示屏设置的当前模式。该方法还用于确定模式切换是否成功。如果模式切换正在进行中,则getMode()的结果为“undefined”。

返回内容
当前在系统上设置的模式,若出现错误,则为NULL。

UhdHelperListener类

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

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

Display.Mode类

Display.Mode类与Android Marshmallow中的Display.Mode类相似。用于描述显示模式的分辨率和刷新率。

模式切换过程中的间隙

由于HDMI模式切换会打断客户体验,亚马逊已构建一个间隙,可选择显示该间隙,在HDMI模式切换前为客户做好准备。用于触发该间隙的代码可通过亚马逊4K扩展库获取。

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

public voide setPreferredDisplayModeId(Window targetWindow, int modeId, boolean allowOverlayDisplay)

在此代码中将参数allowOverlayDisplay设置为true。在模式切换开始前,显示叠加层两秒。


Last updated: 2020年10月29日