Android screen density calculation

androidscreen

Can somebody tell me how Android counts the screen density?

My problem is I have a device (ODYS Space) with 480×800 resolution and with 7" diagonal screen.
If I calculate its density I get a value 133 DPI but Android (2.2 and 2.3 too) reports it like "MEDIUM" density device (160 DPI).

I'm fighting with multiscreen support so I supposed 133 DPI will be rather reported like "LOW" than "MEDIUM" so now my screen layout looks quite stupid on this medium reported device.

I check the device with code like this:

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

If I run that code on a virtual device configured (480×800/7" and 133 DPI) then I got density=120.

On the real device why does it say 160 instead?

Best Answer

There are two different things here.

  1. The behavior in the emulator which is a combination of the AVD manager configuring the AVD itself and maybe using a device definition. The emulator system images have baked in values so that we can ship the same image for all device configurations. This baked in value is mdpi for density. When you create an AVD with a different density we inject just before boot time the new value. The injected value is converted to a density bucket value (ldpi, mdpi, hdpi, ...) based on basic rules (if you are past the half point between bucket value, you go in the next value).

So the half point between 120 and 160 is 140, and therefore 133dpi -> ldpi.

  1. Device do whatever they want. It's a manual process for any OEM to decide what their device's bucket value is, and this get set in a property. It is not dynamically computed based on the actual hardware screen size of the device. You can do a device that has a true screen density of 133 and yet put it in the xxdpi bucket if you want.

The end result is that you need to create a new device definition where you manually say your 7" 480x800 device is actually a medium density device, and it should work. If it doesn't, it's a bug on our side when we configure the emulator for a particular device-based AVD. It's not an issue on the Android platform itself which doesn't compute anything.