2012-01-29 7 views
6

¿Alguien puede decirme cómo Android cuenta la densidad de la pantalla?Cálculo de la densidad de la pantalla de Android

Mi problema es que tengo un dispositivo (ODYS Space) con resolución de 480x800 y con pantalla diagonal de 7 " Si calculo su densidad, recibo un valor de 133 DPI pero Android (2.2 y 2.3 también) lo informa como" MEDIUM "dispositivo de densidad (160 DPI).

Estoy peleando con soporte multipantalla, así que supuse que 133 DPI aparecerían más como" BAJO "que" MEDIO ", por lo que ahora el diseño de mi pantalla parece bastante estúpido en este dispositivo medio.

puedo comprobar el dispositivo con un código como éste:

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

Si ejecuto ese código en un dispositivo virtual configurado (480x800/7 "y 133 DPI) obtuve densidad = 120.

En el dispositivo real, ¿por qué dice 160 en su lugar?

+0

Si está buscando la recompensa, vea la respuesta de Peter O. y mi comentario debajo. El punto principal aquí es cómo Android realmente calcula la densidad, no cómo recupera la configuración. Por ejemplo, dónde está el límite entre LDPI y MDPI, MDPI y HDPI, y así sucesivamente ... por qué un número dado se redondea a la densidad superior y no a la densidad adyacente inferior, y así sucesivamente. Nuevamente, se puede ver una pista de la respuesta en el Editor de dispositivos AVD, pero hasta ahora no he podido encontrar una respuesta determinista, cierta y correcta. – davidcesarino

+0

DPI - Dispositivo pixel independiente No se puede tener valores personalizados porque hay starndards 0,75 - LDPI - 120 dpi 1,0 - MDPI - 160 dpi 1,5 - IPAP - 240 dpi 2,0 - xhdpi - 320 dpi 3,0 - xxhdpi - 480 dpi 4.0 - xxxhdpi - 640 dpi –

Respuesta

0

Si marca docs (busque la sección "Usar los calificadores de configuración"), un dispositivo se considera "bajo DPI" hasta que llegue a menos de 120 DPI.

+0

Sí. androis dice 120 = BAJO; 160 = MEDIANO; 240 = ALTO. está bien (también sé que usa cualquier redondeo cuando se calculan estos valores estándar) – rugo

+1

PERO ¿por qué android redondea 133 DPI a 160 frente a 120 como esperaba? – rugo

+0

Estoy seguro de que tenían buenas razones para ello, pero yo no los conozco. – dmon

0

Estoy usando el mismo código y he visto los valores 160, 240, 320 densidadDpi solamente. Creo que es una normalización en Android OS. Es mi sugerencia, solo que no sé información técnica detallada.

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

    } 
} 
2

He puesto al día una de las otras soluciones de 2014.

llama a este método en una de sus actividades:

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

podía comprender si usted quiere tener la visualización de las aplicaciones dpi la respuesta está en algún lugar entre si consulta las métricas de visualización:

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

densityDpi le dará los valores/sugerencia cual la densidad se debe utilizar

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 

como se especifica en las entradas anteriores

pero dm.xdpi no le dará siempre la PPP real, de pantalla dada así, quizá verdadera dpi de la pantalla debe ser Density*xdpi

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

}

Esto funcionará en API lavel 4 o superior.

3

Aquí hay dos cosas diferentes.

  1. Comportamiento en el emulador que es una combinación del administrador de AVD que configura el AVD mismo y tal vez usa una definición de dispositivo. Las imágenes del sistema del emulador se han horneado en valores para que podamos enviar la misma imagen para todas las configuraciones de dispositivos. Este valor cocido es mdpi para la densidad. Cuando crea un AVD con una densidad diferente inyectamos justo antes del arranque el nuevo valor. El valor inyectado se convierte en un valor de cubo de densidad (ldpi, mdpi, hdpi, ...) basado en reglas básicas (si ha pasado el punto medio entre el valor del cubo, ingresa el siguiente valor).

Entonces el punto medio entre 120 y 160 es 140, y por lo tanto 133dpi -> ldpi.

  1. El dispositivo hace lo que quiere. Es un proceso manual para que cualquier OEM decida cuál es el valor del cubo de su dispositivo, y esto se establece en una propiedad. No se calcula de forma dinámica en función del tamaño real de la pantalla del hardware del dispositivo. Puede hacer un dispositivo que tenga una densidad de pantalla verdadera de 133 y, sin embargo, colocarlo en el cubo xxdpi si lo desea.

El resultado final es que es necesario crear una nueva definición de dispositivo en el que dice manualmente su 480x800 dispositivo 7" es en realidad un dispositivo de densidad media, y debería funcionar. Si no es así, se trata de un error en nuestro lado cuando configuramos el emulador para un AVD particular basado en dispositivo. No es un problema en la plataforma Android que no computa nada.

+0

Claro, sabía que los OEM definían su propio valor (similar a como lo hace la comunidad de modding, creo). Sobre el editor de AVD, no sabía exactamente cómo el cuadro de diálogo calculó la densidad (sin ver el código). Dicho esto, gracias por confirmar lo que sospechaba al experimentar: que selecciona el cubo que está más cerca de la densidad calculada.Con esa información, fui a buscar dónde se encontraba exactamente y encontré la clase 'SizeListener' en' DeviceCreationDialog' (en sdkuilib), que me proporcionó el algoritmo exacto utilizado en esa circunstancia. Gracias. – davidcesarino

0

El fabricante elige la densidad cuando crea la imagen ROM para su dispositivo. No se calcula en tiempo de ejecución

Si echa un vistazo a la fuente: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/DisplayMetrics.java#L294 verá la función getDeviceDensity() intenta usar dos propiedades del sistema, uno es el valor del emulador qemu qemu.sf.lcd_density, y el otro es el valor establecido por el fabricante ro.sf.lcd_density, y finalmente, si el fabricante olvidó establecer uno, el sistema vuelve al valor predeterminado. DENSITY_DEFAULT se establece en DENSITY_MEDIUM que se establece en 160.

Usted puede verificar la propiedad de dispositivo mediante la conexión de su dispositivo y la ejecución de este comando:

adb shell getprop ro.sf.lcd_density 

Las propiedades se almacenan en /system/build.prop y se cargan en el arranque. Puede mirar el contenido del archivo con este comando:

adb shell cat /system/build.prop 
Cuestiones relacionadas