Страницы

Поиск по вопросам

четверг, 5 декабря 2019 г.

Как получить точную плотность пикселей на Android

#java #android #screen #display #dpi


Как можно на Android получить точную плотность пикселей?

Сейчас использую следующий код:

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
double screenInches = Math.sqrt(x + y);
Log.d("debug", "Screen inches : " + screenInches); 


Его минус в том, что dm.xdpi и dm.ydpi возвращают не точные значения плотности, а
табличную плотность, к которой наиболее близка реальная плотность.

В моем случае телефон 5 дюймов 720*1280, реальная плотность 294, но код выдает мне
плотность на уровне 320 и, как следствие, неверный размер экрана в дюймах. 

Как мне получить реальную плотность?
    


Ответы

Ответ 1



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

Ответ 2



Ох уж это разнообразие размеров экранов... Давайте разбираться как работает AIDA64. Нужно отдать им должное, у них очень большая база устройств с еще не менее малым числом уточнений для конкретных моделей. У меня получилось высчитать такие же значения для тестового телефона Xiaomi Redme Note 3 Pro. Вот что у меня получилось: float my_LCD_Diagonal = 5.5f; WindowManager windowManager = activity.getWindowManager(); Resources res = activity.getResources(); Display display = null; DisplayMetrics displayMetrics = null; if(windowManager != null) { display = windowManager.getDefaultDisplay(); } if(res != null) { displayMetrics = res.getDisplayMetrics(); } if(display != null && displayMetrics != null) { float xdpi = displayMetrics.xdpi; float ydpi = displayMetrics.ydpi; if (Build.VERSION.SDK_INT >= 17) { Point point = new Point(); display.getRealSize(point); screenWidthPx = point.x; screenHeightPx = point.y; } int roundedXdpi = Math.round(xdpi); int roundedYdpi = Math.round(ydpi); float diagonal_ppi= ((float)(Math.sqrt(((double)(screenWidthPx * screenWidthPx + screenHeightPx * screenHeightPx))) / (((double)SystemInfo.DB_LCD_Diagonal)))); if(diagonal_ppi> 1f) { ydpi = diagonal_ppi; xdpi = diagonal_ppi; } if(screenWidthPx > 0 && screenHeightPx > 0 && xdpi > 1f && ydpi > 1f) { float xmm = (((float)screenWidthPx)) / xdpi * 25.4f; float ymm = (((float)screenHeightPx)) / ydpi * 25.4f; float diagonal_in_inch = (((float)Math.sqrt(((double)(xmm * xmm + ymm * ymm))))) / 25.4f; String res_dpi = String.format(Locale.getDefault(), "%d %s", Math.round((((float)Math.sqrt(((double)(screenWidthPx * screenWidthPx + screenHeightPx * screenHeightPx))))) / diagonal_in_inch), "dpi"); } } P.S. В результате получилось значение в res_dpi "401 dpi". P.P.S. Ввел данные, которые привел автор вопроса, получил значение "294 dpi". Но этот алгоритм будет работать не для всех моделей телефонов!!! Потому как должны быть внесены поправки.

Комментариев нет:

Отправить комментарий