在 Android 上检测 4K 超高清屏幕 [英] Detecting 4K UHD screens on Android

查看:73
本文介绍了在 Android 上检测 4K 超高清屏幕的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试检测设备何时能够以 4K 超高清 (3840x2160) 分辨率输出.许多设备(如 nVidia Shield TV 和 Sony Xperia Z5 Premium)将报告说它们以 1080p 运行,即使它们支持超高清,因为它们默认为非视频布局的 1080p 输出.我需要一些方法来检测它们是否能够 4K 区分它们和非 4K 设备(例如 Nexus Player).

这是我用来确定当前分辨率的代码:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);显示 display = wm.getDefaultDisplay();点大小 = new Point();display.getSize(size);

在 Shield TV 上,它始终返回 1920x1080,即使 ExoPlayer 报告它正在以 3840x2160 输出视频.

解决方案

更新:从 ExoPlayer 1.5.1 开始,此问题已得到修复(请参阅 https://github.com/google/ExoPlayer/commit/79055066813123c939c29e5a5e223>a5a5e223>a5f0

我跟进了 ExoPlayer 的开发人员并找到了答案:

可靠检测 4K 设备的唯一方法是使用 Device.Mode,它仅在 api 级别 23+ 中可用.请参阅此处的 Android M 说明:

https://developer.android.com/preview/api-概览.html#4K-display

以及这里的课程文档:

https://developer.android.com/参考/android/view/Display.Mode.html#getPhysicalWidth()

至于 ExoPlayer 它没有实现此代码,从当前版本 (1.4.2) 开始,但这可能会改变.见:

https://github.com/google/ExoPlayer/issues/800

最后来回答这个问题,现在检测 4K 的正确方法是这样的:

/*** 用于检查连接的设备是否支持 UHD (3840x2160)** 请注意,此调用将无法识别 23 (M) 以下 api 级别的 UHD 设备** @return 1 如果设备是 UHD,否则 0*/公共 int isUHD(){显示显示 = getActivity().getWindowManager().getDefaultDisplay();点 displaySize = getDisplaySize(display);返回 (displaySize.x >= 3840 && displaySize.y >= 2160) ?1:0;}/*** 方便的功能,分叉到不同的方式来确定不同 Android 版本的显示大小** @param display 显示实例来获取信息** @return Point a Point 描述显示尺寸*/私有静态点getDisplaySize(显示显示){Point displaySize = new Point();如果(Util.SDK_INT >= 23){getDisplaySizeV23(display, displaySize);}else if(Util.SDK_INT >= 17) {getDisplaySizeV17(display, displaySize);} else if(Util.SDK_INT >= 16) {getDisplaySizeV16(display, displaySize);} 别的 {getDisplaySizeV9(display, displaySize);}返回显示大小;}@TargetApi(23)private static void getDisplaySizeV23(Display display, Point outSize){Display.Mode[] 模式 = display.getSupportedModes();if(modes.length > 0){Display.Mode 模式 = 模式 [0];outSize.x = mode.getPhysicalWidth();outSize.y = mode.getPhysicalHeight();}}@TargetApi(17)private static void getDisplaySizeV17(Display display, Point outSize) {display.getRealSize(outSize);}@TargetApi(16)private static void getDisplaySizeV16(Display display, Point outSize) {display.getSize(outSize);}private static void getDisplaySizeV9(Display display, Point outSize) {outSize.x = display.getWidth();outSize.y = display.getHeight();}

在小于 23 的 api 上会给出错误的结果.

I am trying to detect when a device is capable of outputting at 4K UHD (3840x2160) resolution. A number of devices such as the nVidia Shield TV and the Sony Xperia Z5 Premium will report that they are running at 1080p even though they are capable of UHD, because they default to 1080p output for non-video layouts. I need some way to detect if they are 4K capable to distinguish between them and non-4K devices like the Nexus Player.

Here is the code I'm using to determine the current resolution:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);

On the Shield TV, this returns 1920x1080 all the time, even when ExoPlayer reports that it's outputting video at 3840x2160.

解决方案

UPDATE: This has been fixed as of ExoPlayer 1.5.1 (see https://github.com/google/ExoPlayer/commit/79055066813123c939c29e5a5e223a5ff043b91e)


I followed up with ExoPlayer's developers and found the answer:

The only way to reliably detect 4K devices is using Device.Mode which is only available in api level 23+. See the Android M note on that here:

https://developer.android.com/preview/api-overview.html#4K-display

And the documentation for the class here:

https://developer.android.com/reference/android/view/Display.Mode.html#getPhysicalWidth()

As for ExoPlayer it does not implement this code, as of the current version (1.4.2) but that will probably change. See:

https://github.com/google/ExoPlayer/issues/800

And finally to answer the question, the right way to detect 4K right now is something like this:

/**
 * Used to check if the connected device support UHD (3840x2160)
 *
 * Note that this call will fail to identify UHD devices on api level bellow 23 (M)
 *
 * @return 1 if device is UHD, 0 otherwise
 */
public int isUHD(){
    Display display = getActivity().getWindowManager().getDefaultDisplay();
    Point displaySize = getDisplaySize(display);
    return (displaySize.x >= 3840 && displaySize.y >= 2160) ? 1 : 0;
}

/**
 * Convenience function that forks to the different ways to obatin the Display size across Android versions
 *
 * @param display Display instance to obtain information from
 *
 * @return Point a Point describing the Display size
 */
private static Point getDisplaySize(Display display) {
    Point displaySize = new Point();
    if(Util.SDK_INT >= 23){
        getDisplaySizeV23(display, displaySize);
    }else if(Util.SDK_INT >= 17) {
        getDisplaySizeV17(display, displaySize);
    } else if(Util.SDK_INT >= 16) {
        getDisplaySizeV16(display, displaySize);
    } else {
        getDisplaySizeV9(display, displaySize);
    }
    return displaySize;
}

@TargetApi(23)
private static void getDisplaySizeV23(Display display, Point outSize){
    Display.Mode[] modes = display.getSupportedModes();
    if(modes.length > 0){
        Display.Mode mode = modes[0];
        outSize.x = mode.getPhysicalWidth();
        outSize.y = mode.getPhysicalHeight();
    }
}

@TargetApi(17)
private static void getDisplaySizeV17(Display display, Point outSize) {
    display.getRealSize(outSize);
}

@TargetApi(16)
private static void getDisplaySizeV16(Display display, Point outSize) {
    display.getSize(outSize);
}

private static void getDisplaySizeV9(Display display, Point outSize) {
    outSize.x = display.getWidth();
    outSize.y = display.getHeight();
}

Which will give wrong results on api less than 23.

这篇关于在 Android 上检测 4K 超高清屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆