¿Hay alguna manera de verificar si el usuario está usando una tableta o un teléfono? Tengo problemas con mi función de inclinación y mi nueva tableta (Transformador)
¿Hay alguna manera de verificar si el usuario está usando una tableta o un teléfono? Tengo problemas con mi función de inclinación y mi nueva tableta (Transformador)
Respuestas:
Como se mencionó anteriormente, no desea verificar si el dispositivo es una tableta o un teléfono, pero desea conocer las características del dispositivo,
La mayoría de las veces, la diferencia entre una tableta y un teléfono es el tamaño de la pantalla, por lo que desea utilizar diferentes archivos de diseño. Estos archivos se almacenan en los res/layout-<qualifiers>
directorios. Puede crear un archivo XML en el directorio res/values-<same qualifiers>
para cada uno de sus diseños y colocar un recurso int / bool / string en él para distinguir entre los diseños que utiliza.
Archivo res/values/screen.xml
(suponiendo que res/layout/
contenga sus archivos de diseño para teléfonos)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">phone</string>
</resources>
Archivo res/values-sw600dp/screen.xml
(suponiendo que res/layout-sw600dp/
contenga sus archivos de diseño para tabletas pequeñas como el Nexus 7)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">7-inch-tablet</string>
</resources>
Archivo res/values-sw720dp/screen.xml
(suponiendo que res/layout-sw720dp/
contenga sus archivos de diseño para tabletas grandes como el Nexus 10):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">10-inch-tablet</string>
</resources>
Ahora se puede acceder al tipo de pantalla a través de la R.string.screen_type
constante.
Para detectar si el dispositivo es una tableta, use el siguiente código:
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);
}
Los tamaños de pantalla LARGE y XLARGE son determinados por el fabricante en función de la distancia desde el ojo en el que se utilizarán (de ahí la idea de una tableta).
Más información: http://groups.google.com/group/android-developers/browse_thread/thread/d6323d81f226f93f
Configuration.SCREENLAYOUT_SIZE_XLARGE
, por lo que no tiene que usar una constante, y puede usar >= LARGE
.
Esta publicación me ayudó mucho,
Lamentablemente, no tengo la reputación necesaria para evaluar todas las respuestas que me ayudaron.
Necesitaba identificar si mi dispositivo era una tableta o un teléfono, con eso podría implementar la lógica de la pantalla. Y en mi análisis, la tableta debe tener más de 7 pulgadas (Xlarge) a partir de MDPI.
Aquí está el código a continuación, que se creó en base a esta publicación.
/**
* 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;
}
¿Por qué no calcular el tamaño de la diagonal de la pantalla y usarlo para tomar la decisión de si el dispositivo es un teléfono o una tableta?
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 );
}
Por supuesto, uno puede discutir si el umbral debe ser de 9 pulgadas o menos.
no hay diferencia. Debes definir cuál crees que es la diferencia, y verificar eso. ¿Una pestaña de galaxia es un teléfono? o una tableta? ¿y por qué?
Debe definir qué características específicas está buscando y codificar para eso.
Parece que estás buscando 'inclinación'. Creo que esto es lo mismo que el acelerómetro (¿es una palabra?). Puede verificar si el dispositivo lo admite, utilizando:
public class Accel extends Activity implements SensorListener {
...
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
boolean accelSupported = sensorMgr.registerListener(this,
SENSOR_ACCELEROMETER,
SENSOR_DELAY_UI);
...
}
(de http://stuffthathappens.com/blog/2009/03/15/android-accelerometer/ . No lo he probado)
Mi suposición es que cuando define 'Móvil / Teléfono' desea saber si puede hacer una llamada telefónica en el dispositivo que no se puede hacer en algo que se definiría como una 'Tableta'. La forma de verificar esto es a continuación. Si desea saber algo basado en sensores, tamaño de pantalla, etc., esta es realmente una pregunta diferente.
Además, mientras usaba la resolución de pantalla, o la gestión de recursos grande frente a xlarge, puede haber sido un enfoque válido en el pasado, los nuevos dispositivos 'móviles' ahora vienen con pantallas tan grandes y altas resoluciones que están borrando esta línea, si realmente lo desean para conocer la capacidad de llamadas telefónicas versus ninguna llamada telefónica, lo siguiente es "mejor".
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
return "Tablet";
}else{
return "Mobile";
}
Basado en Robert Dale Johnson III y Helton Isac se me ocurrió este código Espero que esto sea útil
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;
}
Entonces, en su código, haga un filtro como
if(isTabletDevice(Utilities.this) && isTablet(Utilities.this)){
//Tablet
} else {
//Phone
}
En el código fuente de la aplicación Google IOSched 2017 , se utiliza el siguiente método:
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
Para aquellos que desean consultar el código de Google para decidir qué dispositivos usarán una interfaz de usuario de tableta, pueden consultar a continuación:
// 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
?
Este método es recomendado por Google. Veo este código en la aplicación de Android oficial de Googleiosched
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; }
Las otras respuestas enumeran muchas formas de determinar mediante programación si el dispositivo es un teléfono o una tableta. Sin embargo, si lee la documentación , esa no es la forma recomendada para admitir varios tamaños de pantalla.
En cambio, declare diferentes recursos para tabletas o teléfonos. Esto se hace añadiendo mis carpetas de recursos adicionales para layout
, values
, etc.
Para Android 3.2 (API nivel 13), agregue una sw600dp
carpeta. Esto significa que el S mallest w idth es al menos 600dp, que es aproximadamente la brecha teléfono / comprimido. Sin embargo, también puede agregar otros tamaños. Consulte esta respuesta para ver un ejemplo de cómo agregar un archivo de recursos de diseño adicional.
Si también es compatible con dispositivos anteriores a Android 3.2, deberá agregar carpetas large
o xlarge
carpetas para admitir tabletas. (Los teléfonos son generalmente small
y normal
.)
Aquí hay una imagen de lo que le gustaría a sus recursos después de agregar archivos xml adicionales para diferentes tamaños de pantalla.
Al usar este método, el sistema determina todo por usted. No tiene que preocuparse por qué dispositivo se está utilizando en tiempo de ejecución. Solo debe proporcionar los recursos adecuados y dejar que Android haga todo el trabajo.
Notas
Si solo se dirige al nivel de API> = 13, intente
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
salud :-)
Pensando en los "nuevos" directorios aceptados (valores-sw600dp por ejemplo) creé este método basado en el ancho DP de la pantalla:
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;
}
Y en esta lista puede encontrar algunos de los DP de dispositivos populares y tamaños de tabletas:
Wdp / Hdp
GALAXY Nexus: 360/567
XOOM: 1280/752
GALAXY NOTA: 400/615
NEXUS 7: 961/528
GALAXY TAB (> 7 && <10): 1280/752
GALAXY S3: 360/615
Wdp = Ancho dp
Hdp = Altura dp
Bueno, la mejor solución que funcionó para mí es bastante simple:
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);
}
Usado así:
public void onCreate(Bundle savedInstanceState) {
[...]
if (this.isTabletDevice(this.getResources()) == true) {
[...]
}
}
Realmente no quiero ver el tamaño de los píxeles, sino que solo confío en el tamaño de la pantalla.
Funciona bien, ya que Nexus 7 (GRANDE) se detecta como tableta, pero no Galaxy S3 (NORMAL).
Use este método que devuelve verdadero cuando el dispositivo es una tableta
public boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Si la detección del tamaño de la pantalla no devuelve el valor correcto en los dispositivos más nuevos, pruebe:
/*
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;}
}
Probado en Android 4.2.2 (perdón por mi inglés)
Sé que esto no es directamente una respuesta a su pregunta, pero otras respuestas aquí dan una buena idea de cómo identificar el tamaño de la pantalla. Usted escribió en su pregunta que tenía problemas con la inclinación y esto también me sucedió a mí.
Si ejecuta el giroscopio (o sensor de rotación) en un teléfono inteligente, los ejes X e Y pueden definirse de manera diferente que en una tableta, de acuerdo con la orientación predeterminada de ese dispositivo (por ejemplo, Samsung GS2 es vertical, Samsung GT-7310 es paisaje predeterminado, el nuevo Google Nexus 7 es el retrato predeterminado, ¡aunque es una tableta!).
Ahora, si desea usar Gyroscope, puede terminar con una solución de trabajo para teléfonos inteligentes, pero con confusión de ejes en algunas tabletas o al revés.
Si usa una de las soluciones de arriba para ir solo al tamaño de la pantalla y luego aplicar
SensorManager.remapCoordinateSystem(inputRotationMatrix, SensorManager.AXIS_X,
SensorManager.AXIS_Y, outputRotationMatrix);
para voltear el eje si tiene un tamaño de pantalla grande o grande, esto podría funcionar en el 90% de los casos, pero, por ejemplo, en el Nexus 7 causará problemas (porque tiene una orientación vertical predeterminada y un tamaño de pantalla grande).
La forma más sencilla de solucionar esto se proporciona en RotationVectorSample que se incluye con las demostraciones de API configurando sceenOrientation nosensor
en su manifiesto:
<activity
...
android:screenOrientation="nosensor">
...
</activity>
El siguiente método es calcular la longitud diagonal de la pantalla del dispositivo para decidir si el dispositivo es un teléfono o una tableta. La única preocupación para este método es cuál es el valor umbral para decidir si el dispositivo es tableta o no. en el ejemplo a continuación lo configuré como 7 pulgadas o más.
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 );
}
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)));
}
Cada vez es más difícil trazar la línea entre el teléfono y la tableta. Por ejemplo (a partir de agosto de 2015), el dispositivo Samsung Mega 6.3 extrae recursos de las carpetas sw600dp, por lo que, en lo que respecta a Android, es una tableta.
La respuesta de @Vyshnavi funciona en todos los dispositivos que hemos probado, pero no para Mega 6.3.
La respuesta anterior de @Helton Isac devuelve el Mega 6.3 como teléfono, pero dado que el dispositivo todavía toma recursos de sw600dp, puede causar otros problemas, por ejemplo, si usa un visor para teléfonos y no para tabletas, terminará con errores de NPE .
Al final, parece que hay demasiadas condiciones para verificar y es posible que tengamos que aceptar que algunos teléfonos son en realidad tabletas :-P
Este es el método que uso:
public static boolean isTablet(Context ctx){
return = (ctx.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Utilizando:
Configuración. SCREENLAYOUT_SIZE_MASK
Configuración. SCREENLAYOUT_SIZE_LARGE
¡Este es el método recomendado!
¿Por qué usar esto?
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;
}
Veo muchas formas arriba. La clase de configuración tiene la respuesta correcta a continuación:
/**
* 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;
}
solo llama :
getResources().getConfiguration().
isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);
¿está bien?
Necesitaba detectar el teléfono inteligente / tableta solo en el archivo de diseño, porque estoy usando el código de navegación.
Lo primero que hice fue crear un directorio layout-sw600dp pero no funcionaba bien porque se activaría en mi Nokia 8 en modo horizontal, pero la altura de la pantalla sería demasiado pequeña.
Entonces, cambié el nombre del directorio como layout-sw600dp-h400dp y luego obtuve el efecto deseado. El parámetro h-xxxdp debe depender de la cantidad de contenido que desee colocar en su diseño y, como tal, debe depender de la aplicación.
Por favor, consulte el siguiente código.
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;
}
Creo que una tableta tiene un ancho y una altura mínima y máxima de 600 px,
así que necesito saber la densidad de la pantalla y la altura / ancho en dp,
para recuperar el valor:
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;
Por ejemplo, tengo una diferencia importante (al menos para mi programa) entre el teléfono y la tableta. Es la orientación predeterminada del dispositivo. El teléfono tiene una orientación vertical, la tableta - horizontal. Y respectivamente método para determinar el dispositivo:
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;
}
EDITADO: Después de las discusiones con Dan Hulme, cambió el nombre del método.
¡Recomiendo la biblioteca de Android 'cafeína' que contiene Get Phone o tablet, y 10 pulgadas ~!
Muy fácil de usar.
La biblioteca está aquí.
https://github.com/ShakeJ/Android-Caffeine-library
y use
DisplayUtil.isTablet(this);
DisplayUtil.isTenInch(this);
Para mí, la distinción entre teléfono y tableta no es el tamaño del dispositivo y / o la densidad de píxeles, que cambiará con la tecnología y el gusto, sino la relación de pantalla. Si estoy mostrando una pantalla de texto, necesito saber si, por ejemplo, se necesitan 15 líneas largas (teléfono) frente a 20 líneas más cortas (tableta). Para mi juego utilizo lo siguiente para una estimación aproximada del rectángulo con el que tratará mi software:
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;
}