Програмне виявлення 7-дюймового та 10-дюймового планшетів


93

Чи є спосіб програмно визначити, чи пристрій, на якому встановлена ​​програма, є 7-дюймовим або 10-дюймовим планшетом?


Наприклад: layout-sw600dp шукає найменший розмір ширини 600dp.
Rookie

Я це розумію, але що ви шукаєте програмно?
Geobits

Мені потрібно придбати ці пристрої програмно .. оскільки є деякі властивості, які я не можу визначити у xml..ці властивості визначені в самому коді .. тому якщо я просто покладу код, він застосовуватиметься до всіх пристроїв .. але Я цього не хочу ..
Новачок

@Raghav Ви спробували з матрицею відображення отримати розмір екрана, а потім можете порівняти. Хоча це не чистий спосіб, але ви можете використовувати.
PiyushMishra

Ви могли б отримати розміри екрану і працювати звідти ... stackoverflow.com/questions/1016896/…
Радж

Відповіді:


234

Ви можете використовувати, 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т.д. DPI ваги

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функцію Mathclass, передаючи символи 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
}

І ось як ви розраховуєте, з яким пристроєм ви працюєте.


3
Відмінні поради Шон. Раніше я перевіряв px на планшети, але в деяких випадках виникають проблеми (Galaxy 3, 4, Note, має рівні або більше px, ніж Nexus 7). Тепер я також можу перевірити на дюйм. Ось список багатьох популярних специфікацій екрану пристроїв: en.wikipedia.org/wiki/List_of_displays_by_pixel_density
Pelanes

8
Не використовуйте xdpi або ydpi. Вони є необов’язковими і встановлюються виробником, а не обчислюються. Вони часто або невикористані, або неточні.
sturrockad

2
Використовуючи ваш метод для отримання ширини в dpi, я отримую різні результати залежно від орієнтації. наприклад, для Nexus 7: ПОРТРЕТ: найменша ширина = 600,9; ПЕЙЗАЖ: найменшаШирина = 552,8; У чому причина цього?
Крістофер Массер,

3
Логіка if (smallestWidth > 600) { /* 7" */ } else if (smallestWidth > 720) { /* 10" */ }хибна: 10 "планшет розпізнається як 7". Я взяв на себе свободу це виправити.
Jonik

21
В кінці кінців я пішов з resources.getConfiguration().smallestScreenWidthDpвід відповіді Дєєва в який є єдиним методом , який дає таке ж значення як в портретному і альбомному на моєму Nexus 7 (600dp). Він був доданий до рівня API 13.
Jonik,

32

Немає нічого, що говорить 7"або 10"AFAIK. Існує приблизно два способи отримання розмірів екрану, які система використовує при декодуванні растрових зображень і не тільки. Вони обидва знайдені в Resourcesоб'єкті програми, знайденому в Context.

Перший - це Configurationоб’єкт, який можна отримати getContext().getResources().getConfiguration(). У ньому ви маєте:

Configuration#densityDpi - цільова щільність екрану, на яку відображається, що відповідає кваліфікатору ресурсу щільності.

Configuration#screenHeightDp - Поточна висота доступного простору екрану в dp одиницях, що відповідає кваліфікатору ресурсу висоти екрану.

Configuration#screenWidthDp - Поточна ширина доступного екранного простору в dp одиницях, що відповідає кваліфікатору ресурсу ширини екрана.

Configuration#smallestScreenWidthDp - Найменший розмір екрана, який програма побачить у звичайній роботі, відповідає найменшому класифікатору ресурсу ширини екрана.

При тому, що ви можете в значній мірі використовувати принципи екрану , щоб з'ясувати , якщо пристрій витягує з відповідних спеціалізованих папок ресурсів ( hdpi, xhdpi, large, xlargeі т.д.).

Пам’ятайте, ось деякі сегменти:

  • великі екрани мають принаймні 960dp x 720dp
  • великі екрани мають принаймні 640dp x 480dp
  • нормальні екрани не менше 470dp x 320dp
  • маленькі екрани мають принаймні 426dp x 320dp

  • 320dp: типовий екран телефону (240x320 ldpi, 320x480 mdpi, 480x800 hdpi тощо).

  • 480 dp: твінер-планшет типу Streak (480x800 mdpi).
  • 600 dp: 7-дюймовий планшет (600x1024 mdpi).
  • 720dp: 10-дюймовий планшет (720x1280 mdpi, 800x1280 mdpi тощо).

Більше інформації

Другий - це DisplayMetricsоб’єкт, отриманий getContext().getResources().getDisplayMetrics(). У тому, що у вас є:

DisplayMetrics#density - Логічна щільність відображення.

DisplayMetrics#densityDpi - Щільність екрана, виражена у вигляді точок на дюйм.

DisplayMetrics#heightPixels - Абсолютна висота відображення в пікселях.

DisplayMetrics#widthPixels - Абсолютна ширина дисплея в пікселях.

DisplayMetrics#xdpi - Точні фізичні пікселі на дюйм екрану в розмірі X.

DisplayMetrics#ydpi - Точні фізичні пікселі на дюйм екрану в вимірі Y.

Це зручно, якщо вам потрібна точна кількість пікселів на екрані, а не щільність. Однак важливо зазначити, що це всі пікселі екрана. Не тільки доступні вам.


4
+1, я отримую найкращі результати за допомогою smallestScreenWidthDp. На відміну від інших рішень, це дає таке ж значення на моєму Nexus 7 (600dp) незалежно від орієнтації . Як бонус, це також найпростіший код!
Jonik

1
Я думаю, що це продовжує залишатися найкращим способом, оскільки він повинен збігатися з позначенням sw ??? dp на шляхах ресурсів. Важлива послідовність.
lilbyrdie

13

помістіть цей метод у 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 дюймів.


8

Вищезазначене не завжди спрацьовує при переключенні портрета на альбом.

Якщо ви націлюєтеся на рівень 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();
}

4
Вам не потрібно створювати окремий макет, я вважаю, що ви можете просто мати окремий strings.xml залежно від розміру, маючи різні папки значень, наприклад values-sw600dp тощо. Визначте рядок <string name = 'screensize' > 600dp </string> у папці sw600dp тощо. Це навіть не повинно бути рядком, це може бути в ints.xml або dimens.xml.
ajacian81

7

Чудова інформація, саме те, що я шукав! Однак, випробувавши це, я виявив, що при використанні згаданих тут показників 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();
}

3

У мене є два пристрої для 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);

детальніше дивіться тут ..


2

Вони так , що 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);

2

Ви можете скористатися наведеним нижче способом, щоб отримати розмір екрану в дюймах, виходячи з цього, ви просто можете перевірити, який планшет або телефон є пристроєм.

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;
}

2

Я зберігав значення у папці значень що дає мені екран 7 дюймів або 10 дюймів, але ми можемо зробити це на будь-якому пристрої, використовуючи папку значень.

як створити папку different-2 values ​​для різних-2 пристроїв. Але це залежить від вимоги.


1

Вам доведеться зробити трохи обчислень, використовуючи дані класу DisplayMetrics .

У вас є heightPixel і widthPixels (роздільна здатність екрана в пікселях)

Вам потрібна діагональ, оскільки "розмір дюймового екрану" завжди описує довжину діагоналі. Ви можете отримати діагональ екрану в пікселях (за допомогою піфагора)

diagonalPixel = √ (heightPixel² + widthPixels²)

тоді ви можете перетворити значення пікселя в дюйми завдяки значенню щільності DPI:

inchDiag = діагональPixel / щільністьDPI.

Сподіваюся, я тут не припустився помилок, маючи на увазі, що значення, які ви отримуєте з класу DisplayMetrics, задаються конструктором, виявляється (у дуже рідкісних випадках), що вони невдало встановлені відповідно до фізичного матеріалу ...

Це дасть вам фізичний розмір екрану, але це, мабуть, не найкращий спосіб керувати кількома макетами. Більше на цю тему


1

Інший спосіб:

  • Створіть ще 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

Вуаля! 😀 Це все, що вам потрібно, щоб відрізнити планшети від телефонів

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;
}

0

Ось кілька корисних розширень 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
    }

Це працює! Але слід використовувати належні DisplayMetrics, наприклад, з Resourcesin Context: resources.displayMetrics.isTablet() або з WindowManagerякого зберігається в Activity: val displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getMetrics(displayMetrics) displayMetrics.isTablet()
Akbolat SSS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.