Чи є спосіб програмно визначити, чи пристрій, на якому встановлена програма, є 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, ми зазвичай воліємо працювати в пікселях, що не залежать від щільності.
Ви отримуєте density
на екрані , використовуючи metrics
знову ж , у вигляді масштабного коефіцієнта для пристрою, яке засноване на Android Design ресурсів для mdpi
, і hdpi
т.д.
float scaleFactor = metrics.density;
З цього результату ми можемо розрахувати кількість незалежних від щільності пікселів для певної висоти або ширини.
float widthDp = widthPixels / scaleFactor
float heightDp = heightPixels / scaleFactor
Результат, який ви отримаєте від цього, допоможе вам визначитися з типом екрану, з яким ви працюєте, разом із прикладами конфігурації Android , які дають вам відносний dp для кожного розміру екрана:
- 320dp: типовий екран телефону (240x320 ldpi, 320x480 mdpi, 480x800 hdpi тощо).
- 480 dp: твінер-планшет типу Streak (480x800 mdpi).
- 600 dp: 7-дюймовий планшет (600x1024 mdpi).
- 720dp: 10-дюймовий планшет (720x1280 mdpi, 800x1280 mdpi тощо).
Використовуючи вищенаведену інформацію, ми знаємо, що якщо найменша ширина пристрою перевищує 600dp, то пристрій - це 7-дюймовий планшет, якщо він більший за 720dp, то пристрій - це 10-дюймовий планшет.
Ми можемо обробити найменшу ширину, використовуючи min
функцію Math
class, передаючи символи 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
В іншому випадку, якщо ви можете собі це дозволити, скористайтеся наступним методом, який є дуже точним підходом для виявлення 600dp (наприклад, 6 ") проти 720dp (як 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) Потім у коді, наприклад, Діяльність, тестуйте відповідно:
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 розрахунки з використанням згаданих вище показників виключають розміри панелі навігації. Ще деякі дослідження привели мене до відповіді Френка Нгуєна, який використовує різні методи, які дадуть вам вихідні (або реальні) розміри пікселів екрану. Моє первинне тестування показало, що наступний код від виправлення Френка повідомляє розміри на 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 вказує розмір екрану через чотири узагальнених розмірів: маленьких , нормальних , великих і XLarge .
Хоча в документації Android зазначено, що групи розмірів застаріли
... ці групи розмірів застаріли на користь нової техніки управління розмірами екрану на основі доступної ширини екрана. Якщо ви розробляєте для Android 3.2 та новіших версій, див. [Декларування макетів планшетів для Android 3.2] (hdpi (висока) ~ 240dpi) для отримання додаткової інформації.
Зазвичай кваліфікатор розміру large визначає 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 дюймів, але ми можемо зробити це на будь-якому пристрої, використовуючи папку значень.
як створити папку different-2 values для різних-2 пристроїв. Але це залежить від вимоги.
Вам доведеться зробити трохи обчислень, використовуючи дані класу DisplayMetrics .
У вас є heightPixel і widthPixels (роздільна здатність екрана в пікселях)
Вам потрібна діагональ, оскільки "розмір дюймового екрану" завжди описує довжину діагоналі. Ви можете отримати діагональ екрану в пікселях (за допомогою піфагора)
diagonalPixel = √ (heightPixel² + widthPixels²)
тоді ви можете перетворити значення пікселя в дюйми завдяки значенню щільності DPI:
inchDiag = діагональPixel / щільність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 ("LARGE") {
// від 4 ~ 7 дюймів
} інакше якщо (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;
}
Ось кілька корисних розширень kotlin:
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()