Есть ли способ программно определить, на каком устройстве установлено приложение: 7-дюймовый планшет или 10-дюймовый?
Есть ли способ программно определить, на каком устройстве установлено приложение: 7-дюймовый планшет или 10-дюймовый?
Ответы:
Вы можете использовать DisplayMetrics
для получения большого количества информации об экране, на котором работает ваше приложение.
Сначала мы создаем DisplayMetrics
объект метрики:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Отсюда мы можем получить информацию, необходимую для определения размера дисплея:
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;
Это вернет абсолютное значение ширины и высоты в пикселях, поэтому 1280x720 для Galaxy SIII, Galaxy Nexus и т. Д.
Само по себе это обычно не помогает, поскольку, когда мы работаем с устройствами Android, мы обычно предпочитаем работать с пикселями, независимыми от плотности, dip.
Вы снова получаете изображение density
экрана metrics
в виде масштабного коэффициента для устройства, который основан на ресурсах дизайна Android для mdpi
и hdpi
т. Д.
float scaleFactor = metrics.density;
Исходя из этого результата, мы можем вычислить количество независимых от плотности пикселей для определенной высоты или ширины.
float widthDp = widthPixels / scaleFactor
float heightDp = heightPixels / scaleFactor
Результат, который вы получите, поможет вам решить, с каким типом экрана вы работаете, в сочетании с примерами конфигурации Android , которые дают вам относительный dp для каждого размера экрана:
- 320dp: обычный экран телефона (240x320 ldpi, 320x480 mdpi, 480x800 hdpi и т. Д.).
- 480dp: анимационный планшет, такой как Streak (480x800 mdpi).
- 600dp: 7-дюймовый планшет (600x1024 mdpi).
- 720dp: 10-дюймовый планшет (720x1280 mdpi, 800x1280 mdpi и т. Д.).
Используя приведенную выше информацию, мы знаем, что если наименьшая ширина устройства больше 600 dp, устройство является 7-дюймовым планшетом, если оно больше 720 dp, устройством является 10-дюймовый планшет.
Мы можем определить наименьшую ширину, используя min
функцию Math
класса, передавая heightDp
и widthDp
возвращая smallestWidth
.
float smallestWidth = Math.min(widthDp, heightDp);
if (smallestWidth > 720) {
//Device is a 10" tablet
}
else if (smallestWidth > 600) {
//Device is a 7" tablet
}
Однако это не всегда дает вам точное совпадение, особенно при работе с малоизвестными планшетами, которые могут неверно отображать свою плотность как hdpi, когда это не так, или это может быть только 800 x 480 пикселей, но все еще отображаться на 7-дюймовом экране. .
В дополнение к этим методам, если вам когда-либо понадобится узнать точные размеры устройства в дюймах, вы также можете решить это, используя metrics
метод определения количества пикселей на дюйм экрана.
float widthDpi = metrics.xdpi;
float heightDpi = metrics.ydpi;
Вы можете использовать сведения о том, сколько пикселей находится на каждом дюйме устройства, и общее количество пикселей, чтобы определить, сколько дюймов на устройстве.
float widthInches = widthPixels / widthDpi;
float heightInches = heightPixels / heightDpi;
Это вернет высоту и ширину устройства в дюймах. Это опять же не всегда полезно для определения типа устройства, поскольку заявленный размер устройства - это диагональ, а все, что у нас есть, - это высота и ширина.
Однако мы также знаем, что, учитывая высоту треугольника и ширину, мы можем использовать теорему Пифагора, чтобы вычислить длину гипотенузы (в данном случае размер диагонали экрана).
//a² + b² = c²
//The size of the diagonal in inches is equal to the square root of the height in inches squared plus the width in inches squared.
double diagonalInches = Math.sqrt(
(widthInches * widthInches)
+ (heightInches * heightInches));
Исходя из этого, мы можем выяснить, является ли устройство планшетом:
if (diagonalInches >= 10) {
//Device is a 10" tablet
}
else if (diagonalInches >= 7) {
//Device is a 7" tablet
}
Вот как вы рассчитываете, с каким устройством вы работаете.
if (smallestWidth > 600) { /* 7" */ } else if (smallestWidth > 720) { /* 10" */ }
ошибочная: 10 "планшет распознается как 7". Я взял на себя смелость исправить это.
resources.getConfiguration().smallestScreenWidthDp
от ответа Деева в который является единственным методом , который дает такое же значение как в портретном и альбомном на моем Nexus 7 (600dp). Он был добавлен на уровне API 13.
Нет ничего, что говорит 7"
или 10"
AFAIK. Есть примерно два способа получить размеры экрана, которые система использует при декодировании растровых изображений и т. Д. Оба они находятся в Resources
объекте приложения, находящемся в Context
.
Первый - это Configuration
объект, который можно получить с помощью getContext().getResources().getConfiguration()
. В нем у вас есть:
Configuration#densityDpi
- Целевая плотность экрана, для которой выполняется рендеринг, соответствующая квалификатору ресурса плотности.
Configuration#screenHeightDp
- Текущая высота доступного пространства экрана в единицах dp, соответствующая квалификатору ресурса высоты экрана.
Configuration#screenWidthDp
- Текущая ширина доступного пространства экрана в единицах dp, соответствующая квалификатору ресурса ширины экрана.
Configuration#smallestScreenWidthDp
- Наименьший размер экрана, который приложение будет видеть при нормальной работе, соответствует квалификатору ресурса наименьшей ширины экрана.
При том, что вы можете в значительной степени использовать принципы экрана , чтобы выяснить , если устройство вытягивает из соответствующих специализированных папок ресурсов ( hdpi
, xhdpi
, large
, xlarge
и т.д.).
Помните, что это некоторые из ведер:
маленькие экраны: не менее 426dp x 320dp
320dp: обычный экран телефона (240x320 ldpi, 320x480 mdpi, 480x800 hdpi и т. Д.).
Второй - DisplayMetrics
объект, полученный с помощью getContext().getResources().getDisplayMetrics()
. В этом у вас есть:
DisplayMetrics#density
- Логическая плотность отображения.
DisplayMetrics#densityDpi
- Плотность экрана в точках на дюйм.
DisplayMetrics#heightPixels
- Абсолютная высота дисплея в пикселях.
DisplayMetrics#widthPixels
- Абсолютная ширина дисплея в пикселях.
DisplayMetrics#xdpi
- Точное количество физических пикселей на дюйм экрана по оси X.
DisplayMetrics#ydpi
- Точное количество физических пикселей на дюйм экрана по оси Y.
Это удобно, если вам нужно точное количество пикселей экрана, а не плотность. Однако важно отметить, что это все пиксели экрана. Не только те, которые вам доступны.
smallestScreenWidthDp
. В отличие от других решений, он дает такое же значение на моем Nexus 7 (600dp) независимо от ориентации . В качестве бонуса это еще и самый простой код!
поместите этот метод в onResume () и можете проверить.
public double tabletSize() {
double size = 0;
try {
// Compute screen size
DisplayMetrics dm = context.getResources().getDisplayMetrics();
float screenWidth = dm.widthPixels / dm.xdpi;
float screenHeight = dm.heightPixels / dm.ydpi;
size = Math.sqrt(Math.pow(screenWidth, 2) +
Math.pow(screenHeight, 2));
} catch(Throwable t) {
}
return size;
}
обычно таблетки начинаются после 6 дюймов.
Вышеупомянутое не всегда работает при переключении портрета на пейзаж.
Если вы ориентируетесь на уровень API 13+, это просто, как описано выше - используйте Configuration.smallestScreenWidthDp, затем протестируйте соответственно:
resources.getConfiguration().smallestScreenWidthDp
В противном случае, если вы можете себе это позволить, используйте следующий метод, который является очень точным подходом для обнаружения 600 dp (например, 6 дюймов) по сравнению с 720 dp (например, 10 дюймов), позволяя системе сообщать вам:
1) Добавьте в layout-sw600dp и layout-sw720dp (и, если применимо, его ландшафт) невидимый вид с правильным идентификатором, например:
Для 720, на layout-sw720dp:
<View android:id="@+id/sw720" android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>
Для 600, на layout-sw600dp:
<View android:id="@+id/sw600" android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>
2) Затем в коде, например, Activity, протестируйте соответственно:
private void showFragment() {
View v600 = (View) findViewById(R.id.sw600);
View v720 = (View) findViewById(R.id.sw720);
if (v600 != null || v720 !=null)
albumFrag = AlbumGridViewFragment.newInstance(albumRefresh);
else
albumFrag = AlbumListViewFragment.newInstance(albumRefresh);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.view_container, albumFrag)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
}
Отличная информация, именно то, что я искал! Однако, попробовав это, я обнаружил, что при использовании упомянутых здесь показателей Nexus 7 (модель 2012 года) имеет размеры 1280x736. У меня также есть Motorola Xoom с Jelly Bean, и он неверно сообщает о разрешении 1280x752. Я наткнулся на этот пост здесь , что подтверждает это. По сути, в ICS / JB вычисления с использованием упомянутых выше показателей исключают размеры панели навигации. Еще несколько исследований привели меня к ответу Фрэнка Нгуена, который использует различные методы, которые дадут вам необработанные (или реальные) пиксельные размеры экрана. Мое первоначальное тестирование показало, что следующий код от Frank correclty сообщает размеры Nexus 7 (модель 2012 года с JB) и моего Motorola Xoom с JB:
int width = 0, height = 0;
final DisplayMetrics metrics = new DisplayMetrics();
Display display = getWindowManager().getDefaultDisplay();
Method mGetRawH = null, mGetRawW = null;
try {
// For JellyBeans and onward
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
display.getRealMetrics(metrics);
width = metrics.widthPixels;
height = metrics.heightPixels;
} else {
mGetRawH = Display.class.getMethod("getRawHeight");
mGetRawW = Display.class.getMethod("getRawWidth");
try {
width = (Integer) mGetRawW.invoke(display);
height = (Integer) mGetRawH.invoke(display);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (NoSuchMethodException e3) {
e3.printStackTrace();
}
У меня два устройства Android с одинаковым разрешением
Устройство1 -> разрешение 480x800, размер диагонали экрана -> 4,7 дюйма
Device2 -> разрешение 480x800, размер диагонали экрана -> 4,0 дюйма
Это дает оба устройства диагональю экрана -> 5,8
решение вашей проблемы ...
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width=dm.widthPixels;
int height=dm.heightPixels;
int dens=dm.densityDpi;
double wi=(double)width/(double)dens;
double hi=(double)height/(double)dens;
double x = Math.pow(wi,2);
double y = Math.pow(hi,2);
double screenInches = Math.sqrt(x+y);
см подробности здесь ..
Таким образом, Android определяет размеры экрана с помощью четырех общих размеров: маленький , нормальный , большой и большой .
Хотя в документации Android указано, что группы размеров устарели
... эти размерные группы не рекомендуются в пользу нового метода управления размерами экрана на основе доступной ширины экрана. Если вы разрабатываете для Android 3.2 и выше, см. [Объявление макетов планшета для Android 3.2] (hdpi (высокое) ~ 240 точек на дюйм) для получения дополнительной информации.
Как правило , размер отборочного больших специфицирует таблетка и размер Классификатор. 7" XLarge специфицирует 10" таблетки:
Приятная особенность срабатывания триггера по квалификатору размера заключается в том, что вы можете гарантировать, что ваши активы и код согласуются с тем, какой актив использовать или путь кода для активации.
Чтобы получить квалификатор размера в коде, выполните следующие вызовы:
int sizeLarge = SCREENLAYOUT_SIZE_LARGE // For 7" tablet
boolean is7InchTablet = context.getResources().getConfiguration()
.isLayoutSizeAtLeast(sizeLarge);
int sizeXLarge = SCREENLAYOUT_SIZE_XLARGE // For 10" tablet
boolean is10InchTablet = context.getResources().getConfiguration()
.isLayoutSizeAtLeast(sizeXLarge);
Вы можете использовать приведенный ниже метод, чтобы получить размер экрана в дюймах, исходя из этого, просто вы можете проверить, на каком планшете или телефоне находится устройство.
private static double checkDimension(Context context) {
WindowManager windowManager = ((Activity)context).getWindowManager();
Display display = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
// since SDK_INT = 1;
int mWidthPixels = displayMetrics.widthPixels;
int mHeightPixels = displayMetrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
try
{
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(display, realSize);
mWidthPixels = realSize.x;
mHeightPixels = realSize.y;
}
catch (Exception ignored) {}
DisplayMetrics dm = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(dm);
double x = Math.pow(mWidthPixels/dm.xdpi,2);
double y = Math.pow(mHeightPixels/dm.ydpi,2);
double screenInches = Math.sqrt(x+y);
Log.d("debug","Screen inches : " + screenInches);
return screenInches;
}
Я хранил значение в папке значений, которая дает мне экран 7 дюймов или 10 дюймов, но мы можем сделать это для любого устройства, используя папку значений.
например, создать папку с разными значениями 2 для устройств с разными значениями. Но это зависит от требований.
Вам нужно будет произвести небольшие вычисления, используя данные, предоставленные классом DisplayMetrics .
У вас есть heightPixel и widthPixels (разрешение экрана в пикселях)
Вам нужна диагональ, так как «размер экрана в дюймах» всегда описывает длину диагонали. Вы можете получить диагональ экрана в пикселях (используя pythagore)
diagonalPixel = √ (heightPixel² + widthPixel²)
то вы можете преобразовать значение пикселя в дюймы благодаря значению densityDPI:
inchDiag = диагональ пикселей / плотность DPI.
Надеюсь, я не ошибся здесь, имейте в виду, что значения, которые вы получаете из класса DisplayMetrics, задаются конструктором, оказывается (в очень редких случаях), что они не очень хорошо настроены в соответствии с физическим материалом ...
Это даст вам физический размер экрана, но, вероятно, это не лучший способ управлять несколькими макетами. Подробнее по этой теме
По-другому:
Создайте еще 2 папки: values-large + values-xlarge
Поместите: <string name="screentype">LARGE</string>
в папку с большими значениями (strings.xml)
Поместите: <string name="screentype">XLARGE</string>
в папку values-xlarge (strings.xml)
В коде:
Строка mType = getString (R.string.screentype);
if (mType! = null && mType.equals ("НАИБОЛЬШИЙ") {
// от 4 до 7 дюймов
} else if (mType! = null && mType.equals ("XLARGE") {
// от 7 ~ 10 дюймов
}
1. Вспомогательная функция для получения ширины экрана:
private float getScreenWidth() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
return Math.min(metrics.widthPixels, metrics.heightPixels) / metrics.density;
}
2. Функция определения того, является ли устройство планшетом.
boolean isTablet() {
return getScreenWidth() >= 600;
}
3. Наконец, если вы хотите выполнять разные операции для устройств разного размера:
boolean is7InchTablet() {
return getScreenWidth() >= 600 && getScreenWidth() < 720;
}
boolean is10InchTablet() {
return getScreenWidth() >= 720;
}
Вот несколько полезных расширений котлина:
fun DisplayMetrics.isTablet(): Boolean {
return screenWith() >= 600
}
fun DisplayMetrics.is7InchTablet(): Boolean {
return screenWith() >= 600 && screenWith() < 720
}
fun DisplayMetrics.is10InchTablet(): Boolean {
return screenWith() >= 720
}
fun DisplayMetrics.screenWith(): Float {
return widthPixels.coerceAtMost(heightPixels) / density
}
Resources
in Context
: resources.displayMetrics.isTablet()
или из WindowManager
которых хранится в Activity
: val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
displayMetrics.isTablet()