Есть ли способ проверить, использует ли пользователь планшет или телефон? У меня проблемы с функцией наклона и новым планшетом (трансформатором)
Планшет или телефон - Android
Ответы (29)
Как уже упоминалось ранее, вы не хотите проверять, является ли устройство планшетом или телефоном, но вы хотите знать о функциях устройства,
В большинстве случаев разница между планшетом и телефоном заключается в размере экрана, поэтому вы хотите использовать разные файлы макета. Эти файлы хранятся в res/layout-<qualifiers>
каталогах. Вы можете создать XML-файл в директории 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
.
Чтобы определить, является ли устройство планшетом, используйте следующий код:
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);
}
БОЛЬШИЕ и БОЛЬШИЕ размеры экрана определяются производителем на основе расстояния от глаза, на котором они будут использоваться (отсюда и идея планшета).
Дополнительная информация: http://groups.google.com/group/android-developers/browse_thread/thread/d6323d81f226f93f
Configuration.SCREENLAYOUT_SIZE_XLARGE
, поэтому вам не нужно использовать константу, и вы можете использовать >= LARGE
.
- person Triang3l; 12.01.2013
Этот пост мне очень помог,
К сожалению, у меня нет репутации, необходимой для оценки всех ответов, которые мне помогли.
Мне нужно было определить, было ли мое устройство планшетом или телефоном, с этим я мог бы реализовать логику экрана. И в моем анализе планшет должен быть больше 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;
}
Почему бы не рассчитать размер диагонали экрана и не использовать его, чтобы решить, является ли устройство телефоном или планшетом?
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 дюймов или меньше.
нет никакой разницы. Вы должны определить, в чем, по вашему мнению, есть разница, и проверить это. Вкладка Galaxy - это телефон? или планшет? и почему?
Вы должны определить, какие конкретные функции вы ищете, и код для этого.
Похоже, вы ищете «тильт». Я думаю, это то же самое, что и акселерометр (это слово?). Вы можете просто проверить, поддерживает ли это устройство, используя:
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/. не тестировал)
Я предполагаю, что когда вы определяете «Мобильный / Телефон», вы хотите знать, можете ли вы сделать телефонный звонок на устройстве, что невозможно сделать на чем-то, что можно определить как «Планшет». Способ проверить это ниже. Если вы хотите что-то узнать на основе датчиков, размера экрана и т. Д., Тогда это действительно другой вопрос.
Кроме того, при использовании разрешения экрана или управления ресурсами большой по сравнению с xlarge, возможно, был допустимый подход в прошлом, новые `` мобильные '' устройства теперь поставляются с такими большими экранами и высокими разрешениями, что они стирают эту границу, хотя, если вы действительно хотите Чтобы узнать о телефонном звонке и отсутствии возможности телефонного звонка, "лучше всего" ниже.
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
return "Tablet";
}else{
return "Mobile";
}
Я придумал этот код на основе Роберта Дейла Джонсона 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
}
В приложении Google IOSched 2017 исходный код, используется следующий метод:
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
Для тех, кто хочет обратиться к коду Google для определения того, какие устройства будут использовать пользовательский интерфейс планшета, можно найти ниже:
// 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;
}
}
shortSize
?
- person kc ochibili; 05.09.2013
Этот метод рекомендуется Google. Я вижу этот код в официальном приложении Google для Android iosched
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
public static bool isTablet (Context context) { return (context.Resources.Configuration.ScreenLayout & Android.Content.Res.ScreenLayout.SizeMask) >= Android.Content.Res.ScreenLayout.SizeLarge; }
- person Phil Ryan; 23.03.2015
Код не нужен
В других ответах перечислены многие способы программного определения того, является ли устройство телефоном или планшетом. Однако если вы читаете документацию, это не рекомендуется. для поддержки экранов различных размеров.
Вместо этого объявите разные ресурсы для планшетов или телефонов. Вы делаете это, добавляя дополнительные папки ресурсов для layout
, values
и т. Д.
Для Android 3.2 (уровень API 13) добавьте папку
sw600dp
. Это означает, что наименьшая ширина ширины составляет не менее 600 точек на дюйм, что приблизительно равно разделению между телефоном и планшетом. Однако вы также можете добавить другие размеры. Посмотрите этот ответ, чтобы узнать, как добавить дополнительный файл ресурсов макета.Если вы также поддерживаете устройства до Android 3.2, вам нужно будет добавить папки
large
илиxlarge
для поддержки планшетов. (Обычно телефоныsmall
иnormal
.)
Вот изображение того, что может понравиться вашим ресурсам после добавления дополнительных файлов xml для разных размеров экрана.
При использовании этого метода система все определяет за вас. Вам не нужно беспокоиться о том, какое устройство используется во время выполнения. Вы просто предоставляете соответствующие ресурсы, а Android делает всю работу.
Примечания
- Вы можете использовать псевдонимы, чтобы избежать дублирования идентичных файлов ресурсов.
Документы по Android, которые стоит прочитать
- Поддержка нескольких экранов
- Поддержка экранов разных размеров
- Распространение на определенные экраны
Если вы ориентируетесь только на уровень API> = 13, попробуйте
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
ваше здоровье :-)
Думая о "новых" принятых каталогах (например, values-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
GALAXY NOTE: 400/615
NEXUS 7: 961/528
ВКЛАДКА GALAXY (> 7 && ‹10): 1280/752
GALAXY S3: 360/615
Wdp = Ширина dp
Hdp = Высота dp
Что ж, лучшее решение, которое сработало для меня, довольно простое:
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 (БОЛЬШОЙ) определяется как планшет, но не Galaxy S3 (НОРМАЛЬНЫЙ).
Используйте этот метод, который возвращает true, если устройством является планшет.
public boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Если определение размера экрана не возвращает правильное значение на новых устройствах, попробуйте:
/*
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 (извините за мой англ.)
Я знаю, что это не прямой ответ на ваш вопрос, но другие ответы здесь дают хорошее представление о том, как определить размер экрана. В своем вопросе вы написали, что у вас проблемы с наклоном, и это тоже случилось со мной.
Если вы запустите гироскоп (или датчик вращения) на смартфоне, оси x и y могут быть определены иначе, чем на планшете, в зависимости от ориентации этого устройства по умолчанию (например, Samsung GS2 - портретная ориентация по умолчанию, Samsung GT-7310 - по умолчанию альбомная ориентация, новый Google Nexus 7 - портретная ориентация по умолчанию, хотя это планшет!).
Теперь, если вы хотите использовать Gyroscope, у вас может получиться рабочее решение для смартфонов, но путаница с осями на некоторых планшетах или наоборот.
Если вы используете одно из вышеперечисленных решений, чтобы выбрать только размер экрана, а затем примените
SensorManager.remapCoordinateSystem(inputRotationMatrix, SensorManager.AXIS_X,
SensorManager.AXIS_Y, outputRotationMatrix);
чтобы перевернуть ось, если у него большой или xlarge размер экрана, это может сработать в 90% случаев, но, например, на Nexus 7 это вызовет проблемы (поскольку он имеет портретную ориентацию по умолчанию и большой размер экрана).
Самый простой способ исправить это предоставляется в RotationVectorSample, который поставляется с демонстрациями API, установив для sceenOrientation значение nosensor
в вашем манифесте:
<activity
...
android:screenOrientation="nosensor">
...
</activity>
com.sec.feature.multiwindow.tablet в диспетчере пакетов относится только к планшету, а com.sec.feature.multiwindow.phone - к телефону.
Нижеприведенный метод вычисляет длину диагонали экрана устройства, чтобы решить, является ли устройство телефоном или планшетом. Единственная проблема для этого метода - какое пороговое значение определяет, является ли устройство планшетом или нет. в приведенном ниже примере я установил его как 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 );
}
Становится все труднее провести грань между телефоном и планшетом. Например (по состоянию на август 2015 г.) устройство Samsung Mega 6.3 извлекает ресурсы из sw600dp. папки - для Android это планшет.
Ответ от @Vyshnavi работает на всех протестированных нами устройствах, но не на Mega 6.3.
@Helton Isac ответ выше возвращает Mega 6.3 как телефон, но поскольку устройство по-прежнему захватывает ресурсы из sw600dp, это может вызвать другие проблемы - например, если вы используете viewpager для телефонов, а не для планшетов, вы столкнетесь с ошибками NPE.
В конце концов кажется, что существует слишком много условий, которые нужно проверить, и нам, возможно, просто придется признать, что некоторые телефоны на самом деле являются планшетами :-P
Это метод, который я использую:
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 < / сильный>
Это рекомендуемый метод!
зачем это использовать?
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;
}
я вижу много способов выше. класс конфигурации получил правильный ответ чуть ниже:
/**
* Check if the Configuration's 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);
it's ok?
Смартфон / планшет мне нужно было определить только в файле макета, потому что я использую код навигации.
Сначала я создал каталог layout-sw600dp, но он не работал должным образом, потому что он активировался на моем Nokia 8 в ландшафтном режиме, но высота экрана была бы слишком маленькой.
Итак, я переименовал каталог в layout-sw600dp-h400dp и получил желаемый эффект. Параметр h-xxxdp должен зависеть от того, сколько контента вы хотите поместить в свой макет, и, как таковой, должен зависеть от приложения.
Пожалуйста, ознакомьтесь с приведенным ниже кодом.
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;
}
Я думаю, что планшет имеет минимальную и максимальную ширину и высоту 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;
Например. есть одно важное отличие (по крайней мере для моей программы) между телефоном и планшетом. Это ориентация устройства по умолчанию. Телефон имеет портретную ориентацию, планшет - альбомную. И соответственно способ определения устройства:
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;
}
EDITED: после обсуждения с Дэном Халмом изменилось название метода.
Я рекомендую Android-библиотеку «кофеин», которая содержит телефон или планшет и 10 дюймов ~!
очень простое использование.
библиотека здесь.
https://github.com/ShakeJ/Android-Caffeine-library
и использовать
DisplayUtil.isTablet(this);
DisplayUtil.isTenInch(this);
Для меня разница между телефоном и планшетом заключается не в размере устройства и / или плотности пикселей, которая будет меняться в зависимости от технологии и вкуса, а в соотношении экрана. Если я показываю экран с текстом, мне нужно знать, нужны ли, скажем, 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;
}
Я считаю, что это самый простой способ, если честно. Это проверит используемый размер экрана:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Удачи!