Как получить размер экрана Android в программном отношении, раз и навсегда?

Как я могу определить размер экрана программно, в единицах, используемых событиями касания и Просмотр измерения/компоновки? Другими словами, мне нужны координаты в правом нижнем углу экрана, в системе координат, используемой сенсорными событиями " getRawX()/getRawY() и View.getLocationOnScreen().

Я не решаюсь вызывать нужные единицы измерения/просмотра "пикселей" поскольку, очевидно, существует несколько понятий "пикселей" , на моем телефоне в различных режимах, и они не дополняют последовательную историю.

Я вижу, что это было задано и много ответили на stackoverflow и в других местах, но ни один из ответов не работает на моем телефоне (droid 4, android 4.1.2) во всех режимах:

(вау!)

Это код библиотеки, который должен работать независимо от того, находится ли приложение в режиме совместимости с экраном, (т.е. targetSdkVersion <= 10 в манифесте) или нет, и я также не хочу делать никаких предположений о позиции, размере или наличии строки состояния или любые другие подобные декорации экрана.


Вот факты:

  • мой телефон (дроид 4 работает андроид 4.1.2) имеет 540x960 физических пикселей, то есть маленькие цветные светящиеся точки.

  • размер экрана в желаемых единицах, от просмотра событий касания и просмотра измерений, является 360x640, когда приложение находится в режиме сопоставления экрана, 540x960, когда приложение не находится в режиме сопоставления экрана. Это числа, которые мне нужно найти программно, без отбрасывания событиями касания или представлениями, чтобы найти их, но мне очень сложно найти какой-либо API которые вернут эти числа.

  • Полученные объекты Display и DisplayMetrics в разных отношениях все утверждают, что размер экрана 540x960 "пикселей" (в режиме сопоставления экрана или нет). Чтобы быть конкретным, все говорят 540x960 все время:   DisplayMetrics. {Ширина, высота} Пиксели,   Display.getSize(),   Display.getRealSize(),   Display.get {ширина, высота}(),

  • Объекты конфигурации, полученные различными способами все говорят экран {Ширина, Высота} Dp = 360x614 (в режиме сопоставления экрана или нет). Я не считаю, что это весь экран, так как соотношение сторон неверно. (Я думаю, что весь экран минус строка состояния; Мне нужен весь экран.) Я думаю, что можно с уверенностью сказать, что весь экран 360x640 dp, хотя я не знаю API, который возвращает это 640.

  • DisplayMetrics, полученный различными способами скажем, "плотность" 1.0f, когда в режиме сопоставления экрана, 1.5f, если не в режиме сопоставления экрана.

  • Деятельность   getWindow().getAttributes().{width,height} не является полезным, поскольку он обычно содержит MATCH_PARENT а не фактические размеры. Но я, видимо, могу получить желаемый ответ от   getWindow().getDecorView().getMeasured{Width,Height}() (что на самом деле удивительно, поскольку окно активности decorView не похоже, что он занимает весь экран; похоже, что он занимает экран минус строка состояния). Но я не хочу полагаться на это, потому что если окно когда-либо будет изменено (появляется мягкая клавиатура? кто-то вызывает window.setAttributes()? или, может быть, я вообще не занимаюсь деятельностью), это, очевидно, будет неправильным.

Я понимаю, что предполагается следующая формула:   пикселей = плотность dp * Это, похоже, согласуется со всеми представленными числами ((3), (4), (5) выше) если не в режиме совместимости с экраном:   540x960 = 360x640 * 1,5 Но в режиме совместимости с экраном он не складывается:   540x960!= 360x640 * 1 Итак, что-то не так.

Простейшее объяснение, я думаю, заключается в том, что методы, перечисленные в (3) выше просто дают неправильный ответ для "пикселей" , когда в режиме сопоставления экрана, то есть они были предназначены для возврата 360x640 "пикселей" , но они ошибочно возвращают 540x960 вместо этого. Но могут быть и другие способы взглянуть на это.

В любом случае, получение желаемых номеров независимо от режима, из вышеупомянутых кусочков головоломки, безусловно, сложная головоломка. Я нашел способ, который, кажется, работает на моем телефоне в обоих режимах, но это очень круто, и он полагается на два предположения, которые по-прежнему кажутся довольно шаткими (как описано в комментариях кода ниже).

Вот мой рецепт:

/** get screen size in "pixels", i.e. touchevent/view units.
* on my droid 4, this is 360x640 or 540x960
* depending on whether the app is in screen compatibility mode
* (i.e. targetSdkVersion<=10 in the manifest) or not. */
public void getScreenSizePixels(int widthHeightInPixels[/*2*/])
{
    Resources resources = getResources();
    Configuration config = resources.getConfiguration();
    DisplayMetrics dm = resources.getDisplayMetrics();
    // Note, screenHeightDp isn't reliable
    // (it seems to be too small by the height of the status bar),
    // but we assume screenWidthDp is reliable.
    // Note also, dm.widthPixels,dm.heightPixels aren't reliably pixels
    // (they get confused when in screen compatibility mode, it seems),
    // but we assume their ratio is correct.
    double screenWidthInPixels = (double)config.screenWidthDp * dm.density;
    double screenHeightInPixels = screenWidthInPixels * dm.heightPixels / dm.widthPixels;
    widthHeightInPixels[0] = (int)(screenWidthInPixels + .5);
    widthHeightInPixels[1] = (int)(screenHeightInPixels + .5);
}

Есть ли лучший/чистый способ найти размер экрана?

Ответ 1

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

Теперь вы можете измерить размер экрана в пикселях, который является лучшим измерительным устройством, чем сантиметр, потому что все кнопки, текстовые изображения и т.д. измеряются в этом устройстве. Это то, что я обычно использую

Ответ 2

С помощью DisplayMetrics вы можете получить высоту и ширину экрана любого устройства. Обратите внимание, что ширина и высота чувствительны к вращению. вот код

DisplayMetrics metrics; 
int width = 0, height = 0;

В вашем методе onCreate

 metrics = new DisplayMetrics();        
 getWindowManager().getDefaultDisplay().getMetrics(metrics);

 height = Math.min(metrics.widthPixels, metrics.heightPixels); //height
 width = Math.max(metrics.widthPixels, metrics.heightPixels); //width

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

Ответ 3

В своем # 6 вы заметите, что DecorView, похоже, обеспечивает то, что вы хотите, но вы не думаете, что это реально. Я считаю, что это так близко, как вы можете прийти. Согласно документации для Window.getDecorView:

Получить представление об уровне окна верхнего уровня (содержащее стандартный оконный фрейм/декорации и содержимое клиента внутри него), который можно добавить в окно в диспетчере окон.

Строка состояния является частью упомянутого там оформления окна. Программные клавиатуры и другие наложения получат свое собственное окно, поэтому они не должны мешать соответствующим значениям. Правильно, что это не точно показатели отображения, но если ваше приложение полноэкранное, всегда должен быть полный размер экрана, отфильтрованный через переводчик совместимости. Другие приложения не будут иметь доступ к вашему приложению Window, поэтому нет необходимости беспокоиться о том, что какое-либо другое приложение меняет атрибуты, пока вы не смотрите.

Надеюсь, что это поможет.

Ответ 4

Я должен поставить это как комментарий, но у меня нет репутации для этого.
Это может быть не совсем правильный ответ, но я получил свои размеры, когда я переключил высоту и ширину в методе DisplayMetrics.

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);   
    width = metrics.heightPixels;
    height = metrics.widthPixels;

как я сказал, это может быть неверно, но я не знаю, почему, но это сработало для меня.

Ответ 5

Если вы используете уровень api 17 или выше, проверьте getRealMetrics и getRealSize в Display

Для api уровня 14,15 и 16 посмотрите здесь

Ответ 6

Я использовал теорему Пифагора, чтобы найти диагональный размер экрана телефона Android/планшета Android, тот же самый принцип может быть применен к экрану iPhone или Blackberry.

DisplayMetrics met = new DisplayMetrics();                
this.getWindowManager().getDefaultDisplay().getMetrics(met);// get display metrics object
String strSize = 
new DecimalFormat("##.##").format(Math.sqrt(((met.widthPixels / met.xdpi) *
(met.widthPixels / met.xdpi)) +
((met.heightPixels / met.ydpi) * (met.heightPixels / met.ydpi))));
// using Dots per inches with width and height

Пифагор, должно быть, был гением, он знал программирование смартфонов так много лет назад: p

Ответ 7

Я использую метод ниже, чтобы получить ширину устройства:

public static int getDeviceWidth(Context context){
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    int width=display.getWidth();
    return width;
}

Ответ 8

Я думаю, что эта функция поможет вам просто получить ширину и высоту размера экрана вашего Android. Функция возвращает ширину и высоту в виде массива целых чисел, как показано ниже.

private int[] getScreenSIze(){
        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int h = displaymetrics.heightPixels;
        int w = displaymetrics.widthPixels;

        int[] size={w,h};
        return size;

    }

и на вашем методе создания выведите свою ширину и высоту, как показано ниже.

 int[] screenSize= getScreenSIze();
        int width=screenSize[0];
        int height=screenSize[1];
        screenSizes.setText("Phone Screen sizes \n\n  width = "+width+" \n Height = "+height);

Загрузите исходный код и протестируйте его на своей студии Android.

Ответ 9

Это работает для меня:

int width = Resources.getSystem().getDisplayMetrics().widthPixels;

int height = Resources.getSystem().getDisplayMetrics().heightPixels;

Я использовал это, чтобы обновить ширину моих предметов в горизонтальном представлении переработчика (согласно моему требованию) Надеюсь, это поможет кому-то!

Ответ 10

Для этого решения в Kotlin, попробуйте это:

private fun yourFunction(){
   val metrics = DisplayMetrics()
   windowManager.defaultDisplay.getMetrics(metrics)
   val width = metrics.widthPixels
   val height = metrics.heightPixels
}