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?
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?
Antworten:
Mit können Sie DisplayMetrics
eine ganze Reihe von Informationen über den Bildschirm abrufen, auf dem Ihre App ausgeführt wird.
Zuerst erstellen wir ein DisplayMetrics
Metrikobjekt:
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 density
des Bildschirms metrics
wieder, in Form eines Skalierungsfaktors für das Gerät, das auf der Basis Android Design - Ressourcen für mdpi
, hdpi
usw.
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 min
Funktion der Math
Klasse berechnen, indem wir das heightDp
und 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 metrics
Methode 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.
if (smallestWidth > 600) { /* 7" */ } else if (smallestWidth > 720) { /* 10" */ }
ist fehlerhaft: 10 "Tablet wird als 7" erkannt. Ich habe mir erlaubt, das zu beheben.
resources.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.
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 Resources
Objekt der Anwendung in der Context
.
Das erste ist das Configuration
Objekt, 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:
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.).
Das zweite ist das DisplayMetrics
Objekt, 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.
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!
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.
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();
}
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();
}
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 ..
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:
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);
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;
}
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.
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
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
}}
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;
}
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
}
Resources
in Context
: resources.displayMetrics.isTablet()
oder von WindowManager
der in Activity
: val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
displayMetrics.isTablet()