Определить, является ли устройство смартфоном или планшетом?
Я хотел бы получить информацию об устройстве, чтобы увидеть, смартфон это или планшет. Как мне это сделать?
Я хотел бы показать различные веб-страницы из ресурсов в зависимости от типа устройства:
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)
}
9 ответов
Эта тема обсуждается в обучении 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
}
Я считаю, что планшет должен иметь как минимум 6,5-дюймовый экран. Вот как это вычислить, основываясь на ответе Нольфа выше.
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
}
Я предполагаю, что когда вы определяете "Мобильный телефон", вы хотите знать, можете ли вы сделать телефонный звонок на устройстве, что нельзя сделать на чем-то, что будет определено как "планшет". Способ проверить это ниже. Если вы хотите узнать что-то по сенсорам, размеру экрана и т. Д., То это действительно другой вопрос.
Кроме того, при использовании разрешения экрана или больших ресурсов управления ресурсами против xlarge, возможно, было правильным подходом в прошлом. Новые мобильные устройства теперь выпускаются с такими большими экранами и высоким разрешением, что они размывают эту линию, хотя, если вы действительно хотите чтобы узнать телефонный звонок против возможности телефонного звонка, ниже "лучше".
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
return "Tablet";
}else{
return "Mobile";
}
Мне нравится решение Ol_v_er и его простота, однако, я обнаружил, что это не всегда так просто, как с новыми устройствами и дисплеями, постоянно выходящими, и я хочу быть немного более "детальным" в попытке выяснить реальный размер экрана, Еще одно решение, которое я нашел здесь от Джона, использует ресурс 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
}
Ответ Шона О'Тула на " Обнаружение 7-дюймового и 10-дюймового планшета программным способом" также был тем, что я искал. Возможно, вы захотите проверить это, если ответы здесь не позволяют вам быть настолько конкретными, как вам бы хотелось. Он отлично объясняет, как рассчитать различные метрики, чтобы выяснить, с чем вы на самом деле имеете дело.
ОБНОВИТЬ
Просматривая исходный код приложения Google I/O 2013, я наткнулся на следующее, которое они используют, чтобы определить, является ли устройство планшетом или нет, поэтому я решил добавить его. Вышеприведенное дает вам немного больше "контроля" над ним, но если вы просто хотите узнать, является ли это планшетом, следующее довольно просто:
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Я использую этот метод во всех своих приложениях, и он успешно работает:
public static boolean isTablet(Context ctx){
return (ctx.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Поскольку планшет обычно больше смартфонов и поскольку планшет с низким разрешением может иметь такое же количество пикселей, что и смартфон с высоким разрешением, один из способов решить эту проблему - рассчитать физический РАЗМЕР (не разрешение) устройства:
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
}
Лучший вариант, который я нашел, и менее навязчивый, это установить параметр тега в вашем xml, например:
PHONE 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"/>
ПЛАНШЕТНАЯ ПЛАТА XML
<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()));
Надеюсь, это работает для вас.
Решение, которое я использую, заключается в определении двух макетов. Один с папкой макета, установленной, например, layout-sw600dp, я использую это, чтобы предоставить кнопку меню для пользователей моего планшета и скрыть это для пользователей телефона. Таким образом, мне не нужно (пока) реализовывать ActionBar для моих существующих приложений...
Смотрите этот пост для более подробной информации.
Касательно вышесказанного о том, как отличить телефон от не-телефона: насколько я знаю, только телефон имеет 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() по какой-то причине возвращает phoneType "GSM", поэтому проверка типа телефона ненадежна. Аналогично, getNetworkType() вернет 0 для телефона в режиме полета. Фактически, режим самолета приведет к тому, что методы getLine1Number() и getSim* также будут возвращать ноль. Но даже в режиме полета IMEI телефона сохраняется.