2012-01-29 161 views
6

有人可以告訴我Android是如何計算屏幕密度的?Android屏幕密度計算

我的問題是我有一個具有480x800分辨率和7英寸對角線屏幕的設備(ODYS空間) 如果我計算它的密度,我得到的值是133 DPI,但Android(2.2和2.3)報告它像「MEDIUM 「密度設備(160 DPI)

我與多屏幕支持戰鬥,所以我認爲133 DPI將被報告像」低「比」中「,所以現在我的屏幕布局看起來很愚蠢在這個媒體報道的設備。

我檢查設備與這樣的代碼:

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

如果我在配置的虛擬設備(480x800/7「和133 DPI)上運行該代碼,那麼我的密度= 120。

在真實的設備上,它爲什麼說160代替?

+0

如果您正在尋找賞金,請參閱Peter O.的答案和我的評論。這裏的要點是Android如何計算密度,而不是如何檢索設置。例如,LDPI和MDPI,MDPI和HDPI之間的截斷點在哪裏等等......爲什麼給定的數字四捨五入到較高的密度而不是較低的相鄰密度,等等。再次,在AVD設備編輯器中可以看到一個答案,但到目前爲止,我還沒有找到確定的,確定的,正確的答案。 – davidcesarino 2014-09-18 02:34:56

+0

DPI - 設備獨立像素 不能有自定義值,因爲有starndards 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 – 2014-09-20 15:46:34

回答

0

如果您檢查docs(查看「使用配置限定符」部分),則設備會被視爲「低DPI」,直到您達到/低於120 DPI。

+0

是的。安德魯斯說120 =低; 160 = MEDIUM; 240 =高。這是可以的(我也知道它使用任何四捨五入時計算這些標準值) – rugo 2012-01-29 17:17:02

+1

但爲什麼android輪播133 DPI到160對面120像我所料? – rugo 2012-01-29 17:17:55

+0

我相信他們有很好的理由,但我不認識他們。 – dmon 2012-01-29 17:27:14

0

我正在使用相同的代碼,我只看到160,240,320個densityDpi值。我認爲這是在android操作系統上的這種規範化。這是我的建議,只是我不知道詳細的技術信息。

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

我已經更新了另一種解決方案在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

Actualy,如果你想擁有真正顯示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定顯示器的,所以也許顯示的實際DPI應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; 

}

這將在API lavel 4或更高版本中工作。

3

這裏有兩個不同的東西。

  1. 模擬器中的行爲,它是配置AVD本身並可能使用設備定義的AVD管理器的組合。仿真器系統映像已烘焙了值,以便我們可以爲所有設備配置發送相同的映像。這個烘焙值是密度爲mdpi。 當您創建具有不同密度的AVD時,我們在引導時間之前注入新值。根據基本規則將注入的值轉換爲密度桶值(ldpi,mdpi,hdpi,...)(如果您已經過了桶值之間的一半點,則進入下一個值)。

所以120和160之間的半點是140,因此133dpi - > ldpi。

  1. 設備可以做他們想做的任何事情。對於任何OEM來說,這是一個手動過程,可以決定他們設備的存儲桶價值,並將其設置爲屬性。它不是基於設備的實際硬件屏幕大小動態計算的。你可以做一個真正的屏幕密度爲133的設備,如果你願意的話,可以把它放在xxdpi桶中。

最終的結果是,你需要創建一個新的設備定義,你手動說你的7「480x800設備實際上是一箇中等密度的設備,它應該工作,如果沒有,這是一個錯誤當我們爲特定的基於設備的AVD配置仿真器時,這並不是什麼問題,在Android平臺本身並不存在任何問題

+0

當然,我知道原始設備製造商定義了自己的價值(類似於改裝社區的做法,我猜)。關於AVD編輯器,我不知道_exactly_對話如何計算密度(不看代碼)。也就是說,感謝您通過實驗確認我所懷疑的是:這是選擇最接近計算密度的桶。有了這些信息,我找到了它的確切位置,並在'DeviceCreationDialog'(sdkuilib)中找到'SizeListener'類,這給了我在這種情況下使用的確切算法。謝謝。 – davidcesarino 2014-09-21 00:43:12

0

製造商在爲設備製作ROM映像時選擇密度。它不是在運行時計算的。

如果你看看源代碼: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