Detecta tabletas de 7 y 10 pulgadas mediante programación

93

¿Hay alguna manera de encontrar mediante programación si el dispositivo en el que está instalada la aplicación es una tableta de 7 pulgadas o una tableta de 10 pulgadas?

Novato
fuente
Por ejemplo: layout-sw600dp busca el tamaño de ancho más pequeño de 600dp.
Novato
Entiendo eso, pero ¿qué estás buscando programáticamente?
Geobits
Necesito buscar estos dispositivos programáticamente ... ya que hay algunas propiedades que no puedo definir en xml ... esas propiedades están definidas en el código mismo ... así que si simplemente pongo el código, se aplicará a todos los dispositivos ... pero No quiero eso ..
Novato
@Raghav ha probado con display matrix para obtener el tamaño de la pantalla y luego puede comparar. Aunque no es una forma limpia, pero puedes usarla.
PiyushMishra
Puede obtener las dimensiones de su pantalla y trabajar desde allí ... stackoverflow.com/questions/1016896/…
Raj

Respuestas:

234

Puede usar el DisplayMetricspara obtener una gran cantidad de información sobre la pantalla en la que se ejecuta su aplicación.

Primero, creamos un DisplayMetricsobjeto de métricas:

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

A partir de esto, podemos obtener la información necesaria para dimensionar la pantalla:

int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;

Esto devolverá el valor absoluto del ancho y la altura en píxeles, por lo que 1280x720 para el Galaxy SIII, el Galaxy Nexus, etc.

Por lo general, esto no es útil por sí solo, ya que cuando trabajamos en dispositivos Android, generalmente preferimos trabajar en píxeles independientes de la densidad, dip.

Obtienes densityel tamaño de la pantalla usando metricsnuevamente, en forma de un factor de escala para el dispositivo, que se basa en los Recursos de diseño de Android para mdpi, hdpietc. Escalas DPI

float scaleFactor = metrics.density;

A partir de este resultado, podemos calcular la cantidad de píxeles independientes de la densidad que hay para una determinada altura o anchura.

float widthDp = widthPixels / scaleFactor
float heightDp = heightPixels / scaleFactor

El resultado que obtenga de esto lo ayudará a decidir con qué tipo de pantalla está trabajando junto con los ejemplos de configuración de Android , que le brindan el dp relativo para cada tamaño de pantalla:

  • 320dp: una pantalla de teléfono típica (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc.).
  • 480dp: una tableta tweener como la Streak (480x800 mdpi).
  • 600dp: una tableta de 7 ”(600x1024 mdpi).
  • 720dp: una tableta de 10 ”(720x1280 mdpi, 800x1280 mdpi, etc.).

Usando la información anterior, sabemos que si el ancho más pequeño del dispositivo es mayor que 600dp, el dispositivo es una tableta de 7 ", si es mayor que 720dp, el dispositivo es una tableta de 10".

Podemos calcular el ancho más pequeño usando la minfunción de Mathclase, pasando el heightDpy el widthDppara devolver el smallestWidth.

float smallestWidth = Math.min(widthDp, heightDp);

if (smallestWidth > 720) {
    //Device is a 10" tablet
} 
else if (smallestWidth > 600) {
    //Device is a 7" tablet
}

Sin embargo, esto no siempre le da una coincidencia exacta, especialmente cuando se trabaja con tabletas oscuras que pueden estar tergiversando su densidad como hdpi cuando no lo es, o que solo pueden tener 800 x 480 píxeles y aún así estar en una pantalla de 7 ". .

Además de estos métodos, si alguna vez necesita saber las dimensiones exactas de un dispositivo en pulgadas, también puede calcularlo utilizando el metricsmétodo de cuántos píxeles hay por pulgada de la pantalla.

float widthDpi = metrics.xdpi;
float heightDpi = metrics.ydpi;

Puede utilizar el conocimiento de cuántos píxeles hay en cada pulgada del dispositivo y la cantidad de píxeles en total para calcular cuántas pulgadas tiene el dispositivo.

float widthInches = widthPixels / widthDpi;
float heightInches = heightPixels / heightDpi;

Esto devolverá la altura y el ancho del dispositivo en pulgadas. Nuevamente, esto no siempre es tan útil para determinar qué tipo de dispositivo es, ya que el tamaño anunciado de un dispositivo es la diagonal, todo lo que tenemos es la altura y el ancho.

Sin embargo, también sabemos que, dada la altura y el ancho de un triángulo, podemos usar el teorema de Pitágoras para calcular la longitud de la hipotenusa (en este caso, el tamaño de la diagonal de la pantalla).

//a² + b² = c²

//The size of the diagonal in inches is equal to the square root of the height in inches squared plus the width in inches squared.
double diagonalInches = Math.sqrt(
    (widthInches * widthInches) 
    + (heightInches * heightInches));

A partir de esto, podemos averiguar si el dispositivo es una tableta o no:

if (diagonalInches >= 10) {
    //Device is a 10" tablet
} 
else if (diagonalInches >= 7) {
    //Device is a 7" tablet
}

Y así es como calcula con qué tipo de dispositivo está trabajando.

Sean O'Toole
fuente
3
Excelentes consejos Sean. Solía ​​consultar con px para tabletas, pero en algunos casos hay problemas (Galaxy 3, 4, Note, tiene igual o más px que Nexus 7). Ahora también puedo comprobar las pulgadas. Aquí hay una lista de muchas especificaciones de pantalla de dispositivos populares: en.wikipedia.org/wiki/List_of_displays_by_pixel_density
Pelanes
8
No utilice xdpi ni ydpi. Estos son opcionales y serán establecidos por el fabricante, no calculados. A menudo no se utilizan o son inexactos.
sturrockad
2
Usando su método para obtener el ancho en ppp, obtengo resultados diferentes según la orientación. por ejemplo, para Nexus 7: RETRATO: smallWidth = 600,9; PAISAJE: pequeño ancho = 552,8; ¿Cuál es la razón para eso?
Christopher Masser
3
La lógica if (smallestWidth > 600) { /* 7" */ } else if (smallestWidth > 720) { /* 10" */ }es defectuosa: la tableta de 10 "se reconoce como de 7". Me tomé la libertad de arreglar eso.
Jonik
21
En última instancia, seguí la respuestaresources.getConfiguration().smallestScreenWidthDp de DeeV, que es el único método que da el mismo valor tanto en vertical como en horizontal en mi Nexus 7 (600dp). Se agregó en el nivel de API 13.
Jonik
32

No hay nada que diga 7"o 10"AFAIK. Hay aproximadamente dos formas de obtener las dimensiones de la pantalla que utiliza el sistema al decodificar mapas de bits y otras cosas. Ambos se encuentran en el Resourcesobjeto de la aplicación que se encuentra en Context.

El primero es el Configurationobjeto que puede obtenerse getContext().getResources().getConfiguration(). En ella tienes:

Configuration#densityDpi - La densidad de pantalla de destino a la que se está representando, correspondiente al calificador de recursos de densidad.

Configuration#screenHeightDp - La altura actual del espacio de pantalla disponible, en unidades de dp, correspondiente al calificador de recursos de altura de pantalla.

Configuration#screenWidthDp - El ancho actual del espacio de pantalla disponible, en unidades de dp, correspondiente al calificador de recursos de ancho de pantalla.

Configuration#smallestScreenWidthDp - El tamaño de pantalla más pequeño que verá una aplicación en el funcionamiento normal, correspondiente al calificador de recursos de ancho de pantalla más pequeño.

Con esto, se puede utilizar más o menos las directrices de la pantalla para averiguar si el dispositivo está tirando de las respectivas carpetas de recursos especializados ( hdpi, xhdpi, large, xlarge, etc.).

Recuerde, estos son algunos de los depósitos:

  • Las pantallas xlarge son de al menos 960dp x 720dp
  • las pantallas grandes miden al menos 640dp x 480dp
  • las pantallas normales son de al menos 470dp x 320dp
  • las pantallas pequeñas miden al menos 426dp x 320dp

  • 320dp: una pantalla de teléfono típica (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc.).

  • 480dp: una tableta tweener como la Streak (480x800 mdpi).
  • 600dp: una tableta de 7 ”(600x1024 mdpi).
  • 720dp: una tableta de 10 ”(720x1280 mdpi, 800x1280 mdpi, etc.).

Más información

El segundo es el DisplayMetricsobjeto obtenido por getContext().getResources().getDisplayMetrics(). En eso tienes:

DisplayMetrics#density - La densidad lógica de la pantalla.

DisplayMetrics#densityDpi - La densidad de la pantalla expresada en puntos por pulgada.

DisplayMetrics#heightPixels - La altura absoluta de la pantalla en píxeles.

DisplayMetrics#widthPixels - El ancho absoluto de la pantalla en píxeles.

DisplayMetrics#xdpi - Los píxeles físicos exactos por pulgada de la pantalla en la dimensión X.

DisplayMetrics#ydpi - Los píxeles físicos exactos por pulgada de la pantalla en la dimensión Y.

Esto es útil si necesita un número exacto de píxeles de la pantalla en lugar de la densidad. Sin embargo, es importante tener en cuenta que se trata de todos los píxeles de la pantalla. No solo los que están disponibles para ti.

DeeV
fuente
4
+1, obtengo los mejores resultados con smallestScreenWidthDp. A diferencia de las otras soluciones, da el mismo valor en mi Nexus 7 (600dp) independientemente de la orientación . Como beneficio adicional, ¡también es el código más simple!
Jonik
1
Creo que esta sigue siendo la mejor manera porque debería coincidir con la notación sw ??? dp en las rutas de recursos. La consistencia es importante.
lilbyrdie
13

coloque este método en onResume () y puede verificar.

public double tabletSize() {

     double size = 0;
        try {

            // Compute screen size

            DisplayMetrics dm = context.getResources().getDisplayMetrics();

            float screenWidth  = dm.widthPixels / dm.xdpi;

            float screenHeight = dm.heightPixels / dm.ydpi;

            size = Math.sqrt(Math.pow(screenWidth, 2) +

                                 Math.pow(screenHeight, 2));

        } catch(Throwable t) {

        }

        return size;

    }

generalmente las tabletas comienzan después del tamaño de 6 pulgadas.

PiyushMishra
fuente
8

Lo anterior no siempre funciona cuando se cambia de retrato a paisaje.

Si tiene como objetivo el nivel de API 13+, es fácil como se describe anteriormente: use Configuration.smallestScreenWidthDp, luego pruebe en consecuencia:

resources.getConfiguration().smallestScreenWidthDp

De lo contrario, si puede pagar esto, utilice el siguiente método, que es un enfoque muy preciso para detectar 600 dp (como 6 ") frente a 720dp (como 10") al permitir que el sistema le diga:

1) Agregue a layout-sw600dp y layout-sw720dp (y si corresponde a su paisaje) una vista invisible con la identificación adecuada, por ejemplo:

Para 720, en layout-sw720dp:

<View android:id="@+id/sw720" android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>

Para 600, en layout-sw600dp:

<View android:id="@+id/sw600" android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>

2) Luego, en el código, por ejemplo, la Actividad, pruebe en consecuencia:

private void showFragment() {
    View v600 = (View) findViewById(R.id.sw600);
    View v720 = (View) findViewById(R.id.sw720);
    if (v600 != null || v720 !=null)
        albumFrag = AlbumGridViewFragment.newInstance(albumRefresh);
    else
        albumFrag = AlbumListViewFragment.newInstance(albumRefresh);
    getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.view_container, albumFrag)
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
        .commit();
}
CEO
fuente
4
No necesita crear un diseño separado, creo que puede tener un strings.xml separado según el tamaño, al tener diferentes carpetas de valores, como values-sw600dp, etc. Tener una cadena definida <string name = 'screenize' > 600dp </string> en la carpeta sw600dp, etc. Ni siquiera tiene que ser una cadena, podría estar en ints.xml o dimens.xml.
ajacian81
7

Excelente información, ¡justo lo que estaba buscando! Sin embargo, después de probar esto, descubrí que al usar las métricas mencionadas aquí, Nexus 7 (modelo 2012) informa que tiene dimensiones de 1280x736. También tengo un Motorola Xoom con Jelly Bean y reporta incorrectamente una resolución de 1280x752. Me topé con esta publicación aquí que lo confirma. Básicamente, en ICS / JB, los cálculos que utilizan las métricas mencionadas anteriormente parecen excluir las dimensiones de la barra de navegación. Un poco más de investigación me llevó a la respuesta de Frank Nguyen aquí que utiliza diferentes métodos que le darán las dimensiones de píxeles en bruto (o reales) de la pantalla. Mi prueba inicial ha demostrado que el siguiente código de Frank correclty informa las dimensiones en el Nexus 7 (modelo 2012 con JB) y mi Motorola Xoom con JB:

int width = 0, height = 0;
final DisplayMetrics metrics = new DisplayMetrics();
Display display = getWindowManager().getDefaultDisplay();
Method mGetRawH = null, mGetRawW = null;

try {
    // For JellyBeans and onward
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
        display.getRealMetrics(metrics);

        width = metrics.widthPixels;
        height = metrics.heightPixels;
    } else {
        mGetRawH = Display.class.getMethod("getRawHeight");
        mGetRawW = Display.class.getMethod("getRawWidth");

        try {
            width = (Integer) mGetRawW.invoke(display);
            height = (Integer) mGetRawH.invoke(display);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
} catch (NoSuchMethodException e3) {
    e3.printStackTrace();
}
Jason
fuente
3

Tengo dos dispositivos Android con la misma resolución.

Dispositivo1 -> resolución 480x800 diagonal tamaño de pantalla -> 4,7 pulgadas

Device2 -> resolución 480x800 diagonal tamaño de pantalla -> 4.0 pulgadas

Le da a ambos dispositivos un tamaño de pantalla diagonal -> 5.8

la solución a tu problema es ...

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width=dm.widthPixels;
int height=dm.heightPixels;
int dens=dm.densityDpi;
double wi=(double)width/(double)dens;
double hi=(double)height/(double)dens;
double x = Math.pow(wi,2);
double y = Math.pow(hi,2);
double screenInches = Math.sqrt(x+y);

ver detalles aquí ..

AndroidGeek
fuente
2

La forma en que Android especifica los tamaños de pantalla es a través de cuatro tamaños generalizados: pequeño , normal , grande y xlarge .

Mientras que la documentación de Android indica que los grupos de tamaño están obsoletos

... estos grupos de tamaños están obsoletos a favor de una nueva técnica para administrar los tamaños de pantalla en función del ancho de pantalla disponible. Si está desarrollando para Android 3.2 y superior, consulte [Declaración de diseños de tableta para Android 3.2] (hdpi (alto) ~ 240 ppp) para obtener más información.

Generalmente, el calificador de tamaño grande especifica una tableta de 7 ". Y un calificador de tamaño de xlarge especifica una tableta de 10":

ingrese la descripción de la imagen aquí

Lo bueno de activar el calificador de tamaño es que puede garantizar que sus activos y su código coincidan sobre qué activo usar o qué ruta de código activar.

Para recuperar el calificador de tamaño en el código, realice las siguientes llamadas:

int sizeLarge = SCREENLAYOUT_SIZE_LARGE // For 7" tablet
boolean is7InchTablet = context.getResources().getConfiguration()
    .isLayoutSizeAtLeast(sizeLarge);

int sizeXLarge = SCREENLAYOUT_SIZE_XLARGE // For 10" tablet
boolean is10InchTablet = context.getResources().getConfiguration()
    .isLayoutSizeAtLeast(sizeXLarge);
Benjamín
fuente
2

Puede usar el método a continuación para obtener el tamaño de la pantalla en pulgadas, basándose en eso, simplemente puede verificar qué tableta o teléfono es el dispositivo.

private static double checkDimension(Context context) {

    WindowManager windowManager = ((Activity)context).getWindowManager();
    Display display = windowManager.getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    display.getMetrics(displayMetrics);

    // since SDK_INT = 1;
    int mWidthPixels = displayMetrics.widthPixels;
    int mHeightPixels = displayMetrics.heightPixels;

    // includes window decorations (statusbar bar/menu bar)
    try
    {
        Point realSize = new Point();
        Display.class.getMethod("getRealSize", Point.class).invoke(display, realSize);
        mWidthPixels = realSize.x;
        mHeightPixels = realSize.y;
    }
    catch (Exception ignored) {}

    DisplayMetrics dm = new DisplayMetrics();
    windowManager.getDefaultDisplay().getMetrics(dm);
    double x = Math.pow(mWidthPixels/dm.xdpi,2);
    double y = Math.pow(mHeightPixels/dm.ydpi,2);
    double screenInches = Math.sqrt(x+y);
    Log.d("debug","Screen inches : " + screenInches);
    return screenInches;
}
Ashish Rajvanshi
fuente
2

Estaba almacenando un valor en la carpeta de valores que me da una pantalla de 7 pulgadas o 10 inc, pero podemos hacerlo para cualquier dispositivo que use la carpeta de valores.

como crear una carpeta de valores 2 diferentes para 2 dispositivos diferentes. Pero esto depende del requisito.

sharma_kunal
fuente
1

Tendrá que hacer un pequeño cálculo utilizando los datos proporcionados por la clase DisplayMetrics .

Tiene heightPixel y widthPixels (la resolución de pantalla en píxeles)

Necesita la diagonal ya que el 'tamaño de pantalla en pulgadas' siempre describe la longitud de la diagonal. Puede obtener la diagonal de la pantalla en píxeles (usando Pythagore)

diagonalPixel = √ (heightPixel² + widthPixels²)

luego puede convertir el valor de píxel a pulgadas gracias al valor de densidadDPI:

inchDiag = diagonalPixel / densidadDPI.

Espero no haber cometido errores aquí, tenga en cuenta que los valores que obtiene de la clase DisplayMetrics los da el constructor, parece (en casos muy raros) que no están bien configurados de acuerdo con el material físico ...

Esto le dará el tamaño físico de la pantalla, pero probablemente no sea la mejor manera de administrar varios diseños. Más sobre estos temas

Guian
fuente
1

De otra manera:

  • Cree 2 carpetas más: valores-grande + valores-xlarge

  • Poner: <string name="screentype">LARGE</string>en la carpeta de valores grandes (strings.xml)

  • Poner: <string name="screentype">XLARGE</string>en la carpeta values-xlarge (strings.xml)

  • En codigo:

    String mType = getString (R.string.screentype);

    if (mType! = null && mType.equals ("GRANDE") {

    // de 4 ~ 7 pulgadas

    } else if (mType! = null && mType.equals ("XLARGE") {

    // de 7 ~ 10 pulgadas

    }

Frank Nguyen
fuente
1

¡Voila! 😀 Esto es todo lo que necesita para distinguir las tabletas de los teléfonos

1. Función auxiliar para obtener el ancho de la pantalla:

private float getScreenWidth() {
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    return Math.min(metrics.widthPixels, metrics.heightPixels) / metrics.density;
}

2. Función para averiguar si un dispositivo es una tableta

boolean isTablet() {
    return getScreenWidth() >= 600;
}

3. Finalmente, si está buscando realizar diferentes operaciones para diferentes tamaños de dispositivos:

boolean is7InchTablet() {
    return getScreenWidth() >= 600 && getScreenWidth() < 720;
}

boolean is10InchTablet() {
    return getScreenWidth() >= 720;
}
Sagar
fuente
0

Aquí algunas extensiones útiles de kotlin:


    fun DisplayMetrics.isTablet(): Boolean {
        return screenWith() >= 600
    }

    fun DisplayMetrics.is7InchTablet(): Boolean {
        return screenWith() >= 600 && screenWith() < 720
    }

    fun DisplayMetrics.is10InchTablet(): Boolean {
        return screenWith() >= 720
    }

    fun DisplayMetrics.screenWith(): Float {
        return widthPixels.coerceAtMost(heightPixels) / density
    }
Danimate
fuente
¡Eso funciona! Pero debe usar DisplayMetrics adecuado, por ejemplo, desde Resourcesen Context: resources.displayMetrics.isTablet() o desde el WindowManagerque se almacenó en Activity: val displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getMetrics(displayMetrics) displayMetrics.isTablet()
Akbolat SSS