Android DisplayMetrics возвращает неверный размер экрана в пикселях на ICS

Я попробовал это....

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int fullscreenheight = metrics.heightPixels;
int fullscreenwidth = metrics.widthPixels;

а также....

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

Gnex имеет дисплей 720×1280. Возвращаемый результат для ширины / высоты (в зависимости от ориентации курса) никогда не равен 1280. Я подумал, что это может быть как-то связано с панелью навигации на экране в Ice Cream Sandwich, поэтому я скрываю это с помощью:

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

... а затем начал поток, который непрерывно записывает размер экрана высота / ширина. Даже после того, как панель навигации ICS полностью исчезла... размер экрана никогда не будет отображать значение 1280. Я бы получил такие цифры:

width  = 720
height = 1184

Как вы получаете истинное разрешение экрана устройства в ICS?

Причина, по которой мне нужно это значение, заключается в том, что мое приложение воспроизводит видео, и я хотел бы, чтобы видео занимало весь экран, когда устройство находится в горизонтальной ориентации. Теперь я знаю, о чем вы думаете, почему бы просто не дать видеовизу значение "match_parent" для высоты / ширины? Причина в том, что мои видео имеют несколько форматов изображения, и я хотел бы иметь возможность рассчитать правильный размер видео в зависимости от всей ширины экрана.

6 ответов

Решение

Я нашел это скрытое сокровище ТОЛЬКО для ICS...... если вы ориентируетесь на API выше, чем ICS, см. Комментарий Криса Шмиха ниже.

Как скрыть и отобразить панель навигации на сборке Android ICS

В случае, если ссылка умирает.... вот как узнать фактический размер экрана устройства.....

Display display = getWindowManager().getDefaultDisplay();     
Method mGetRawH = Display.class.getMethod("getRawHeight");
Method mGetRawW = Display.class.getMethod("getRawWidth");
int rawWidth = (Integer) mGetRawW.invoke(display);
int rawHeight = (Integer) mGetRawH.invoke(display);

РЕДАКТИРОВАТЬ (19.11.12)

Приведенный выше код не будет работать на Android 4.2, и будет сгенерировано исключение.... Мне еще предстоит найти способ получить полноэкранный размер устройства в Android 4.2. Когда я это сделаю, я отредактирую этот ответ, но сейчас вы должны написать код на случай непредвиденных обстоятельств для Android 4.2!

Из ответа Ахмеда это полный код без ошибок:

    int width = 0, height = 0;
    final DisplayMetrics metrics = new DisplayMetrics();
    Display display = getWindowManager().getDefaultDisplay();
    Method mGetRawH = null, mGetRawW = null;

    try {
        // For JellyBean 4.2 (API 17) and onward
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
            display.getRealMetrics(metrics);

            width = metrics.widthPixels;
            height = metrics.heightPixels;
        } else {
            mGetRawH = Display.class.getMethod("getRawHeight");
            mGetRawW = Display.class.getMethod("getRawWidth");

            try {
                width = (Integer) mGetRawW.invoke(display);
                height = (Integer) mGetRawH.invoke(display);
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    } catch (NoSuchMethodException e3) {  
        e3.printStackTrace();
    }

Ты можешь использовать getRealSize чтобы получить разрешение экрана. Он официально поддерживается в API 17 и выше, но фактически существует в SDK начиная с API 14. Если вы используете платформу SDK для API 17 или выше, вы можете получить доступ к методу обычным способом и просто обойти предупреждение о том, что он доступен только в API. 17.

/**
 * Gets the device's native screen resolution rotated
 * based on the device's current screen orientation.
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) //To remove warning about using
                                               //getRealSize prior to API 17
private Point screenResolution() {
    WindowManager windowManager =
        (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    Point screenResolution = new Point();

    if (Build.VERSION.SDK_INT < 14)
        throw new RuntimeException("Unsupported Android version.");
    display.getRealSize(screenResolution);

    return screenResolution;    
}

Я проверил это на реальном устройстве Android 5.0.2 и эмуляторе под управлением 4.1.1 (и, возможно, других).

Спасибо benkc за то, что указал на это в комментариях.

Попробуй это

    final DisplayMetrics metrics = new DisplayMetrics(); 
    Display display = getWindowManager().getDefaultDisplay();     
    Method mGetRawH = null,mGetRawW = null;

    try {
                    // For JellyBeans and onward
        if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN){
            display.getRealMetrics(metrics);

            realWidth = metrics.widthPixels;
            realHeight = metrics.heightPixels;
        }else{
            mGetRawH = Display.class.getMethod("getRawHeight");
            mGetRawW = Display.class.getMethod("getRawWidth");

            try {
                realWidth = (Integer) mGetRawW.invoke(display);
                realHeight = (Integer) mGetRawH.invoke(display);
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
public static Point getRealSize(Display display) {
        Point outPoint = new Point();
        Method mGetRawH;
        try {
            mGetRawH = Display.class.getMethod("getRawHeight");
            Method mGetRawW = Display.class.getMethod("getRawWidth");
            outPoint.x = (Integer) mGetRawW.invoke(display);
            outPoint.y = (Integer) mGetRawH.invoke(display);
            return outPoint;
        } catch (Throwable e) {
            return null;
        }
    }

    public static Point getSize(Display display) {
        if (Build.VERSION.SDK_INT >= 17) {
            Point outPoint = new Point();
            DisplayMetrics metrics = new DisplayMetrics();
            display.getRealMetrics(metrics);
            outPoint.x = metrics.widthPixels;
            outPoint.y = metrics.heightPixels;
            return outPoint;
        }
        if (Build.VERSION.SDK_INT >= 14) {
            Point outPoint = getRealSize(display);
            if (outPoint != null)
                return outPoint;
        }
        Point outPoint = new Point();
        if (Build.VERSION.SDK_INT >= 13) {
            display.getSize(outPoint);
        } else {
            outPoint.x = display.getWidth();
            outPoint.y = display.getHeight();
        }
        return outPoint;
    }

На некоторых устройствах, например планшетах, панель навигации вообще не может быть скрыта ( источник, см. Раздел "Управление отображением пользовательского интерфейса системы"), поскольку в качестве резервной копии нет аппаратных кнопок. Если на вашем устройстве вам удалось скрыть панель, вы можете сделать полноэкранный просмотр и запросить его размер с помощью getWidth() и getHeight().

Насколько я знаю, нет надежного способа получить размер экрана на всех устройствах ICS.

Другие вопросы по тегам