1. 程式人生 > >Android 獲取螢幕尺寸與密度

Android 獲取螢幕尺寸與密度

轉的別人的

android中獲取螢幕的長與寬,參考了網上有很多程式碼,但結果與實際不符,如我的手機是i9000,螢幕大小是480*800px,得到的結果卻為320*533

結果很不靠譜,於是自己寫了幾行程式碼,親測一下

測試引數:

測試環境: i9000(三星)

物理螢幕:480*800px

density :1.5

測試程式碼:

[java] view plaincopyprint?
  1. // 獲取螢幕密度(方法1)
  2. int screenWidth  = getWindowManager().getDefaultDisplay().getWidth();       // 螢幕寬(畫素,如:480px)
  3. int
     screenHeight = getWindowManager().getDefaultDisplay().getHeight();      // 螢幕高(畫素,如:800p)
  4. Log.e(TAG + "  getDefaultDisplay""screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);  
  5. // 獲取螢幕密度(方法2)
  6. DisplayMetrics dm = new DisplayMetrics();  
  7. dm = getResources().getDisplayMetrics();  
  8. float
     density  = dm.density;        // 螢幕密度(畫素比例:0.75/1.0/1.5/2.0)
  9. int densityDPI = dm.densityDpi;     // 螢幕密度(每寸畫素:120/160/240/320)
  10. float xdpi = dm.xdpi;             
  11. float ydpi = dm.ydpi;  
  12. Log.e(TAG + "  DisplayMetrics""xdpi=" + xdpi + "; ydpi=" + ydpi);  
  13. Log.e(TAG + "  DisplayMetrics""density=" + density + 
    "; densityDPI=" + densityDPI);  
  14. screenWidth  = dm.widthPixels;      // 螢幕寬(畫素,如:480px)
  15. screenHeight = dm.heightPixels;     // 螢幕高(畫素,如:800px)
  16. Log.e(TAG + "  DisplayMetrics(111)""screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);  
  17. // 獲取螢幕密度(方法3)
  18. dm = new DisplayMetrics();  
  19. getWindowManager().getDefaultDisplay().getMetrics(dm);  
  20. density  = dm.density;      // 螢幕密度(畫素比例:0.75/1.0/1.5/2.0)
  21. densityDPI = dm.densityDpi;     // 螢幕密度(每寸畫素:120/160/240/320)
  22. xdpi = dm.xdpi;           
  23. ydpi = dm.ydpi;  
  24. Log.e(TAG + "  DisplayMetrics""xdpi=" + xdpi + "; ydpi=" + ydpi);  
  25. Log.e(TAG + "  DisplayMetrics""density=" + density + "; densityDPI=" + densityDPI);  
  26. int screenWidthDip = dm.widthPixels;        // 螢幕寬(貌似恆為:320) 
  27. int screenHeightDip = dm.heightPixels;      // 螢幕寬(螢幕實際畫素高度/dm.density)
  28. Log.e(TAG + "  DisplayMetrics(222)""screenWidthDip=" + screenWidthDip + "; screenHeightDip=" + screenHeightDip);  
  29. screenWidth  = (int)(dm.widthPixels * density + 0.5f);      // 螢幕寬(px,如:480px)
  30. screenHeight = (int)(dm.heightPixels * density + 0.5f);     // 螢幕高(px,如:800px)
  31. Log.e(TAG + "  DisplayMetrics(222)""screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);  


結果如下:

[java] view plaincopyprint?
  1. E/== MyScreenActivity ===================================  getDefaultDisplay( 8509): screenWidth=320; screenHeight=533
  2. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): xdpi=156.3077; ydpi=157.51938
  3. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): density=1.0; densityDPI=160
  4. E/== MyScreenActivity ===================================  DisplayMetrics(111)( 8509): screenWidth=320; screenHeight=533
  5. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): xdpi=234.46153; ydpi=236.27907
  6. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): density=1.5; densityDPI=240
  7. E/== MyScreenActivity ===================================  DisplayMetrics(222)( 8509): screenWidthDip=320; screenHeightDip=533
  8. E/== MyScreenActivity ===================================  DisplayMetrics(222)( 8509): screenWidth=480; screenHeight=800

分析結果:

在onDraw()方法中

方法1和2,得到的結果都一致,均為320*533,明顯不是測試機i9000的螢幕大小

方法3,將方法1和2得到的結果,乘以density後,完美的480*800,perfect!

注: density 大於1的情況下,需要設定targetSdkVersion在4-9之間,例如
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="10" />

仔細分析程式碼,發現問題出在程式碼:

getWindowManager().getDefaultDisplay().getMetrics(dm)

Initialize a DisplayMetrics object from this display's data.

dm = getResources().getDisplayMetrics()

Return the current display metrics that are in effect for this resource object. The returned object should be treated as read-only.

補充知識:

而dip與px之間的換算關係是:
  pixs =dips * (densityDpi/160),也就是說當densityDpi=160時,1dip=1px
  sp: scaled pixels(放大畫素),sp的大小取決於系統metrics.scaledDensity值大小
  pt: point,是一個標準的長度單位,1pt=1/72英寸,用於印刷業(基本用不到)
  pt與px的換算關係:pixs = pt*xdpi * (1.0f/72);xdpi表示1英寸畫素個數
  in(英寸)長度單位(基本用不到)
  in與px的換算關係:pixs = in*xdpi
  mm(毫米)長度單位(基本用不到)
  mm與px的換算關係:pixs = mm * xdpi * (1.0f/25.4f)

還有一點:

其中dm.withPixels和dm.heightPixels得到的寬度和高度值都是以寬度為320為標準的,也就是說,不管你的螢幕是什麼解析度,寬度都會得到320,而高度就根據比例寬高比例計算,所以在我的Milestone上(480X854)得到的寬高為320X569,如果要得到真實的解析度,就必須乘以dm.density,這個值是因硬體解析度而異的,如果是螢幕硬體寬為320畫素,那麼這個值就是1,如果是480,這個值就是480/320,就是1.5(關於dm.density這個值還有一種說法:dm.density是當前顯示螢幕的densityDPI/160不過個人認為得到的數值是一樣的)。

  要想使dm.withPixels與dm.heightPixels顯示螢幕正確的解析度只要加上

<uses-sdk android:minSdkVersion="4" /> 就可以了。

因為,因為android剛開始時預設的density是1.0 ,加入android:minSdkVersion後貌似可以使density得到當前手機真正的density值。