Планшет или телефон - Android

Есть ли способ проверить, пользуется ли пользователь планшетом или телефоном? У меня проблемы с функцией наклона и мой новый планшет (Transformer)

Ответ 1

Как уже упоминалось ранее, вы не хотите проверять, является ли устройство планшетом или телефоном, но вы хотите узнать об особенностях устройства,

В большинстве случаев разница между планшетом и телефоном - это размер экрана, поэтому вы хотите использовать разные файлы макета. Эти файлы хранятся в каталогах res/layout-<qualifiers>. Вы можете создать XML файл в directoy res/values-<same qualifiers> для каждого из ваших макетов и поместить в него ресурс int/bool/string, чтобы различать используемые вами макеты.

Пример:

Файл res/values/screen.xml (предполагается, что res/layout/ содержит ваши файлы макетов для мобильных телефонов)

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="screen_type">phone</string>
</resources>


Файл res/values-sw600dp/screen.xml (предполагается, что res/layout-sw600dp/ содержит ваши файлы макета для небольших планшетов, таких как Nexus 7)

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="screen_type">7-inch-tablet</string>
</resources>


Файл res/values-sw720dp/screen.xml (предполагается, что res/layout-sw720dp/ содержит ваши файлы макета для больших планшетов, таких как Nexus 10):

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="screen_type">10-inch-tablet</string>
</resources>


Теперь тип экрана доступен через константу R.string.screen_type.

Ответ 2

Чтобы определить, использует ли устройство планшет, используйте следующий код:

public boolean isTablet(Context context) {
    boolean xlarge = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE);
    boolean large = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE);
    return (xlarge || large);
}

LARGE и XLARGE Размеры экрана определяются производителем на основе расстояния от глаз, которым они должны использоваться (таким образом, идея планшета).

Дополнительная информация: http://groups.google.com/group/android-developers/browse_thread/thread/d6323d81f226f93f

Ответ 3

Этот пост мне очень помог,

К сожалению, у меня нет репутации, необходимой для оценки всех ответов, которые мне помогли.

Мне нужно было определить, было ли мое устройство планшетом или телефоном, и я мог бы реализовать логику экрана. И в моем анализе планшет должен составлять более 7 дюймов (Xlarge), начиная с MDPI.

Вот код ниже, который был создан на основе этого сообщения.

/**
 * Checks if the device is a tablet or a phone
 * 
 * @param activityContext
 *            The Activity Context.
 * @return Returns true if the device is a Tablet
 */
public static boolean isTabletDevice(Context activityContext) {
    // Verifies if the Generalized Size of the device is XLARGE to be
    // considered a Tablet
    boolean xlarge = ((activityContext.getResources().getConfiguration().screenLayout & 
                        Configuration.SCREENLAYOUT_SIZE_MASK) == 
                        Configuration.SCREENLAYOUT_SIZE_XLARGE);

    // If XLarge, checks if the Generalized Density is at least MDPI
    // (160dpi)
    if (xlarge) {
        DisplayMetrics metrics = new DisplayMetrics();
        Activity activity = (Activity) activityContext;
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

        // MDPI=160, DEFAULT=160, DENSITY_HIGH=240, DENSITY_MEDIUM=160,
        // DENSITY_TV=213, DENSITY_XHIGH=320
        if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
                || metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
                || metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM
                || metrics.densityDpi == DisplayMetrics.DENSITY_TV
                || metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {

            // Yes, this is a tablet!
            return true;
        }
    }

    // No, this is not a tablet!
    return false;
}

Ответ 4

Почему бы не рассчитать размер диагонали экрана и использовать это, чтобы принять решение, является ли устройство телефоном или планшетом?

private boolean isTablet()
{
    Display display = getWindowManager().getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    display.getMetrics(displayMetrics);

    int width = displayMetrics.widthPixels / displayMetrics.densityDpi;
    int height = displayMetrics.heightPixels / displayMetrics.densityDpi;

    double screenDiagonal = Math.sqrt( width * width + height * height );
    return (screenDiagonal >= 9.0 );
}

Конечно, можно утверждать, должен ли порог быть 9 дюймов или меньше.

Ответ 5

нет разницы. Вы должны определить, что вы думаете о различии, и проверить это. Является ли вкладка галактики телефоном? или планшет? и почему?

Вы должны определить, какие функции вы ищете, и код для этого.

Кажется, вы ищете "наклон". Я думаю, что это то же самое, что и акселерометр (это слово?). Вы можете просто проверить, поддерживает ли это устройство, используя:

public class Accel extends Activity implements SensorListener {
...
  SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
  boolean accelSupported = sensorMgr.registerListener(this,
        SENSOR_ACCELEROMETER,
        SENSOR_DELAY_UI);
...
}

(из http://stuffthathappens.com/blog/2009/03/15/android-accelerometer/. Я его не тестировал)

Ответ 6

Мое предположение заключается в том, что когда вы определяете "Мобильный/Телефон", вы хотите знать, можете ли вы сделать телефонный звонок на устройстве, который не может быть выполнен на том, что будет определено как "Планшет". Ниже приведен способ проверить это. Если вы хотите узнать что-то на основе датчиков, размера экрана и т.д., То это действительно другой вопрос.

Кроме того, при использовании разрешения экрана или управления ресурсами большой vs xlarge, возможно, был действительный подход в прошлом, новые мобильные устройства теперь идут с такими большими экранами и высокими разрешениями, что они размывают эту строку, а если вы действительно хотите узнать телефонный звонок без возможности вызова по телефону ниже "лучше".

TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
    return "Tablet";
}else{
    return "Mobile";
}

Ответ 7

Основываясь на Роберте Дейле Джонсоне III и Хелтоне Исаке, я придумал этот код. Надеюсь, это полезно.

public static boolean isTablet(Context context) {
    TelephonyManager manager = 
        (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    if (manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
        //Tablet
        return true;
    } else {
        //Mobile
        return false; 
    }
}

public static boolean isTabletDevice(Context activityContext) {
    // Verifies if the Generalized Size of the device is XLARGE to be
    // considered a Tablet
    boolean xlarge = 
         ((activityContext.getResources().getConfiguration().screenLayout & 
           Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE);

    // If XLarge, checks if the Generalized Density is at least MDPI (160dpi)
    if (xlarge) {
        DisplayMetrics metrics = new DisplayMetrics();
        Activity activity = (Activity) activityContext;
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

        // MDPI=160, DEFAULT=160, DENSITY_HIGH=240, DENSITY_MEDIUM=160,
        // DENSITY_TV=213, DENSITY_XHIGH=320
        if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
                  || metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
                  || metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM   
                  || metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {

             // Yes, this is a tablet!
             return true;
        }
    }

    // No, this is not a tablet!
    return false;
}

Итак, в вашем коде создайте фильтр вроде

if(isTabletDevice(Utilities.this) && isTablet(Utilities.this)){
    //Tablet
} else {
    //Phone
}

Ответ 8

Для тех, кто хочет ссылаться на код Google, определяющий, какие устройства будут использовать пользовательский интерфейс Tablet, можно сослаться ниже:

  // SystemUI (status bar) layout policy
        int shortSizeDp = shortSize
                * DisplayMetrics.DENSITY_DEFAULT
                / DisplayMetrics.DENSITY_DEVICE;

        if (shortSizeDp < 600) {
            // 0-599dp: "phone" UI with a separate status & navigation bar
            mHasSystemNavBar = false;
            mNavigationBarCanMove = true;
        } else if (shortSizeDp < 720) {
            // 600-719dp: "phone" UI with modifications for larger screens
            mHasSystemNavBar = false;
            mNavigationBarCanMove = false;
        } else {
            // 720dp: "tablet" UI with a single combined status & navigation bar
            mHasSystemNavBar = true;
            mNavigationBarCanMove = false;
        }
        }

Ответ 9

Этот метод рекомендуется Google. Я вижу этот код в приложении Google Offical для Android iosched

public static boolean isTablet(Context context) {
        return (context.getResources().getConfiguration().screenLayout
                & Configuration.SCREENLAYOUT_SIZE_MASK)
                >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}

Ответ 10

В исходном коде приложения Google IOSched 2017 используется следующий метод:

public static boolean isTablet(Context context) {
    return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}

Ответ 11

Если вы используете только уровень API >= 13, попробуйте

public static boolean isTablet(Context context) {
    return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}

приветствия: -)

Ответ 12

Не требуется код

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

Вместо этого объявляйте разные ресурсы для планшетов или телефонов. Вы делаете это, добавляя дополнительные папки ресурсов для layout, values и т.д.

  • Для Android 3.2 (уровень API 13) добавьте папку sw600dp. Это означает, что s самый высокий w idth составляет не менее 600 децибел, что примерно соответствует разнице в телефоне/таблетке. Однако вы также можете добавить другие размеры. Ознакомьтесь с этим ответом на примере того, как добавить дополнительный файл ресурсов макета.

  • Если вы также поддерживаете устройства до Android 3.2, вам нужно будет добавить папки large или xlarge для поддержки таблеток. (Телефоны обычно small и normal.)

Вот изображение того, что может понравиться вашим ресурсам после добавления дополнительных файлов xml для разных размеров экрана.

введите описание изображения здесь

При использовании этого метода система определяет все для вас. Вам не нужно беспокоиться о том, какое устройство используется во время выполнения. Вы просто предоставляете соответствующие ресурсы и позволяете Android выполнять всю работу.

Примечания

  • Вы можете использовать псевдонимы, чтобы избежать дублирования идентичных файлов ресурсов.

Android-документы, которые стоит прочитать

Ответ 13

Используйте этот метод, который возвращает true, когда устройство является планшетом

public boolean isTablet(Context context) {  
    return (context.getResources().getConfiguration().screenLayout   
        & Configuration.SCREENLAYOUT_SIZE_MASK)    
        >= Configuration.SCREENLAYOUT_SIZE_LARGE; 
}

Ответ 14

Размышляя над "новыми" перехваченными каталогами (например, значения-sw600dp), я создал этот метод на основе ширины экрана "DP:

 public static final int TABLET_MIN_DP_WEIGHT = 450;
 protected static boolean isSmartphoneOrTablet(Activity act){
    DisplayMetrics metrics = new DisplayMetrics();
    act.getWindowManager().getDefaultDisplay().getMetrics(metrics);

    int dpi = 0;
    if (metrics.widthPixels < metrics.heightPixels){
        dpi = (int) (metrics.widthPixels / metrics.density);
    }
    else{
        dpi = (int) (metrics.heightPixels / metrics.density);
    }

    if (dpi < TABLET_MIN_DP_WEIGHT)         return true;
    else                                    return false;
}

И в этом списке вы найдете некоторые из DP популярных устройств и размеров планшета:

Wdp/Hdp

GALAXY Nexus: 360/567
XOOM: 1280/752
ГАЛАКТИКА ПРИМЕЧАНИЕ: 400/615
NEXUS 7: 961/528
GALAXY TAB ( > 7 & < 10): 1280/752
GALAXY S3: 360/615

Wdp = Ширина dp
Hdp = Высота dp

Ответ 15

Хорошо, лучшее решение, которое сработало для меня, довольно просто:

private boolean isTabletDevice(Resources resources) {   
    int screenLayout = resources.getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
    boolean isScreenLarge = (screenLayout == Configuration.SCREENLAYOUT_SIZE_LARGE);
    boolean isScreenXlarge = (screenLayout == Configuration.SCREENLAYOUT_SIZE_XLARGE);
    return (isScreenLarge || isScreenXlarge);
}

Используется следующим образом:

public void onCreate(Bundle savedInstanceState) {
    [...]
    if (this.isTabletDevice(this.getResources()) == true) {
        [...]
    }
}

Я действительно не хочу смотреть на размеры пикселей, но полагаюсь только на размер экрана.

Хорошо работает, так как Nexus 7 (LARGE) определяется как планшет, но не Galaxy S3 (NORMAL).

Ответ 16

Если обнаружение размера экрана не возвращает правильное значение для новых устройств, попробуйте:

/*
 Returns '1' if device is a tablet
 or '0' if device is not a tablet.
 Returns '-1' if an error occured.
 May require READ_EXTERNAL_STORAGE
 permission.
 */
public static int isTablet()
{
    try
    {
        InputStream ism = Runtime.getRuntime().exec("getprop ro.build.characteristics").getInputStream();
        byte[] bts = new byte[1024];
        ism.read(bts);
        ism.close();

        boolean isTablet = new String(bts).toLowerCase().contains("tablet");
        return isTablet ? 1 : 0;
    }
    catch (Throwable t)
    {t.printStackTrace(); return -1;}
}

Протестировано на Android 4.2.2 (извините за мой английский.)

Ответ 17

Я знаю, что это не прямой ответ на ваш вопрос, но другие ответы здесь дают хорошее представление о том, как определить размер экрана. Вы написали в своем вопросе, что у вас проблемы с наклоном, и это случилось со мной.

Если вы запускаете гироскоп (или датчик вращения) на смартфоне, ось x и y может быть по-разному определена, чем на планшете, в соответствии с ориентацией по умолчанию этого устройства (например, Samsung GS2 является портретом по умолчанию, Samsung GT -7310 по умолчанию пейзаж, новый Google Nexus 7 по умолчанию портрет, хотя это таблетка!).

Теперь, если вы хотите использовать гироскоп, у вас может получиться рабочее решение для смартфонов, но путаница на некоторых таблицах или наоборот.

Если вы используете одно из решений сверху, чтобы перейти только к размеру экрана, а затем примените

SensorManager.remapCoordinateSystem(inputRotationMatrix, SensorManager.AXIS_X, 
    SensorManager.AXIS_Y, outputRotationMatrix);

чтобы перевернуть ось, если она имеет большой или большой размер экрана, это может работать в 90% случаев, но, например, на Nexus 7 это вызовет проблемы (потому что у него есть портретная ориентация по умолчанию и большой размер экрана).

Самый простой способ исправить это можно получить в RotationVectorSample, который поставляется с демонстрационными примерами API, установив siceenOrientation в nosensor в вашем манифесте:

<activity
    ...
    android:screenOrientation="nosensor">
...
</activity>

Ответ 18

Это метод, который я использую:

public static boolean isTablet(Context ctx){    
    return = (ctx.getResources().getConfiguration().screenLayout 
    & Configuration.SCREENLAYOUT_SIZE_MASK) 
    >= Configuration.SCREENLAYOUT_SIZE_LARGE; 
}

Использование:

Конфигурация. SCREENLAYOUT_SIZE_MASK

Конфигурация. SCREENLAYOUT_SIZE_LARGE

Это рекомендуемый метод!

Ответ 19

com.sec.feature.multiwindow.tablet в менеджере пакетов специфичен только для планшета и com.sec.feature.multiwindow.phone специфичен для телефона.

Ответ 20

ниже метод вычисляет длину диагонали экрана устройства, чтобы решить, что устройство представляет собой телефон или планшет. единственной проблемой для этого метода является то, что пороговое значение определяет погода, которую устройство является планшетом или нет. в приведенном ниже примере я установил его как 7 дюймов и выше.

public static boolean isTablet(Activity act)
{
    Display display = act.getWindow().getWindowManager().getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    display.getMetrics(displayMetrics);

    float width = displayMetrics.widthPixels / displayMetrics.xdpi;
    float height = displayMetrics.heightPixels / displayMetrics.ydpi;

    double screenDiagonal = Math.sqrt( width * width + height * height );
    int inch = (int) (screenDiagonal + 0.5);
    Toast.makeText(act, "inch : "+ inch, Toast.LENGTH_LONG).show();
    return (inch >= 7 );
}

Ответ 21

public boolean isTablet() {
        int screenLayout = getResources().getConfiguration().screenLayout;
        return (Build.VERSION.SDK_INT >= 11 &&
                (((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) || 
                 ((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE)));
    }

Ответ 22

Все труднее проводить линию между телефоном и планшетом. Например, (по состоянию на август 2015 года) устройство Samsung Mega 6.3 извлекает ресурсы из папок sw600dp - насколько это касается Android, это планшет.

Ответ от @Vyshnavi работает на всех проверенных нами устройствах, но не на Mega 6.3.

@Helton Isac отвечает выше, возвращает Mega 6.3 как телефон, но поскольку устройство по-прежнему захватывает ресурсы из sw600dp, это может вызвать другие проблемы - например, если вы используйте просмотрщик для телефонов, а не для планшетов, которые вы получите с ошибками NPE.

В конце концов, похоже, слишком много условий для проверки, и нам просто нужно признать, что некоторые телефоны на самом деле являются планшетами: -P

Ответ 23

зачем использовать это?

Use this method which returns true when the device is a tablet

public boolean isTablet(Context context) {  
return (context.getResources().getConfiguration().screenLayout   
    & Configuration.SCREENLAYOUT_SIZE_MASK)    
    >= Configuration.SCREENLAYOUT_SIZE_LARGE; 
}

я вижу много способов выше. Класс Configuration получил правильный ответ чуть ниже:

    /**
 * Check if the Configuration current {@link #screenLayout} is at
 * least the given size.
 *
 * @param size The desired size, either {@link #SCREENLAYOUT_SIZE_SMALL},
 * {@link #SCREENLAYOUT_SIZE_NORMAL}, {@link #SCREENLAYOUT_SIZE_LARGE}, or
 * {@link #SCREENLAYOUT_SIZE_XLARGE}.
 * @return Returns true if the current screen layout size is at least
 * the given size.
 */
public boolean isLayoutSizeAtLeast(int size) {
    int cur = screenLayout&SCREENLAYOUT_SIZE_MASK;
    if (cur == SCREENLAYOUT_SIZE_UNDEFINED) return false;
    return cur >= size;
}

просто позвони:

 getResources().getConfiguration().
 isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);

это нормально?

Ответ 24

Мне нужно было обнаружить смартфон/планшет только в файле макета, потому что я использую код навигации.

Сначала я создал каталог layout-sw600dp, но он не работал должным образом, поскольку он активировался на моем Nokia 8 в альбомном режиме, но высота экрана была бы слишком мала.

Итак, я переименовал каталог в layout-sw600dp-h400dp и получил желаемый эффект. Параметр h-xxxdp должен зависеть от того, сколько контента вы хотите добавить в макет, и, как таковой, должен зависеть от приложения.

Ответ 25

Пожалуйста, ознакомьтесь с нижеприведенным кодом.

private boolean isTabletDevice() {
  if (android.os.Build.VERSION.SDK_INT >= 11) { // honeycomb
    // test screen size, use reflection because isLayoutSizeAtLeast is
    // only available since 11
    Configuration con = getResources().getConfiguration();
    try {
      Method mIsLayoutSizeAtLeast = con.getClass().getMethod(
      "isLayoutSizeAtLeast", int.class);
      boolean r = (Boolean) mIsLayoutSizeAtLeast.invoke(con,
      0x00000004); // Configuration.SCREENLAYOUT_SIZE_XLARGE
      return r;
    } catch (Exception x) {
      x.printStackTrace();
      return false;
    }
  }
  return false;
}

Ответ 26

например. имеют важное значение (по крайней мере, для моей программы) между телефоном и планшетом. Это ориентация устройства по умолчанию. Телефон имеет портретную ориентацию, планшет - пейзаж. И соответственно метод определения устройства:

private static boolean isLandscapeDefault(Display display) {
    Log.d(TAG, "isTablet()");
    final int width = display.getWidth();
    final int height = display.getHeight();

    switch (display.getOrientation()) {
    case 0: case 2:
        if(width > height) return true;
        break;
    case 1: case 3:
        if(width < height) return true;
        break;
    }
    return false;
}

Редакция: После обсуждений с Дэном Хулме изменилось название метода.

Ответ 27

Я думаю, что планшет имеет минимальную и максимальную ширину и высоту 600 пикселей,
поэтому нужно знать плотность экрана и высоту/ширину в dp,
для получения значения:

DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth(); 
int height = display.getHeight(); 
float density = metrics.density;  
if((width/density>=600 && height/density>=600))
 isTablette = true;
else
 isTablette = false;

Ответ 28

Я рекомендую андроидную библиотеку 'caffeine', которая содержит телефон или планшет, и 10inch ~!

очень простое использование.

библиотека находится здесь.

https://github.com/ShakeJ/Android-Caffeine-library

и используйте

DisplayUtil.isTablet(this);
DisplayUtil.isTenInch(this);

Ответ 29

Для меня разница между телефоном и планшетом - это не размер устройства и/или плотность пикселей, который будет меняться с технологией и вкусом, а скорее соотношение экрана. Если я показываю экран с текстом, мне нужно знать, нужно ли, например, 15 длинных строк (телефон) против 20 коротких строк (планшет). Для моей игры я использую следующее для оценки шара прямоугольника, с которым будет работать мое программное обеспечение:

    Rect surfaceRect = getHolder().getSurfaceFrame();
    screenWidth = surfaceRect.width();
    screenHeight = surfaceRect.height();
    screenWidthF = (float) screenWidth;
    screenHeightF = (float) screenHeight;
    widthheightratio = screenWidthF/screenHeightF;
    if(widthheightratio>=1.5) {
        isTablet=false;
    }else {
        isTablet=true;
    }

Ответ 30

Я думаю, что это самый простой способ быть честным. Это будет проверять используемый размер экрана:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

Удачи!