Skip to content Skip to sidebar Skip to footer

Detecting 4k Uhd Screens On Android

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

Solution 1:

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
 */publicintisUHD(){
    Displaydisplay= getActivity().getWindowManager().getDefaultDisplay();
    PointdisplaySize= 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
 */privatestatic Point getDisplaySize(Display display) {
    PointdisplaySize=newPoint();
    if(Util.SDK_INT >= 23){
        getDisplaySizeV23(display, displaySize);
    }elseif(Util.SDK_INT >= 17) {
        getDisplaySizeV17(display, displaySize);
    } elseif(Util.SDK_INT >= 16) {
        getDisplaySizeV16(display, displaySize);
    } else {
        getDisplaySizeV9(display, displaySize);
    }
    return displaySize;
}

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

@TargetApi(17)privatestaticvoidgetDisplaySizeV17(Display display, Point outSize) {
    display.getRealSize(outSize);
}

@TargetApi(16)privatestaticvoidgetDisplaySizeV16(Display display, Point outSize) {
    display.getSize(outSize);
}

privatestaticvoidgetDisplaySizeV9(Display display, Point outSize) {
    outSize.x = display.getWidth();
    outSize.y = display.getHeight();
}

Which will give wrong results on api less than 23.

Solution 2:

Should be using DisplayCompat.getSupportedModes as the TV may be running in FHD even if it support UHD. It is possible that UHD is only enabled during video playback.

funisUhdDevice(context: Context) : Boolean {

    val displayManager = DisplayManagerCompat.getInstance(context)
    val defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY)

    defaultDisplay?.let { display ->
        return DisplayCompat.getSupportedModes(context, display).any { it.physicalHeight >= 2160 && it.physicalWidth >= 3840 }
    }
    returnfalse
}

Post a Comment for "Detecting 4k Uhd Screens On Android"