Erkennen Sie 7-Zoll- und 10-Zoll-Tablets programmgesteuert

93

Gibt es eine Möglichkeit, programmgesteuert festzustellen, ob es sich bei dem Gerät, auf dem die App installiert ist, um ein 7-Zoll-Tablet oder ein 10-Zoll-Tablet handelt?

Anfänger
quelle
Zum Beispiel: layout-sw600dp sucht nach der kleinsten Breite von 600dp.
Rookie
Ich verstehe das, aber wonach suchen Sie programmatisch?
Geobits
Ich muss diese Geräte programmgesteuert abrufen. Da es einige Eigenschaften gibt, die ich nicht in XML definieren kann. Diese Eigenschaften sind im Code selbst definiert. Wenn ich also einfach den Code eingebe, gilt er für alle Geräte. Aber Ich will das nicht ..
Rookie
@Raghav haben Sie mit Display-Matrix versucht, die Größe des Bildschirms zu erhalten und dann können Sie vergleichen. Es ist zwar kein sauberer Weg, aber Sie können verwenden.
PiyushMishra
Sie könnten Ihre Bildschirmabmessungen erhalten und von dort aus trainieren
Raj

Antworten:

234

Mit können Sie DisplayMetricseine ganze Reihe von Informationen über den Bildschirm abrufen, auf dem Ihre App ausgeführt wird.

Zuerst erstellen wir ein DisplayMetricsMetrikobjekt:

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

Daraus können wir die Informationen abrufen, die für die Größe des Displays erforderlich sind:

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

Dies gibt den absoluten Wert der Breite und der Höhe in Pixel zurück, also 1280x720 für das Galaxy SIII, das Galaxy Nexus usw.

Dies ist für sich genommen normalerweise nicht hilfreich, da wir bei der Arbeit mit Android-Geräten normalerweise lieber in dichteunabhängigen Pixeln arbeiten.

Sie erhalten die densitydes Bildschirms metricswieder, in Form eines Skalierungsfaktors für das Gerät, das auf der Basis Android Design - Ressourcen für mdpi, hdpiusw. DPI-Skalen

float scaleFactor = metrics.density;

Aus diesem Ergebnis können wir die Menge der dichteunabhängigen Pixel berechnen, die für eine bestimmte Höhe oder Breite vorhanden sind.

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

Das Ergebnis, das Sie daraus erhalten, hilft Ihnen bei der Entscheidung, mit welchem ​​Bildschirmtyp Sie in Verbindung mit den Android-Konfigurationsbeispielen arbeiten , die Ihnen den relativen dp für jede Bildschirmgröße geben:

  • 320 dp: Ein typischer Telefonbildschirm (240 x 320 ldpi, 320 x 480 mdpi, 480 x 800 hdpi usw.).
  • 480dp: Ein Tweener-Tablet wie das Streak (480x800 mdpi).
  • 600 dp: eine 7-Zoll-Tablette (600 x 1024 mdpi).
  • 720 dp: ein 10-Zoll-Tablet (720 x 1280 mdpi, 800 x 1280 mdpi usw.).

Anhand der obigen Informationen wissen wir, dass das Gerät ein 7-Zoll-Tablet ist, wenn die kleinste Breite des Geräts größer als 600 dp ist. Wenn es größer als 720 dp ist, ist das Gerät ein 10-Zoll-Tablet.

Wir können die kleinste Breite mit der minFunktion der MathKlasse berechnen, indem wir das heightDpund das übergeben widthDp, um das zurückzugeben smallestWidth.

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

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

Dies gibt Ihnen jedoch nicht immer eine genaue Übereinstimmung, insbesondere wenn Sie mit obskuren Tablets arbeiten, deren Dichte möglicherweise nicht als HDPI dargestellt wird, wenn dies nicht der Fall ist, oder die möglicherweise nur 800 x 480 Pixel groß sind und sich dennoch auf einem 7-Zoll-Bildschirm befinden .

Wenn Sie zusätzlich zu diesen Methoden die genauen Abmessungen eines Geräts in Zoll kennen müssen, können Sie dies auch anhand der metricsMethode für die Anzahl der Pixel pro Zoll des Bildschirms ermitteln.

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

Sie können das Wissen über die Anzahl der Pixel in jedem Zoll des Geräts und die Anzahl der Pixel insgesamt verwenden, um herauszufinden, wie viele Zoll das Gerät hat.

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

Dies gibt die Höhe und Breite des Geräts in Zoll zurück. Dies ist wiederum nicht immer hilfreich, um festzustellen, um welchen Gerätetyp es sich handelt, da die angegebene Größe eines Geräts die Diagonale ist. Wir haben lediglich die Höhe und die Breite.

Wir wissen jedoch auch, dass wir angesichts der Höhe eines Dreiecks und der Breite den Satz von Pythagoras verwenden können, um die Länge der Hypotenuse (in diesem Fall die Größe der Bildschirmdiagonale) zu berechnen.

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

Daraus können wir herausfinden, ob das Gerät ein Tablet ist oder nicht:

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

Und so berechnen Sie, mit welcher Art von Gerät Sie arbeiten.

Sean O'Toole
quelle
3
Hervorragende Tipps Sean. Früher habe ich bei px nach Tablets gesucht, aber in einigen Fällen gibt es Probleme (Galaxy 3, 4, Note, hat gleich oder mehr px als Nexus 7). Jetzt kann ich auch nach Zoll suchen. Hier ist eine Liste der gängigen Bildschirmspezifikationen für Geräte: en.wikipedia.org/wiki/List_of_displays_by_pixel_density
Pelanes
8
Verwenden Sie kein xdpi oder ydpi. Diese sind optional und werden vom Hersteller eingestellt, nicht berechnet. Sie sind oft entweder unbenutzt oder ungenau.
Sturrockad
2
Wenn Sie Ihre Methode verwenden, um die Breite in dpi zu erhalten, erhalte ich je nach Ausrichtung unterschiedliche Ergebnisse. zB für Nexus 7: PORTRAIT: kleinste Breite = 600,9; LANDSCHAFT: kleinste Breite = 552,8; Was ist der Grund dafür?
Christopher Masser
3
Die Logik if (smallestWidth > 600) { /* 7" */ } else if (smallestWidth > 720) { /* 10" */ }ist fehlerhaft: 10 "Tablet wird als 7" erkannt. Ich habe mir erlaubt, das zu beheben.
Jonik
21
Letztendlich habe ich mich für die Antwortresources.getConfiguration().smallestScreenWidthDp von DeeV entschieden, die die einzige Methode ist, die auf meinem Nexus 7 (600 dp) sowohl im Hoch- als auch im Querformat den gleichen Wert liefert. Es wurde in API Level 13 hinzugefügt.
Jonik
32

Es gibt nichts, was sagt 7"oder 10"AFAIK. Es gibt ungefähr zwei Möglichkeiten, um Bildschirmabmessungen zu erhalten, die das System beim Dekodieren von Bitmaps und so weiter verwendet. Sie befinden sich beide im ResourcesObjekt der Anwendung in der Context.

Das erste ist das ConfigurationObjekt, das von erhalten werden kann getContext().getResources().getConfiguration(). Darin haben Sie:

Configuration#densityDpi - Die Zielbildschirmdichte, auf die gerendert wird, entspricht dem Qualifikationsmerkmal für die Dichteressource.

Configuration#screenHeightDp - Die aktuelle Höhe des verfügbaren Bildschirmbereichs in dp-Einheiten, die dem Ressourcenqualifizierer für die Bildschirmhöhe entspricht.

Configuration#screenWidthDp - Die aktuelle Breite des verfügbaren Bildschirmbereichs in dp-Einheiten, entsprechend dem Ressourcenqualifizierer für die Bildschirmbreite.

Configuration#smallestScreenWidthDp - Die kleinste Bildschirmgröße, die eine Anwendung im normalen Betrieb sieht, entspricht dem Ressourcenqualifizierer für die kleinste Bildschirmbreite.

Damit kann man so ziemlich die Bildschirm - Richtlinien verwenden , um herauszufinden , ob Ihr Gerät aus den jeweiligen Fachressourcenordnern zieht ( hdpi, xhdpi, large, xlarge, etc.).

Denken Sie daran, dies sind einige der Eimer:

  • xlarge-Bildschirme haben mindestens 960 dp x 720 dp
  • Große Bildschirme haben eine Größe von mindestens 640 dp x 480 dp
  • Normale Bildschirme sind mindestens 470 dp x 320 dp
  • kleine Bildschirme sind mindestens 426dp x 320dp

  • 320 dp: Ein typischer Telefonbildschirm (240 x 320 ldpi, 320 x 480 mdpi, 480 x 800 hdpi usw.).

  • 480dp: Ein Tweener-Tablet wie das Streak (480x800 mdpi).
  • 600 dp: eine 7-Zoll-Tablette (600 x 1024 mdpi).
  • 720 dp: ein 10-Zoll-Tablet (720 x 1280 mdpi, 800 x 1280 mdpi usw.).

Mehr Info

Das zweite ist das DisplayMetricsObjekt, das von erhalten wird getContext().getResources().getDisplayMetrics(). Darin haben Sie:

DisplayMetrics#density - Die logische Dichte der Anzeige.

DisplayMetrics#densityDpi - Die Bildschirmdichte, ausgedrückt als Punkte pro Zoll.

DisplayMetrics#heightPixels - Die absolute Höhe der Anzeige in Pixel.

DisplayMetrics#widthPixels - Die absolute Breite der Anzeige in Pixel.

DisplayMetrics#xdpi - Die genauen physischen Pixel pro Zoll des Bildschirms in der X-Dimension.

DisplayMetrics#ydpi - Die genauen physischen Pixel pro Zoll des Bildschirms in der Y-Dimension.

Dies ist praktisch, wenn Sie die genaue Pixelanzahl des Bildschirms anstelle der Dichte benötigen. Es ist jedoch wichtig zu beachten, dass dies alle Pixel des Bildschirms sind. Nicht nur die, die Ihnen zur Verfügung stehen.

DeeV
quelle
4
+1, ich bekomme die besten Ergebnisse mit smallestScreenWidthDp. Im Gegensatz zu den anderen Lösungen bietet es auf meinem Nexus 7 (600 dp) unabhängig von der Ausrichtung den gleichen Wert . Als Bonus ist es auch der einfachste Code!
Jonik
1
Ich denke, dies ist weiterhin der beste Weg, da es mit der sw ??? dp-Notation auf Ressourcenpfaden übereinstimmen sollte . Konsistenz ist wichtig.
Lilbyrdie
13

Platzieren Sie diese Methode in onResume () und können Sie sie überprüfen.

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;

    }

Im Allgemeinen beginnen Tabletten nach 6 Zoll Größe.

PiyushMishra
quelle
8

Das Obige funktioniert nicht immer, wenn Sie zwischen Hoch- und Querformat wechseln.

Wenn Sie auf API-Level 13+ abzielen, ist dies wie oben beschrieben einfach. Verwenden Sie Configuration.smallestScreenWidthDp und testen Sie entsprechend:

resources.getConfiguration().smallestScreenWidthDp

Wenn Sie sich dies leisten können, verwenden Sie die folgende Methode, die einen sehr genauen Ansatz darstellt, um 600 dp (wie 6 ") gegenüber 720 dp (wie 10") zu erkennen, indem Sie sich vom System informieren lassen:

1) Fügen Sie layout-sw600dp und layout-sw720dp (und gegebenenfalls die Landschaft) eine unsichtbare Ansicht mit der richtigen ID hinzu, zum Beispiel:

Für 720 auf layout-sw720dp:

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

Für 600 auf layout-sw600dp:

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

2) Testen Sie dann auf dem Code, zum Beispiel der Aktivität, entsprechend:

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
quelle
4
Sie müssen kein separates Layout erstellen. Ich glaube, Sie können nur eine separate Zeichenfolge.xml basierend auf der Größe erstellen, indem Sie verschiedene Werteordner wie values-sw600dp usw. haben. Definieren Sie eine Zeichenfolge <string name = 'screenize'. > 600dp </ string> im Ordner sw600dp usw. Es muss nicht einmal eine Zeichenfolge sein, sondern kann sich in ints.xml oder dimension.xml befinden.
Ajacian81
7

Tolle Informationen, genau das, wonach ich gesucht habe! Nachdem ich dies ausprobiert hatte, stellte ich jedoch fest, dass das Nexus 7 (Modell 2012) bei Verwendung der hier genannten Metriken die Abmessungen 1280 x 736 aufweist. Ich habe auch ein Motorola Xoom mit Jelly Bean und es meldet fälschlicherweise eine Auflösung von 1280x752. Ich stolperte über dieses Thema hier , die dies bestätigt. Grundsätzlich scheinen in ICS / JB die Berechnungen unter Verwendung der oben genannten Metriken die Abmessungen der Navigationsleiste auszuschließen. Weitere Nachforschungen führten mich zu Frank Nguyens Antwort hier , bei der verschiedene Methoden verwendet werden, um die rohen (oder realen) Pixelabmessungen des Bildschirms zu ermitteln. Meine ersten Tests haben gezeigt, dass der folgende Code von Frank Correclty die Abmessungen des Nexus 7 (Modell 2012 mit JB) und meines Motorola Xoom mit JB angibt:

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
quelle
3

Ich habe zwei Android-Geräte mit der gleichen Auflösung

Gerät1 -> Auflösung 480x800 Bildschirmdiagonale -> 4,7 Zoll

Gerät2 -> Auflösung 480x800 Bildschirmdiagonale -> 4,0 Zoll

Es gibt beide Bildschirmdiagonale Bildschirmgröße -> 5,8

Die Lösung für Ihr Problem ist ..

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

siehe Details hier ..

Zar E Ahmer
quelle
2

Die Art und Weise, wie Android Bildschirmgrößen angibt , erfolgt über vier allgemeine Größen: klein , normal , groß und groß .

In der Android- Dokumentation heißt es, dass die Größengruppen veraltet sind

... diese Größengruppen werden zugunsten einer neuen Technik zum Verwalten von Bildschirmgrößen basierend auf der verfügbaren Bildschirmbreite nicht mehr empfohlen. Wenn Sie für Android 3.2 und höher entwickeln, finden Sie weitere Informationen unter [Deklarieren von Tablet-Layouts für Android 3.2] (hdpi (hoch) ~ 240 dpi).

Im Allgemeinen gibt der Größenqualifizierer groß ein 7- Zoll- Tablet an. Ein Größenqualifizierer von xlarge gibt ein 10- Zoll- Tablet an:

Geben Sie hier die Bildbeschreibung ein

Das Schöne am Auslösen des Größenqualifizierers ist, dass Sie sicherstellen können, dass Ihre Assets und Ihr Code übereinstimmen, welches Asset verwendet oder welcher Codepfad aktiviert werden soll.

Führen Sie die folgenden Aufrufe aus, um das Größenqualifikationsmerkmal im Code abzurufen:

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
quelle
2

Mit der folgenden Methode können Sie die Bildschirmgröße in Zoll ermitteln. Auf dieser Grundlage können Sie einfach überprüfen, um welches Tablet oder Telefon es sich bei dem Gerät handelt.

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
quelle
2

Ich habe einen Wert im Werteordner gespeichert , der mir einen Bildschirm von 7 Zoll oder 10 Zoll anzeigt, aber wir können dies für jedes Gerät tun, das den Werteordner verwendet.

Erstellen Sie beispielsweise einen Ordner mit unterschiedlichen 2 Werten für unterschiedliche 2 Geräte. Aber diese Sache hängt von der Anforderung ab.

sharma_kunal
quelle
1

Sie müssen ein wenig mit den Daten der DisplayMetrics- Klasse rechnen .

Sie haben heightPixel und widthPixels (die Bildschirmauflösung in Pixel)

Sie benötigen die Diagonale, da die 'Zoll-Bildschirmgröße' immer die diagonale Länge beschreibt. Sie können die Bildschirmdiagonale in Pixel erhalten (mit Pythonagore)

diagonalPixel = √ (heightPixel² + widthPixels²)

Dann können Sie den Pixelwert dank des DensityDPI-Werts in Zoll konvertieren:

inchDiag = diagonalPixel / DichteDPI.

Ich hoffe, ich habe hier keine Fehler gemacht. Beachten Sie, dass die Werte, die Sie von der DisplayMetrics-Klasse erhalten, vom Konstruktor angegeben werden. Es scheint (in sehr seltenen Fällen), dass sie nicht gut auf das physische Material abgestimmt sind.

Dadurch erhalten Sie die physische Bildschirmgröße, aber es ist wahrscheinlich nicht die bessere Möglichkeit, mehrere Layouts zu verwalten. Mehr zu diesen Themen

Guian
quelle
1

Ein anderer Weg:

  • Erstellen Sie zwei weitere Ordner: values-large + values-xlarge

  • Put: <string name="screentype">LARGE</string>in den Ordner "values-large" (strings.xml)

  • Put: <string name="screentype">XLARGE</string>im Ordner values-xlarge (strings.xml)

  • In Code:

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

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

    // von 4 ~ 7 Zoll

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

    // von 7 ~ 10 Zoll

    }}

Frank Nguyen
quelle
1

Voila! 😀 Dies ist alles, was Sie benötigen, um Tablets von Telefonen zu unterscheiden

1. Hilfsfunktion zum Abrufen der Bildschirmbreite:

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

2. Funktion, um herauszufinden, ob ein Gerät ein Tablet ist

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

3. Wenn Sie verschiedene Vorgänge für verschiedene Gerätegrößen ausführen möchten:

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

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

Hier einige nützliche Kotlin-Erweiterungen:


    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
quelle
Das funktioniert! Sie sollten jedoch die richtige DisplayMetrics verwenden, z. B. von Resourcesin Context: resources.displayMetrics.isTablet() oder von WindowManagerder in Activity: val displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getMetrics(displayMetrics) displayMetrics.isTablet()
Akbolat SSS