الحصول على كثافة الشاشة برمجيا في Android؟
-
02-10-2019 - |
سؤال
كيفية الحصول على كثافة الشاشة برمجيا في Android؟
أعني: كيف تجد شاشة DPI للجهاز الحالي؟
المحلول
يمكنك الحصول على معلومات على الشاشة من DisplayMetrics الهيكل:
DisplayMetrics metrics = getResources().getDisplayMetrics();
على الرغم من أن Android لا يستخدم رسم خرائط للبكسل المباشر ، إلا أنه يستخدم حفنة من قيم بكسل مستقلة الكثافة الكمية ثم يتم تحديدها إلى حجم الشاشة الفعلي. لذلك metrics.densityDpi
ستكون الممتلكات واحدة من DENSITY_xxx
الثوابت (120
, 160
, 213
, 240
, 320
, 480
أو 640
DPI).
إذا كنت بحاجة إلى فِعلي كثافة بكسل LCD (ربما لتطبيق OpenGL) يمكنك الحصول عليها من metrics.xdpi
و metrics.ydpi
خصائص الكثافة الأفقية والرأسية على التوالي.
إذا كنت تستهدف مستويات واجهة برمجة التطبيقات قبل 4. metrics.density
الخاصية هي عامل تحجيم النقطة العائمة من الكثافة المرجعية (160dpi). نفس القيمة المقدمة الآن بواسطة metrics.densityDpi
يمكن حسابها
int densityDpi = (int)(metrics.density * 160f);
نصائح أخرى
هذا يعمل أيضًا:
getResources().getDisplayMetrics().density;
هذا سوف يعطيك:
0.75 - LDPI
1.0 - MDPI
1.5 - HDPI
2.0 - XHDPI
3.0 - XXHDPI
4.0 - XXXHDPI
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 وأعلى.
بلونديل الإجابة كطريقة مساعدة ثابتة:
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";
}
جرب هذا:
DisplayMetrics dm = context.getResources().getDisplayMetrics();
int densityDpi = dm.densityDpi;
للحصول على DPI:
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;
هنا ثوابت الكثافة ، مصدر:
هناك ، بالإضافة إلى الكثافة القياسية ، 5 منها وسيطة. مع الأخذ في الاعتبار هذه الحقيقة ، سيكون الرمز التالي مثالًا كاملًا للعمل:
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
:
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;
}
الجواب التالي هو تحسن بسيط يعتمد على إجابة Qwertzguy.
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
}
الفعلي إذا كنت تريد الحصول على عرض حقيقي DPI الجواب في مكان ما إذا كنت تستفسر عن مقاييس العرض:
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int dpiClassification = dm.densityDpi;
float xDpi = dm.xdpi;
float yDpi = dm.ydpi;
سوف يعطيك Densydpi * 160 القيم/الاقتراح التي يجب أن تستخدمها
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
لن تعطيك دائما DPI الحقيقي من العرض المعطى: مثال:
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 الحقيقية للعرض كثافة*XDPI .. لكنني لست متأكدًا مما إذا كانت هذه هي الطريقة الصحيحة للقيام بها!
هذا يجب أن يساعد في نشاطك ...
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);
}
انتاج :
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
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;
}
إذا كنت ترغب في استرداد الكثافة من الخدمة ، فإنها تعمل على هذا النحو:
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
هذا يجب أن يعمل.
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels; //320
int height = dm.heightPixels; //480
إجابة أخرى:
/**
* @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";
}
}
يجب أن تجرب هذا. فقط أضافت طريقة ستجد وتظهر الخبز المحمص. هذا في أي فئة يسقط الجهاز.
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
جرب هذا...
في كوتلين
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
أنا أستخدم التعليمات البرمجية التالية للوصول إلى DPI من الوحدات النمطية (لا حاجة للوصول إلى كائن سياق):
(Resources.getSystem().getDisplayMetrics().xdpi
Resources.getSystem().getDisplayMetrics().ydpi)/2