Détecter les tablettes de 7 et 10 pouces par programmation

93

Existe-t-il un moyen de savoir par programme si l'appareil sur lequel l'application est installée est une tablette de 7 pouces ou une tablette de 10 pouces?

Débutant
la source
Par exemple: layout-sw600dp recherche la plus petite taille de largeur de 600dp.
Rookie
Je comprends cela, mais que recherchez-vous par programme?
Geobits
J'ai besoin de récupérer ces périphériques par programme ... car il y a des propriétés que je ne peux pas définir dans xml ... ces propriétés sont définies dans le code lui-même ... donc si je mets simplement le code, il s'appliquera à tous les périphériques ... mais Je ne veux pas que ..
Rookie
@Raghav avez-vous essayé avec la matrice d'affichage pour obtenir la taille de l'écran et ensuite vous pouvez comparer. Bien que ce ne soit pas une manière propre mais vous pouvez utiliser.
PiyushMishra
Vous pouvez obtenir les dimensions de votre écran et travailler à partir de là ... stackoverflow.com/questions/1016896/…
Raj

Réponses:

234

Vous pouvez utiliser le DisplayMetricspour obtenir de nombreuses informations sur l'écran sur lequel votre application s'exécute.

Tout d'abord, nous créons un DisplayMetricsobjet métrique:

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

À partir de là, nous pouvons obtenir les informations nécessaires pour dimensionner l'affichage:

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

Celui-ci renverra la valeur absolue de la largeur et de la hauteur en pixels, donc 1280x720 pour le Galaxy SIII, le Galaxy Nexus etc.

Cela n'est généralement pas utile en soi, car lorsque nous travaillons sur des appareils Android, nous préférons généralement travailler dans des pixels indépendants de la densité, dip.

Vous obtenez densityà metricsnouveau l' utilisation de l'écran , sous la forme d'un facteur d'échelle pour l'appareil, basé sur les ressources de conception Android pour mdpi, hdpietc. Échelles DPI

float scaleFactor = metrics.density;

À partir de ce résultat, nous pouvons calculer la quantité de pixels indépendants de la densité pour une certaine hauteur ou largeur.

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

Le résultat que vous en tirez vous aidera à décider du type d'écran sur lequel vous travaillez en conjonction avec les exemples de configuration Android , qui vous donnent le dp relatif pour chaque taille d'écran:

  • 320dp: un écran de téléphone typique (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc.).
  • 480dp: une tablette tweener comme la Streak (480x800 mdpi).
  • 600 ppp: une tablette de 7 pouces (600 x 1 024 mdpi).
  • 720dp: une tablette 10 pouces (720x1280 mdpi, 800x1280 mdpi, etc.).

En utilisant les informations ci-dessus, nous savons que si la plus petite largeur de l'appareil est supérieure à 600dp, l'appareil est une tablette de 7 ", si elle est supérieure à 720dp, l'appareil est une tablette de 10".

Nous pouvons calculer la plus petite largeur en utilisant la minfonction de Mathclasse, en passant le heightDpet le widthDppour renvoyer le smallestWidth.

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

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

Cependant, cela ne vous donne pas toujours une correspondance exacte, en particulier lorsque vous travaillez avec des tablettes obscures qui pourraient déformer leur densité en hdpi alors que ce n'est pas le cas, ou qui pourraient ne faire que 800 x 480 pixels tout en restant sur un écran de 7 pouces .

En plus de ces méthodes, si vous avez besoin de connaître les dimensions exactes d'un appareil en pouces, vous pouvez également le calculer en utilisant la metricsméthode du nombre de pixels par pouce de l'écran.

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

Vous pouvez utiliser la connaissance du nombre de pixels dans chaque pouce de l'appareil et de la quantité de pixels au total pour calculer le nombre de pouces de l'appareil.

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

Cela renverra la hauteur et la largeur de l'appareil en pouces. Encore une fois, ce n'est pas toujours très utile pour déterminer de quel type d'appareil il s'agit, car la taille annoncée d'un appareil est la diagonale, tout ce que nous avons est la hauteur et la largeur.

Cependant, on sait aussi que compte tenu de la hauteur d'un triangle et de la largeur, on peut utiliser le théorème de Pythagore pour calculer la longueur de l'hypoténuse (dans ce cas, la taille de la diagonale de l'écran).

//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));

À partir de là, nous pouvons déterminer si l'appareil est une tablette ou non:

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

Et c'est ainsi que vous calculez le type d'appareil avec lequel vous travaillez.

Sean O'Toole
la source
3
Excellents conseils Sean. J'avais l'habitude de vérifier avec px pour les tablettes, mais dans certains cas, il y a des problèmes (Galaxy 3, 4, Note, a un px égal ou supérieur à Nexus 7). Maintenant, je peux également vérifier le pouce. Voici une liste de nombreuses spécifications d'écran des appareils populaires: en.wikipedia.org/wiki/List_of_displays_by_pixel_density
Pelanes
8
N'utilisez pas xdpi ou ydpi. Ceux-ci sont facultatifs et seront définis par le fabricant et non calculés. Ils sont souvent inutilisés ou inexacts.
sturrockad
2
En utilisant votre méthode pour obtenir la largeur en dpi, j'obtiens des résultats différents selon l'orientation. par exemple pour Nexus 7: PORTRAIT: smallestWidth = 600,9; PAYSAGE: smallestWidth = 552,8; Quelle est la raison de ceci?
Christopher Masser
3
La logique if (smallestWidth > 600) { /* 7" */ } else if (smallestWidth > 720) { /* 10" */ }est imparfaite: la tablette 10 "est reconnue comme 7". J'ai pris la liberté de résoudre ce problème.
Jonik
21
En fin de compte, je suis allé avec la réponseresources.getConfiguration().smallestScreenWidthDp de DeeV qui est la seule méthode qui donne la même valeur en portrait et en paysage sur mon Nexus 7 (600dp). Il a été ajouté au niveau d'API 13.
Jonik
32

Il n'y a rien qui dit 7"ou 10"AFAIK. Il existe à peu près deux façons d'obtenir les dimensions de l'écran que le système utilise lors du décodage des bitmaps, etc. Ils se trouvent tous les deux dans l' Resourcesobjet de l'application dans le fichier Context.

Le premier est l' Configurationobjet qui peut être obtenu par getContext().getResources().getConfiguration(). Vous y trouverez:

Configuration#densityDpi - La densité de l'écran cible en cours de rendu, correspondant au qualificatif de ressource de densité.

Configuration#screenHeightDp - La hauteur actuelle de l'espace d'écran disponible, en unités dp, correspondant au qualificatif de ressource de hauteur d'écran.

Configuration#screenWidthDp - La largeur actuelle de l'espace d'écran disponible, en unités dp, correspondant au qualificatif de ressource de largeur d'écran.

Configuration#smallestScreenWidthDp - La plus petite taille d'écran qu'une application verra en fonctionnement normal, correspondant au plus petit qualificatif de ressources de largeur d'écran.

Avec cela, vous pouvez très bien utiliser les directives à l'écran pour savoir si votre appareil tire à partir des dossiers de ressources spécialisées respectives ( hdpi, xhdpi, large, xlarge, etc.).

N'oubliez pas que voici quelques-uns des seaux:

  • Les écrans xlarge mesurent au moins 960dp x 720dp
  • les grands écrans mesurent au moins 640dp x 480dp
  • les écrans normaux mesurent au moins 470dp x 320dp
  • les petits écrans mesurent au moins 426dp x 320dp

  • 320dp: un écran de téléphone typique (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc.).

  • 480dp: une tablette tweener comme la Streak (480x800 mdpi).
  • 600 ppp: une tablette de 7 pouces (600 x 1 024 mdpi).
  • 720dp: une tablette 10 pouces (720x1280 mdpi, 800x1280 mdpi, etc.).

Plus d'informations

Le second est l' DisplayMetricsobjet obtenu par getContext().getResources().getDisplayMetrics(). En cela, vous avez:

DisplayMetrics#density - La densité logique de l'affichage.

DisplayMetrics#densityDpi - La densité de l'écran exprimée en points par pouce.

DisplayMetrics#heightPixels - La hauteur absolue de l'affichage en pixels.

DisplayMetrics#widthPixels - La largeur absolue de l'affichage en pixels.

DisplayMetrics#xdpi - Les pixels physiques exacts par pouce de l'écran dans la dimension X.

DisplayMetrics#ydpi - Les pixels physiques exacts par pouce de l'écran dans la dimension Y.

Ceci est pratique si vous avez besoin d'un nombre exact de pixels de l'écran plutôt que d'une densité. Cependant, il est important de noter que ce sont tous les pixels de l'écran. Pas seulement ceux dont vous disposez.

DeeV
la source
4
+1, j'obtiens les meilleurs résultats avec smallestScreenWidthDp. Contrairement aux autres solutions, il donne la même valeur sur mon Nexus 7 (600dp) quelle que soit l'orientation . En prime, c'est aussi le code le plus simple!
Jonik
1
Je pense que cela continue d'être le meilleur moyen car il devrait correspondre à la notation sw ??? dp sur les chemins de ressources. La cohérence est importante.
lilbyrdie
13

placez cette méthode dans onResume () et pouvez vérifier.

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;

    }

généralement les comprimés commencent après une taille de 6 pouces.

PiyushMishra
la source
8

Ce qui précède ne fonctionne pas toujours lors du passage du portrait au paysage.

Si vous ciblez le niveau d'API 13+, c'est facile comme décrit ci-dessus - utilisez Configuration.smallestScreenWidthDp, puis testez en conséquence:

resources.getConfiguration().smallestScreenWidthDp

Sinon, si vous pouvez vous le permettre, utilisez la méthode suivante qui est une approche très précise pour détecter 600dp (comme 6 ") contre 720dp (comme 10") en laissant le système vous dire:

1) Ajoutez à layout-sw600dp et layout-sw720dp (et si applicable son paysage) une vue invisible avec l'ID approprié, par exemple:

Pour 720, sur layout-sw720dp:

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

Pour 600, sur layout-sw600dp:

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

2) Ensuite sur le code, par exemple, l'activité, testez en conséquence:

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();
}
PDG
la source
4
Vous n'avez pas besoin de créer une mise en page séparée, je pense que vous pouvez simplement avoir un strings.xml séparé en fonction de la taille, en ayant des dossiers de valeurs différents, comme values-sw600dp, etc. Avoir une chaîne définie <string name = 'screensize' > 600dp </string> dans le dossier sw600dp, etc. Il n'est même pas nécessaire que ce soit une chaîne, cela peut être dans ints.xml ou dimens.xml.
ajacian81
7

Excellente information, exactement ce que je cherchais! Cependant, après avoir essayé cela, j'ai constaté que lors de l'utilisation des métriques mentionnées ici, le Nexus 7 (modèle 2012) rapportait des dimensions de 1280x736. J'ai aussi un Motorola Xoom exécutant Jelly Bean et il signale à tort une résolution de 1280x752. Je suis tombé sur ce post ici qui le confirme. Fondamentalement, dans ICS / JB, les calculs utilisant les mesures mentionnées ci-dessus semblent exclure les dimensions de la barre de navigation. D'autres recherches m'ont conduit à la réponse de Frank Nguyen ici qui utilise différentes méthodes qui vous donneront les dimensions brutes (ou réelles) des pixels de l'écran. Mes premiers tests ont montré que le code suivant de Frank correclty indique les dimensions du Nexus 7 (modèle 2012 runnin JB) et de mon Motorola Xoom exécutant 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
la source
3

J'ai deux appareils Android avec la même résolution

Device1 -> résolution 480x800 diagonale de l'écran -> 4,7 pouces

Device2 -> résolution 480x800 diagonale de l'écran -> 4,0 pouces

Il donne à la fois la taille de l'écran diagonale de l'appareil -> 5,8

la solution à votre problème est ..

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);

voir les détails ici ..

AndroidGeek
la source
2

La façon dont Android spécifie les tailles d'écran passe par quatre tailles généralisées: petite , normale , grande et xlarge .

Alors que la documentation Android indique que les groupes de tailles sont obsolètes

... ces groupes de tailles sont déconseillés au profit d'une nouvelle technique de gestion des tailles d'écran en fonction de la largeur d'écran disponible. Si vous développez pour Android 3.2 et versions ultérieures, consultez [Déclaration des dispositions de tablette pour Android 3.2] (hdpi (élevé) ~ 240 dpi) pour plus d'informations.

En général, le qualificatif de taille large spécifie une tablette de 7 pouces. Et un qualificateur de taille xlarge indique une tablette de 10 pouces:

entrez la description de l'image ici

La bonne chose à propos du déclenchement sur le qualificatif de taille, c'est que vous pouvez garantir que vos actifs et votre code sont en accord sur l'actif à utiliser ou le chemin du code à activer.

Pour récupérer le qualificatif de taille dans le code, effectuez les appels suivants:

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);
Benjamin
la source
2

Vous pouvez utiliser la méthode ci-dessous pour obtenir la taille de l'écran en pouces, en fonction de cela, vous pouvez simplement vérifier la tablette ou le téléphone de l'appareil.

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
la source
2

Je stockais une valeur dans le dossier des valeurs qui me donne un écran de 7 pouces ou 10 inc, mais nous pouvons le faire pour tout appareil utilisant le dossier de valeurs.

comme créer un dossier de valeurs différentes-2 pour différents périphériques-2. Mais cela dépend de l'exigence.

sharma_kunal
la source
1

Vous devrez faire un peu de calcul en utilisant les données fournies par la classe DisplayMetrics .

Vous avez heightPixel et widthPixels (la résolution d'écran en pixels)

Vous avez besoin de la diagonale car la «taille de l'écran en pouces» décrit toujours la longueur de la diagonale. Vous pouvez obtenir la diagonale de l'écran en pixels (en utilisant pythagore)

diagonalPixel = √ (hauteurPixel² + largeurPixels²)

alors vous pouvez convertir la valeur du pixel en pouces grâce à la valeur densitéDPI:

inchDiag = diagonalPixel / densitéDPI.

J'espère ne pas avoir fait d'erreur ici, sachez que les valeurs que vous obtenez de la classe DisplayMetrics sont données par le constructeur, il semble (dans de très rares cas) qu'elles ne sont pas bien définies en fonction du matériau physique ...

Cela vous donnera la taille physique de l'écran, mais ce n'est probablement pas la meilleure façon de gérer plusieurs mises en page. En savoir plus sur ces sujets

Guyane
la source
1

Autrement:

  • Créez 2 autres dossiers: values-large + values-xlarge

  • Mettre: <string name="screentype">LARGE</string>dans le dossier values-large (strings.xml)

  • Mettre: <string name="screentype">XLARGE</string>dans le dossier values-xlarge (strings.xml)

  • Dans du code:

    Chaîne mType = getString (R.string.screentype);

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

    // de 4 ~ 7 pouces

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

    // de 7 ~ 10 pouces

    }

Frank Nguyen
la source
1

Voila! 😀 C'est tout ce dont vous aurez besoin pour distinguer les tablettes des téléphones

1. Fonction d'aide pour obtenir la largeur de l'écran:

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

2. Fonction permettant de déterminer si un appareil est une tablette

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

3. Enfin, si vous souhaitez effectuer différentes opérations pour différentes tailles d'appareils:

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

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

Voici quelques extensions kotlin utiles:


    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
la source
Ça marche! Mais vous devez utiliser DisplayMetrics approprié, par exemple à partir Resourcesde Context: resources.displayMetrics.isTablet() ou à partir de WindowManagerlaquelle stocké dans Activity: val displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getMetrics(displayMetrics) displayMetrics.isTablet()
Akbolat SSS