Android screen density calculation

Can someone tell me how Android calculates screen density?

My problem is that I have a device (ODYS Space) with a resolution of 480x800 and with a 7-inch diagonal screen. If I calculated its density, I get a value of 133 DPI, but Android (2.2 and 2.3 too) reports this as a MEDIUM density device (160 DPI).

I am struggling with multi-screen support, so I assumed that 133 DPI would be reported as “LOW” than “MEDIUM”, so now my screen layout looks pretty dumb on this device with a message with a message.

I test the device with the code as follows:

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

If I ran this code on a configured virtual device (480x800 / 7 "and 133 DPI), then I got density = 120.

On a real device, why does he say 160 instead?

+6
source share
8 answers

There are two different things here.

  • The behavior in the emulator, which is a combination of an AVD manager, configuring the AVD itself and, possibly, using a device definition. Images of the emulator system are baked in values, so we can send the same image for all device configurations. This is the baked mdpi value for density. When you create an AVD with a different density, we enter a new value before loading. The injected value is converted to a density value (ldpi, mdpi, hdpi, ...) based on the basic rules (if you go half the point between the slave value, you go to the next value).

Thus, half the point between 120 and 160 is 140, and therefore 133dpi → ldpi.

  1. The device does whatever it wants. This is a manual process for any OEM to decide what its slave value is for the device, and this is set in the property. It is not dynamically calculated based on the actual size of the device’s hardware screen. You can make a device with a true screen density of 133 and still put it in an xxdpi bucket if you want.

The end result is that you need to create a new device definition in which you manually say that your 780x800 device is actually a medium density device and it should work. If this is not the case, it is a mistake on our side when we configure the emulator for a specific device-based AVD. This is not a problem on the Android platform itself, which does not calculate anything.

+3
source

I updated one of the other solutions for 2014.

Call this method in one of your actions:

 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; } } 
+2
source

In fact, if you want to have a real graphic tag , the answer is somewhere in the middle if you request display metrics:

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

densityDpi will give you values ​​/ assumptions whose density you should use

 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 

as indicated in previous posts

but dm.xdpi will not always display the REAL dpi of this display, so perhaps the actual dpi values ​​on the display should be Density*xdpi

+1
source

If you check the docs (find the “Using Configuration Classifiers” section), the device is considered “low DPI” until you get around / below 120 DPI.

0
source

I use the same code, and I only saw density values ​​of 160, 240, 320 density. I believe that such normalization on android os. This is my suggestion only I do not know the detailed technical information.

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

}

This will work in lavel 4 API or higher.

0
source

The manufacturer chooses the density when creating the ROM image for your device. It is not calculated at runtime.

If you look at the source: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/DisplayMetrics.java#L294 , you will see that the getDeviceDensity() function tries to use two system properties one is the value of the qemu emulator qemu.sf.lcd_density , and the other is the value set by the manufacturer ro.sf.lcd_density , and finally, if the manufacturer forgot to install it, the system returns to default. DENSITY_DEFAULT set to DENSITY_MEDIUM , which is set to 160 .

You can check the device property by connecting your device and running the following command:

 adb shell getprop ro.sf.lcd_density 

Properties are stored in /system/build.prop and loaded at boot time. You can view the contents of the file with this command:

 adb shell cat /system/build.prop 
0
source

Source: https://habr.com/ru/post/907157/


All Articles