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" для высоты/ширины? Причина в том, что мои видеоролики имеют множественные пропорции, и я хотел бы иметь возможность рассчитать правильный размер видео в зависимости от всей ширины экрана.

Ответы

Ответ 1

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

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

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

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);

РЕДАКТИРОВАТЬ (11/19/12)

Вышеприведенный код НЕ РАБОТАЕТ на Android 4.2 и исключение будет выброшено.... Мне еще предстоит найти способ получить полный размер экрана устройства в Android 4.2. Когда я это сделаю, я отредактирую этот ответ, но на данный момент вы должны указывать на непредвиденные обстоятельства для android 4.2!!

Ответ 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();
    }

Ответ 3

Попробуйте это

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

Ответ 4

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

/**
 * Gets the device native screen resolution rotated
 * based on the device 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 (и, возможно, на других).

Благодаря benc для указав это в комментариях.

Ответ 5

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;
    }

Ответ 6

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

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