关于dpi:在android中以编程方式获取屏幕密度?

getting the screen density programmatically in android?

如何在android中以编程方式获取屏幕密度?

我的意思是:如何找到当前设备的屏幕dpi?


您可以从DisplayMetrics结构中获取显示信息:

1
DisplayMetrics metrics = getResources().getDisplayMetrics();

虽然Android不使用直接像素映射,但它使用少量量化的密度独立像素值,然后缩放到实际屏幕大小。因此metrics.densityDpi属性将是DENSITY_xxx常量之一(120160213240320480640 dpi)。

如果您需要实际的lcd像素密度(可能是OpenGL应用程序),您可以分别从metrics.xdpimetrics.ydpi属性获取水平和垂直密度。

如果您的目标API级别早于4. metrics.density属性是参考密度(160dpi)的浮点缩放系数。现在可以计算metrics.densityDpi提供的相同值

1
int densityDpi = (int)(metrics.density * 160f);


这也有效:

1
 getResources().getDisplayMetrics().density;

这会给你:

0.75 - ldpi

1.0 - mdpi

1.5 - hdpi

2.0 - xhdpi

3.0 - xxhdpi

4.0 - xxxhdpi

enter image description here

ref:密度


1
2
3
4
5
6
7
8
9
10
11
12
13
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级别4及更高级别。


Blundell作为静态辅助方法的答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private static String getDensityName(Context context) {
    float density = context.getResources().getDisplayMetrics().density;
    if (density >= 4.0) {
        return"xxxhdpi";
    }
    if (density >= 3.0) {
        return"xxhdpi";
    }
    if (density >= 2.0) {
        return"xhdpi";
    }
    if (density >= 1.5) {
        return"hdpi";
    }
    if (density >= 1.0) {
        return"mdpi";
    }
    return"ldpi";
}


试试这个:

1
2
DisplayMetrics dm = context.getResources().getDisplayMetrics();
int densityDpi = dm.densityDpi;


要获得dpi:

1
2
3
4
5
6
7
8
9
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);

// will either be DENSITY_LOW, DENSITY_MEDIUM or DENSITY_HIGH
int dpiClassification = dm.densityDpi;

// these will return the actual dpi horizontally and vertically
float xDpi = dm.xdpi;
float yDpi = dm.ydpi;


以下答案是基于qwertzguy答案的小改进。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
double density = getResources().getDisplayMetrics().density;
if (density >= 4.0) {
   //"xxxhdpi";
}
else if (density >= 3.0 && density < 4.0) {
   //xxhdpi
}
else if (density >= 2.0) {
   //xhdpi
}
else if (density >= 1.5 && density < 2.0) {
   //hdpi
}
else if (density >= 1.0 && density < 1.5) {
   //mdpi
}


以下是密度常数,来源:

enter image description here

除标准密度外,还有5种中间密度。考虑到这一事实,以下代码将是一个完整的工作示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
float density = getResources().getDisplayMetrics().density;

if (density == 0.75f)
{
    // LDPI
}
else if (density >= 1.0f && density < 1.5f)
{
    // MDPI
}
else if (density == 1.5f)
{
    // HDPI
}
else if (density > 1.5f && density <= 2.0f)
{
    // XHDPI
}
else if (density > 2.0f && density <= 3.0f)
{
    // XXHDPI
}
else
{
    // XXXHDPI
}

或者,您可以使用densityDpi找到密度常数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int densityDpi = getResources().getDisplayMetrics().densityDpi;

switch (densityDpi)
{
    case DisplayMetrics.DENSITY_LOW:
        // LDPI
        break;

    case DisplayMetrics.DENSITY_MEDIUM:
        // MDPI
        break;

    case DisplayMetrics.DENSITY_TV:
    case DisplayMetrics.DENSITY_HIGH:
        // HDPI
        break;

    case DisplayMetrics.DENSITY_XHIGH:
    case DisplayMetrics.DENSITY_280:
        // XHDPI
        break;

    case DisplayMetrics.DENSITY_XXHIGH:
    case DisplayMetrics.DENSITY_360:
    case DisplayMetrics.DENSITY_400:
    case DisplayMetrics.DENSITY_420:
        // XXHDPI
        break;

    case DisplayMetrics.DENSITY_XXXHIGH:
    case DisplayMetrics.DENSITY_560:
        // XXXHDPI
        break;
}

Actualy如果你想拥有真正的显示dpi,答案就在两者之间
如果您查询显示指标:

1
2
3
4
5
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int dpiClassification = dm.densityDpi;
float xDpi = dm.xdpi;
float yDpi = dm.ydpi;

densityDpi * 160将为您提供应使用的密度值/建议

1
2
3
4
5
6
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:
例:

1
2
3
4
5
6
7
8
9
10
Device: Sony ericsson xperia mini pro (SK17i)
Density: 1.0 (e.g. suggests you use 160dpi resources)
xdpi: 193.5238
Real device ppi is arround 193ppi


Device: samsung GT-I8160 (Samsung ace 2)
Density 1.5 (e.g. suggests you use 240dpi resources)
xdpi 160.42105
Real device ppi is arround 246ppi

所以也许显示器的真正dpi应该是Density * xdpi ..但是我不确定这是否是正确的方法!


这应该对你的活动有所帮助......

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void printSecreenInfo(){

    Display display = getWindowManager().getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics(metrics);

    Log.i(TAG,"density :" +  metrics.density);

    // density interms of dpi
    Log.i(TAG,"D density :" +  metrics.densityDpi);

    // horizontal pixel resolution
    Log.i(TAG,"width pix :" +  metrics.widthPixels);

     // actual horizontal dpi
    Log.i(TAG,"xdpi :" +  metrics.xdpi);

    // actual vertical dpi
    Log.i(TAG,"ydpi :" +  metrics.ydpi);

}

输出:

1
2
3
4
5
6
7
8
9
I/test( 1044): density :1.0

I/test( 1044): D density :160

I/test( 1044): width pix :800

I/test( 1044): xdpi :160.0

I/test( 1044): ydpi :160.42105

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static String getDensity(Context context) {
    String r;
    DisplayMetrics metrics = new DisplayMetrics();

    if (!(context instanceof Activity)) {
        r ="hdpi";
    } else {
        Activity activity = (Activity) context;
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

        if (metrics.densityDpi <= DisplayMetrics.DENSITY_LOW) {
            r ="ldpi";
        } else if (metrics.densityDpi <= DisplayMetrics.DENSITY_MEDIUM) {
            r ="mdpi";
        } else {
            r ="hdpi";
        }
    }

    return r;
}


如果要从服务中检索密度,它的工作方式如下:

1
2
3
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);


还有一个答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* @return"ldpi","mdpi","hdpi","xhdpi","xhdpi","xxhdpi","xxxhdpi","tvdpi", or"unknown".
*/
public static String getDensityBucket(Resources resources) {
    switch (resources.getDisplayMetrics().densityDpi) {
        case DisplayMetrics.DENSITY_LOW:
            return"ldpi";
        case DisplayMetrics.DENSITY_MEDIUM:
            return"mdpi";
        case DisplayMetrics.DENSITY_HIGH:
            return"hdpi";
        case DisplayMetrics.DENSITY_XHIGH:
            return"xhdpi";
        case DisplayMetrics.DENSITY_XXHIGH:
            return"xxhdpi";
        case DisplayMetrics.DENSITY_XXXHIGH:
            return"xxxhdpi";
        case DisplayMetrics.DENSITY_TV:
            return"tvdpi";
        default:
            return"unknown";
    }
}

这应该工作。

1
2
3
4
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels; //320
int height = dm.heightPixels; //480


你应该试试这个。刚添加了一个可以找到并显示Toast的方法。设备落入哪个类别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
public static int differentDensityAndScreenSize(Context context) {
  int value = 20;
  String str ="";
  if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {
   switch (context.getResources().getDisplayMetrics().densityDpi) {
   case DisplayMetrics.DENSITY_LOW:
    str ="small-ldpi";
    value = 20;
    break;
   case DisplayMetrics.DENSITY_MEDIUM:
    str ="small-mdpi";
    value = 20;
    break;
   case DisplayMetrics.DENSITY_HIGH:
    str ="small-hdpi";
    value = 20;
    break;
   case DisplayMetrics.DENSITY_XHIGH:
    str ="small-xhdpi";
    value = 20;
    break;
   case DisplayMetrics.DENSITY_XXHIGH:
    str ="small-xxhdpi";
    value = 20;
    break;
   case DisplayMetrics.DENSITY_XXXHIGH:
    str ="small-xxxhdpi";
    value = 20;
    break;
   case DisplayMetrics.DENSITY_TV:
    str ="small-tvdpi";
    value = 20;
    break;
   default:
    str ="small-unknown";
    value = 20;
    break;
   }

  } else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
   switch (context.getResources().getDisplayMetrics().densityDpi) {
   case DisplayMetrics.DENSITY_LOW:
    str ="normal-ldpi";
    value = 82;
    break;
   case DisplayMetrics.DENSITY_MEDIUM:
    str ="normal-mdpi";
    value = 82;
    break;
   case DisplayMetrics.DENSITY_HIGH:
    str ="normal-hdpi";
    value = 82;
    break;
   case DisplayMetrics.DENSITY_XHIGH:
    str ="normal-xhdpi";
    value = 90;
    break;
   case DisplayMetrics.DENSITY_XXHIGH:
    str ="normal-xxhdpi";
    value = 96;
    break;
   case DisplayMetrics.DENSITY_XXXHIGH:
    str ="normal-xxxhdpi";
    value = 96;
    break;
   case DisplayMetrics.DENSITY_TV:
    str ="normal-tvdpi";
    value = 96;
    break;
   default:
    str ="normal-unknown";
    value = 82;
    break;
   }
  } else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
   switch (context.getResources().getDisplayMetrics().densityDpi) {
   case DisplayMetrics.DENSITY_LOW:
    str ="large-ldpi";
    value = 78;
    break;
   case DisplayMetrics.DENSITY_MEDIUM:
    str ="large-mdpi";
    value = 78;
    break;
   case DisplayMetrics.DENSITY_HIGH:
    str ="large-hdpi";
    value = 78;
    break;
   case DisplayMetrics.DENSITY_XHIGH:
    str ="large-xhdpi";
    value = 125;
    break;
   case DisplayMetrics.DENSITY_XXHIGH:
    str ="large-xxhdpi";
    value = 125;
    break;
   case DisplayMetrics.DENSITY_XXXHIGH:
    str ="large-xxxhdpi";
    value = 125;
    break;
   case DisplayMetrics.DENSITY_TV:
    str ="large-tvdpi";
    value = 125;
    break;
   default:
    str ="large-unknown";
    value = 78;
    break;
   }

  } else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
   switch (context.getResources().getDisplayMetrics().densityDpi) {
   case DisplayMetrics.DENSITY_LOW:
    str ="xlarge-ldpi";
    value = 125;
    break;
   case DisplayMetrics.DENSITY_MEDIUM:
    str ="xlarge-mdpi";
    value = 125;
    break;
   case DisplayMetrics.DENSITY_HIGH:
    str ="xlarge-hdpi";
    value = 125;
    break;
   case DisplayMetrics.DENSITY_XHIGH:
    str ="xlarge-xhdpi";
    value = 125;
    break;
   case DisplayMetrics.DENSITY_XXHIGH:
    str ="xlarge-xxhdpi";
    value = 125;
    break;
   case DisplayMetrics.DENSITY_XXXHIGH:
    str ="xlarge-xxxhdpi";
    value = 125;
    break;
   case DisplayMetrics.DENSITY_TV:
    str ="xlarge-tvdpi";
    value = 125;
    break;
   default:
    str ="xlarge-unknown";
    value = 125;
    break;
   }
  }
// The Toast will show the Device falls in Which Categories.
Toast.makeText(MainActivity.this,""+str, Toast.LENGTH_SHORT).show();

  return value;
 }

http://www.androidwarriors.com/2016/01/how-to-find-different-devices-screen.html


我使用以下代码从模块访问DPI(无需访问上下文对象):

1
2
(Resources.getSystem().getDisplayMetrics().xdpi
Resources.getSystem().getDisplayMetrics().ydpi)/2


试试这个...

在kotlin

1
2
3
4
5
6
7
8
9
10
11
fun determineScreenDensityCode(): String {
      return when (resources.displayMetrics.densityDpi) {
         DisplayMetrics.DENSITY_LOW ->"ldpi"
         DisplayMetrics.DENSITY_MEDIUM ->"mdpi"
         DisplayMetrics.DENSITY_HIGH ->"hdpi"
         DisplayMetrics.DENSITY_XHIGH, DisplayMetrics.DENSITY_280 ->"xhdpi"
         DisplayMetrics.DENSITY_XXHIGH, DisplayMetrics.DENSITY_360, DisplayMetrics.DENSITY_400, DisplayMetrics.DENSITY_420 ->"xxhdpi"
         DisplayMetrics.DENSITY_XXXHIGH, DisplayMetrics.DENSITY_560 ->"xxxhdpi"
         else ->"Unknown code ${resources.displayMetrics.densityDpi}"
     }
}

你可以通过println("density: ${determineScreenDensityCode()}")打电话
输出将是System.out: density: xxxhdpi