Reputation: 71
Can somebody tell me how Android counts the screen density?
My problem is I have a device (ODYS Space) with 480x800 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 (480x800/7" and 133 DPI) then I got density=120.
On the real device why does it say 160 instead?
Upvotes: 6
Views: 11865
Reputation: 18187
I have updated one of the other solutions for 2014.
Call this method in one of your Activities:
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;
}
}
Upvotes: 2
Reputation: 11190
The manufacturer chooses the density when it makes the ROM image for your device. It is not calculated at run-time.
If you take a look at the source: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/DisplayMetrics.java#L294 you'll see the getDeviceDensity()
function tries to use two system properties one is the qemu emulator value qemu.sf.lcd_density
, and the other is the manufacturer set value ro.sf.lcd_density
, and finally if the manufacturer forgot to set one the system falls back to the default. DENSITY_DEFAULT
is set to DENSITY_MEDIUM
which is set to 160
.
You can verify the device property by plugging in your device and running this command:
adb shell getprop ro.sf.lcd_density
The properties are stored in /system/build.prop
and are loaded on boot. You can look at the contents of the file with this command:
adb shell cat /system/build.prop
Upvotes: 0
Reputation: 28549
There are two different things here.
So the half point between 120 and 160 is 140, and therefore 133dpi -> ldpi.
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.
Upvotes: 4
Reputation: 2243
**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;
}
}
}
Upvotes: 0
Reputation: 1628
I'm using same code and I have seen values 160, 240, 320 densityDpi values only. I thinks it's such a normalization on android os. It's my suggestion only I don't know detailed technical information.
Upvotes: 0