Расчет плотности экрана Android - PullRequest
6 голосов
/ 29 января 2012

Может кто-нибудь сказать мне, как Android считает плотность экрана?

Моя проблема в том, что у меня есть устройство (ODYS Space) с разрешением 480x800 и диагональю экрана 7 дюймов. Если я вычисляю его плотность, я получаю значение 133 DPI, но Android (2.2 и 2.3 тоже) сообщает о нем как устройство со средней плотностью (160 DPI).

Я борюсь с многоэкранной поддержкой, поэтому я предположил, что 133 DPI будет отображаться скорее как "НИЗКИЙ", чем "СРЕДНИЙ", поэтому теперь мой экран выглядит довольно глупо на этом устройстве, о котором сообщается.

Я проверяю устройство следующим кодом:

DisplayMetrics dMetrics = new DisplayMetrics(); 
getWindowManager().getDefaultDisplay().getMetrics(dMetrics);  
int d=dMetrics.densityDpi;

Если я запускаю этот код на настроенном виртуальном устройстве (480x800 / 7 "и 133 DPI), я получаю плотность = 120.

На реальном устройстве, почему вместо этого написано 160?

Ответы [ 8 ]

3 голосов
/ 20 сентября 2014

Здесь есть две разные вещи.

  1. Поведение в эмуляторе, которое представляет собой комбинацию менеджера AVD, конфигурирующего сам AVD и, возможно, использующего определение устройства.Образы системы эмулятора запечатываются в значения, так что мы можем отправить одно и то же изображение для всех конфигураций устройства.Это запеченный в значении является MDP для плотности.Когда вы создаете AVD с другой плотностью, мы вводим перед загрузкой новое значение.Введенное значение преобразуется в значение сегмента плотности (ldpi, mdpi, hdpi, ...) на основе основных правил (если вы перешли половину точки между значениями сегмента, вы переходите к следующему значению).

Таким образом, половина точки между 120 и 160 равна 140, и, следовательно, 133 dpi -> ldpi.

Устройство делай что хочешь.Любой OEM-изготовитель решает, какова величина сегмента их устройства, вручную, и это устанавливается в свойстве.Он не рассчитывается динамически на основе фактического размера экрана устройства.Вы можете создать устройство с истинной плотностью экрана 133 и при желании поместить его в корзину xxdpi.

Конечный результат заключается в том, что вам необходимо создать новое определение устройства, в котором вы вручнуюскажем, ваше 7-дюймовое устройство 480x800 на самом деле является устройством средней плотности, и оно должно работать. Если это не так, то это ошибка с нашей стороны, когда мы настраиваем эмулятор для конкретного устройства AVD. Это не проблема для Androidсама платформа, которая ничего не вычисляет.

2 голосов
/ 05 марта 2014

Я обновил одно из других решений на 2014 год.

Вызовите этот метод в одном из ваших занятий:

private void tellMeDensity() {
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int dpiClassification = dm.densityDpi;

        float xDpi = dm.xdpi;
        float yDpi = dm.ydpi;

        Toast.makeText(this, "xdpi=" + xDpi, Toast.LENGTH_SHORT).show();
        Toast.makeText(this, "ydpi=" + yDpi, Toast.LENGTH_SHORT).show();

        switch(dpiClassification) {
           case DisplayMetrics.DENSITY_LOW:
               Toast.makeText(this, "low density", Toast.LENGTH_SHORT).show();
               break;    
           case DisplayMetrics.DENSITY_MEDIUM:
               Toast.makeText(this, "medium density", Toast.LENGTH_SHORT).show();
               break;                
           case DisplayMetrics.DENSITY_HIGH:
               Toast.makeText(this, "high density", Toast.LENGTH_SHORT).show();
               break;    
           case DisplayMetrics.DENSITY_XHIGH:
               Toast.makeText(this, "xhigh density", Toast.LENGTH_SHORT).show();
               break;                  
           case DisplayMetrics.DENSITY_XXHIGH:
               Toast.makeText(this, "xxhigh density", Toast.LENGTH_SHORT).show();
               break;                  
           case DisplayMetrics.DENSITY_XXXHIGH:
               Toast.makeText(this, "xxxhigh density", Toast.LENGTH_SHORT).show();
               break;      
        }
    }
1 голос
/ 18 сентября 2014

На самом деле, если вы хотите иметь реальное отображение dpi , ответ будет где-то посередине, если вы запросите метрики отображения:

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int dpiClassification = dm.densityDpi;
float xDpi = dm.xdpi;
float yDpi = dm.ydpi;

densityDpi даст вам значения /предложение, какую плотность вы должны использовать

0.75 - ldpi - 120 dpi
1.0 - mdpi - 160 dpi
1.5 - hdpi - 240 dpi
2.0 - xhdpi - 320 dpi
3.0 - xxhdpi - 480 dpi
4.0 - xxxhdpi - 640 dpi

, как указано в предыдущих постах

, но dm.xdpi не всегда даст вам REAL dpi данного дисплея, поэтомуможет быть, реальное разрешение экрана должно быть Density*xdpi

0 голосов
/ 21 сентября 2014

Производитель выбирает плотность при создании образа ПЗУ для вашего устройства.Он не рассчитывается во время выполнения.

Если вы посмотрите на источник: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/DisplayMetrics.java#L294 вы увидите, что функция getDeviceDensity() пытается использовать два системных свойства, одним из которых является эмулятор qemu.значение qemu.sf.lcd_density, а другое - это установленное производителем значение ro.sf.lcd_density, и, наконец, если производитель забыл установить одно, система возвращается к значению по умолчанию.Для DENSITY_DEFAULT установлено значение DENSITY_MEDIUM, для которого установлено значение 160.

Вы можете проверить свойство устройства, подключив устройство и выполнив следующую команду:

adb shell getprop ro.sf.lcd_density

Свойствахранятся в /system/build.prop и загружаются при загрузке.Вы можете просмотреть содержимое файла с помощью этой команды:

adb shell cat /system/build.prop
0 голосов
/ 20 сентября 2014
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
switch(metrics.densityDpi){
 case DisplayMetrics.DENSITY_LOW:
            break;
 case DisplayMetrics.DENSITY_MEDIUM:
             break;
 case DisplayMetrics.DENSITY_HIGH:
             break;

}

Это будет работать в API уровня 4 или выше.

0 голосов
/ 12 марта 2012
**dpi calculation programitically:**

public class SampleActivity extends Activity
{

   @Override
   public void onCreate(Bundle savedInstanceState)
    {
      super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       DisplayMetrics dm = new DisplayMetrics();
       getWindowManager().getDefaultDisplay().getMetrics(dm);
       int dpiClassification = dm.densityDpi;

    float xDpi = dm.xdpi;
    float yDpi = dm.ydpi;

    Toast.makeText(SampleActivity.this, "xdpi="+xDpi, Toast.LENGTH_SHORT).show();
    Toast.makeText(SampleActivity.this, "ydpi="+yDpi, Toast.LENGTH_SHORT).show();


    switch(dpiClassification)
    {
       case DisplayMetrics.DENSITY_LOW:
           Toast.makeText(SampleActivity.this, "low density",    
                   Toast.LENGTH_SHORT).show();

                 break;

       case DisplayMetrics.DENSITY_MEDIUM:
           Toast.makeText(SampleActivity.this, "low medium", 
                  Toast.LENGTH_SHORT).show();

                 break;
       case DisplayMetrics.DENSITY_HIGH:
           Toast.makeText(SampleActivity.this, "low high", 
                     Toast.LENGTH_SHORT).show();

                  break;



       case DisplayMetrics.DENSITY_XHIGH:
           Toast.makeText(SampleActivity.this, "low xhigh", 
                  Toast.LENGTH_SHORT).show();

                 break;
       }

    }
 }
0 голосов
/ 29 января 2012

Я использую тот же код, и я видел только значения 160, 240, 320 densityDpi. Я думаю, что это такая нормализация на Android OS. Это мое предложение, только я не знаю подробную техническую информацию.

0 голосов
/ 29 января 2012

Если вы проверите docs (см. Раздел «Использование квалификаторов конфигурации»), устройство будет считаться «низким DPI» до тех пор, пока не достигнете / не достигнет 120 DPI.

...