Определите, является ли устройство смартфоном или планшетом?

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

Я хотел бы показать разные веб-страницы из ресурсов на основе типа устройства:

String s="Debug-infos:";
s += "\n OS Version: " + System.getProperty("os.version") + "(" +    android.os.Build.VERSION.INCREMENTAL + ")";
s += "\n OS API Level: " + android.os.Build.VERSION.SDK;
s += "\n Device: " + android.os.Build.DEVICE;
s += "\n Model (and Product): " + android.os.Build.MODEL + " ("+ android.os.Build.PRODUCT + ")";

Однако для моего случая это кажется бесполезным.


Теперь это решение работает для меня:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
int height = metrics.heightPixels;

if (SharedCode.width > 1023 || SharedCode.height > 1023){
   //code for big screen (like tablet)
}else{
   //code for small screen (like smartphone)
}

Ответ 1

Эта тема обсуждается в обучении Android:

Используйте спецификатор наименьшей ширины

Если вы прочитаете всю тему, они объяснят, как установить логическое значение в конкретном файле значений (как res/values-sw600dp/attr.xml):

<resources>
    <bool name="isTablet">true</bool>
</resources>

Потому что квалификатор sw600dp действителен только для платформ выше Android 3.2. Если вы хотите убедиться, что этот метод работает на всех платформах (до 3.2), создайте тот же файл в папке res/values-xlarge:

<resources>
    <bool name="isTablet">true</bool>
</resources>

Затем в "стандартном" файле значений (как res/values /) вы устанавливаете логическое значение false:

<resources>
    <bool name="isTablet">false</bool>
</resources>

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

boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
    // do something
} else {
    // do something else
}

Ответ 2

Я считаю, что планшет имеет по меньшей мере 6,5-дюймовый экран. Вот как это вычислить, основываясь на ответе Nolf выше.

DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);

float yInches= metrics.heightPixels/metrics.ydpi;
float xInches= metrics.widthPixels/metrics.xdpi;
double diagonalInches = Math.sqrt(xInches*xInches + yInches*yInches);
if (diagonalInches>=6.5){
    // 6.5inch device or bigger
}else{
    // smaller device
}

Ответ 3

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

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

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

Ответ 4

Мне нравится решение Ol_v_er, и это простота, но я обнаружил, что это не всегда так просто, что с постоянно появляющимися новыми устройствами и дисплеями, и я хочу быть немного более "гранулированным", пытаясь выяснить фактический размер экрана. Еще одно решение, которое я нашел здесь от John, использует ресурс String вместо логического, чтобы указать размер планшета. Таким образом, вместо того, чтобы просто поместить true в файл /res/values -sw600dp/screen.xml(предполагая, что это ваши макеты для небольших планшетов), вы должны поставить:

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

Опишите это следующим образом, а затем выполните то, что вам нужно, на основе результата:

String screenType = getResources().getString(R.string.screen_type);
if (screenType.equals("7-inch-tablet")) {
    // do something
} else {
    // do something else
}

Ответ Sean O'Toole для Обнаружение 7-дюймового и 10-дюймового планшета программным путем также было тем, что я искал. Вы можете проверить это, если ответы здесь не позволяют вам быть настолько конкретными, насколько вам бы хотелось. Он отлично справляется с объяснением того, как рассчитать разные показатели, чтобы выяснить, что вы на самом деле имеете в виду.

UPDATE

Изучая исходный код приложения I/O 2013 года, я столкнулся с следующим: они используют, чтобы определить, является ли устройство планшетом или нет, поэтому я решил добавить его. Вышесказанное дает вам немного больше "контроля" над ним, но если вы просто хотите узнать, есть ли это планшет, следующее довольно просто:

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

Ответ 5

Так как планшеты в целом больше, чем смартфоны, и поскольку планшет с низким разрешением может иметь такое же количество пикселей, что и смартфон с высоким разрешением, один из способов решить это - вычислить физический РАЗМЕР (не разрешение) устройства:

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);

    float yInches= metrics.heightPixels/metrics.ydpi;
    float xInches= metrics.widthPixels/metrics.xdpi;

   if (yInches> smallestTabletSize|| xInches > smallestTabletSize)
    {
                  //We are on a 
    }

Ответ 6

Лучший вариант, который я нашел и менее навязчивый, - установить параметр тэга в вашем xml, например

ТЕЛЕФОН XML LAYOUT

<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="phone"/>

TABLET XML LAYOUT

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="tablet">

    ...

</RelativeLayout>

а затем вызовите это в своем классе активности:

View viewPager = findViewById(R.id.pager);
Log.d(getClass().getSimpleName(), String.valueOf(viewPager.getTag()));

Надеюсь, что это сработает для u.

Ответ 7

Я использую этот метод во всех своих приложениях, и он работает успешно:

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

Ответ 8

Решение, которое я использую, состоит в том, чтобы определить два макета. Один с папкой макета, установленной, например, макета sw600dp Я использую это, чтобы предоставить кнопку меню для пользователей планшета и скрыть это для пользователей телефона. Таким образом, я еще не должен реализовывать ActionBar для существующих приложений...

Подробнее см. этот пост.

Ответ 9

Re: касательная выше о том, как сообщить телефону с телефона: насколько я знаю, только у телефона есть 15-значный IMEI (идентификация оборудования мобильной мобильной станции), поэтому следующий код будет окончательно различать телефон с телефона:

    TelephonyManager manager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
    String deviceInfo = "";
    deviceInfo += manager.getDeviceId(); // the IMEI
    Log.d(TAG, "IMEI or unique ID is " + deviceInfo);

    if (manager.getDeviceId() == null) {
        Log.d(TAG, "This device is NOT a phone");
    } else {
        Log.d(TAG, "This device is a phone.");
    }

Я обнаружил, что на эмуляторе Nook getPhoneType() по какой-то причине возвращает телефонный тип "GSM", поэтому, похоже, проверка на тип телефона ненадежна. Аналогично, getNetworkType() вернет 0 для телефона в самолете. Фактически, режим самолета заставит getLine1Number() и методы getSim * также возвращать значение null. Но даже в режиме самолета IMEI телефона сохраняется.