it-swarm.com.de

Tablet oder Telefon - Android

Gibt es eine Möglichkeit zu überprüfen, ob der Benutzer ein Tablet oder ein Telefon verwendet? Ich habe Probleme mit der Neigungsfunktion und meinem neuen Tablet (Transformer).

136
Benny

Wie bereits erwähnt, möchten Sie nicht prüfen, ob es sich bei dem Gerät um ein Tablet oder ein Telefon handelt, Sie möchten jedoch die Funktionen des Geräts kennen.

In den meisten Fällen ist der Unterschied zwischen einem Tablet und einem Telefon die Bildschirmgröße, weshalb Sie unterschiedliche Layout-Dateien verwenden möchten. Diese Dateien werden in den res/layout-<qualifiers>-Verzeichnissen gespeichert. Sie können eine XML-Datei im Verzeichnis res/values-<same qualifiers> für jedes Ihrer Layouts erstellen und eine int/bool/string-Ressource hinzufügen, um zwischen den verwendeten Layouts zu unterscheiden.

Beispiel:

Datei res/values/screen.xml (vorausgesetzt, res/layout/ enthält Ihre Layoutdateien für Mobilteile)

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="screen_type">phone</string>
</resources>


Datei res/values-sw600dp/screen.xml (vorausgesetzt res/layout-sw600dp/ enthält Ihre Layout-Dateien für kleine Tablets wie das Nexus 7) 

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="screen_type">7-inch-tablet</string>
</resources>


Datei res/values-sw720dp/screen.xml (vorausgesetzt res/layout-sw720dp/ enthält Ihre Layoutdateien für große Tablets wie das Nexus 10): 

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="screen_type">10-inch-tablet</string>
</resources>


Nun ist der Bildschirmtyp über die Konstante R.string.screen_type erreichbar.

115
John

Um festzustellen, ob das Gerät ein Tablet ist, verwenden Sie den folgenden Code:

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

GROSSE und XLARGE-Bildschirmgrößen werden vom Hersteller anhand des Abstandes vom Auge, an dem sie verwendet werden sollen, festgelegt (daher die Idee eines Tablets). 

Weitere Informationen: http://groups.google.com/group/Android-developers/browse_thread/thread/d6323d81f226f93f

59
petey

Dieser Beitrag hat mir sehr geholfen,

Leider habe ich nicht den nötigen Ruf, um alle Antworten auszuwerten, die mir geholfen haben.

Ich musste feststellen, ob es sich bei meinem Gerät um ein Tablet oder ein Telefon handelt, wodurch ich die Logik des Bildschirms implementieren konnte. Und in meiner Analyse muss das Tablet ab MDPI mehr als 7 Zoll (Xlarge) sein.

Hier ist der Code, der basierend auf diesem Beitrag erstellt wurde.

/**
 * 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;
}
38
Helton Isac

Warum berechnen Sie nicht die Größe der Bildschirmdiagonale und verwenden Sie diese, um zu entscheiden, ob das Gerät ein Telefon oder Tablet ist?

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

Natürlich kann man darüber streiten, ob die Schwelle 9 Zoll oder weniger betragen sollte.

13
Volker Voecking

es gibt keinen Unterschied. Sie sollten definieren, was Sie für den Unterschied halten, und dies überprüfen. Ist ein Galaxy Tab ein Telefon? oder eine Tablette? und warum?

Sie sollten definieren, nach welchen spezifischen Funktionen Sie suchen, und den Code dafür definieren.

Es scheint, dass Sie nach "Neigung" suchen. Ich denke, das ist das gleiche wie der Beschleunigungssensor (ist das ein Wort?). Sie können einfach prüfen, ob das Gerät dies unterstützt.

public class Accel extends Activity implements SensorListener {
...
  SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
  boolean accelSupported = sensorMgr.registerListener(this,
        SENSOR_ACCELEROMETER,
        SENSOR_DELAY_UI);
...
}

(von http://stuffthathappens.com/blog/2009/03/15/Android-accelerometer/ . Ich habe es nicht getestet.)

11
Nanne

Ich gehe davon aus, dass Sie bei der Definition von "Handy/Telefon" wissen möchten, ob Sie auf dem Gerät einen Telefonanruf tätigen können, der jedoch nicht mit einem als "Tablet" definierten Gerät ausgeführt werden kann. Der Weg, um dies zu überprüfen, ist unten. Wenn Sie etwas wissen möchten, basierend auf Sensoren, Bildschirmgröße usw., ist dies wirklich eine andere Frage. 

Bei der Verwendung der Bildschirmauflösung oder der Ressourcenverwaltung im Vergleich zu xlarge waren in der Vergangenheit möglicherweise neue mobile Geräte mit so großen Bildschirmen und hohen Auflösungen, dass sie diese Linie verwischen, wenn Sie es wirklich wünschen Um zu wissen, ob ein Telefonat oder keine Telefonanruf-Fähigkeit vorhanden ist, ist das Folgende "am besten".

TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
    return "Tablet";
}else{
    return "Mobile";
}

Basierend auf Robert Dale Johnson III und Helton Isac kam ich mit diesem Code auf Ich hoffe, das ist nützlich 

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

Also in deinem Code einen Filter machen

if(isTabletDevice(Utilities.this) && isTablet(Utilities.this)){
    //Tablet
} else {
    //Phone
}
6
Cjames

Wer auf den Code von Google zur Entscheidung, welche Geräte eine Tablet-Benutzeroberfläche verwenden möchten, verweisen möchte, kann im Folgenden nachlesen:

  // 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;
        }
        }
3
Pier Betos

Diese Methode wird von Google empfohlen. Ich sehe diesen Code in der offiziellen Android-App von Google iosched

public static boolean isTablet(Context context) {
        return (context.getResources().getConfiguration().screenLayout
                & Configuration.SCREENLAYOUT_SIZE_MASK)
                >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
3
hqt

Wenn Sie nur die API-Ebene> = 13 verwenden, versuchen Sie es

public static boolean isTablet(Context context) {
    return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}

prost :-)

2
dheeran

In der Google IOSched 2017-App Quellcode wird die folgende Methode verwendet:

public static boolean isTablet(Context context) {
    return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
2
Murat

Kein Code notwendig

In den anderen Antworten werden viele Möglichkeiten aufgelistet, um programmgesteuert zu bestimmen, ob es sich bei dem Gerät um ein Telefon oder ein Tablet handelt. Wenn Sie jedoch die Dokumentation lesen, ist dies nicht die empfohlene Methode, um verschiedene Bildschirmgrößen zu unterstützen.

Deklarieren Sie stattdessen unterschiedliche Ressourcen für Tablets oder Telefone. Sie tun dies, indem Sie zusätzliche Ressourcenordner für layout, values usw. hinzufügen.

  • Fügen Sie für Android 3.2 (API-Ebene 13) einen Ordner sw600dp hinzu. Dies bedeutet, dass s mallest w idth mindestens 600dp ist, was in etwa die Telefon-/Tablet-Division ist. Sie können jedoch auch andere Größen hinzufügen. In this answer finden Sie ein Beispiel, wie Sie eine zusätzliche Layout-Ressourcendatei hinzufügen. 

  • Wenn Sie auch Geräte vor Android 3.2 unterstützen, müssen Sie die Ordner large oder xlarge hinzufügen, um Tablets zu unterstützen. (Telefone sind im Allgemeinen small und normal.)

Hier sehen Sie ein Bild davon, wie Ihre Ressourcen aussehen könnten, nachdem Sie zusätzliche XML-Dateien für verschiedene Bildschirmgrößen hinzugefügt haben.

enter image description here

Bei dieser Methode ermittelt das System alles für Sie. Sie müssen sich keine Gedanken darüber machen, welches Gerät zur Laufzeit verwendet wird. Sie stellen nur die entsprechenden Ressourcen bereit und lassen Android die gesamte Arbeit erledigen. 

Anmerkungen

  • Sie können Aliase verwenden, um das Duplizieren identischer Ressourcendateien zu vermeiden.

Android-Dokumente, die es wert sind, gelesen zu werden

2
Suragch

Als ich an die "neuen" Verzeichnisse dachte (values-sw600dp zum Beispiel), habe ich diese Methode basierend auf der Bildschirmbreite erstellt:

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

Auf dieser Liste finden Sie einige der gängigsten Geräte und Tablettgrößen:

Wdp/Hdp

GALAXY Nexus: 360/567
XOOM: 1280/752
GALAXY HINWEIS: 400/615
NEXUS 7: 961/528
GALAXY TAB (> 7 && <10): 1280/752
GALAXY S3: 360/615 

Wdp = Breite dp
Hdp = Höhe dp

1
Aracem

Nun, die beste Lösung, die für mich funktioniert hat, ist ganz einfach:

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

So benutzt:

public void onCreate(Bundle savedInstanceState) {
    [...]
    if (this.isTabletDevice(this.getResources()) == true) {
        [...]
    }
}

Ich möchte nicht wirklich die Pixelgröße betrachten, sondern nur auf die Bildschirmgröße.

Funktioniert gut, da Nexus 7 (LARGE) als Tablet erkannt wird, nicht jedoch Galaxy S3 (NORMAL).

1
Max

Verwenden Sie diese Methode, die true zurückgibt, wenn das Gerät ein Tablet ist

public boolean isTablet(Context context) {  
    return (context.getResources().getConfiguration().screenLayout   
        & Configuration.SCREENLAYOUT_SIZE_MASK)    
        >= Configuration.SCREENLAYOUT_SIZE_LARGE; 
}
1
Vyshnavi

Wenn die Erkennung der Bildschirmgröße auf neueren Geräten keinen korrekten Wert liefert, versuchen Sie es:

/*
 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;}
}

Getestet auf Android 4.2.2 (Entschuldigung für mein Englisch.)

1
BSTech
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)));
    }
0
Xar E Ahmer

Es wird immer schwieriger, die Grenze zwischen Telefon und Tablet zu ziehen. Zum Beispiel (Stand: August 2015) zieht das Samsung Mega 6.3 - Gerät Ressourcen aus den sw600dp-Ordnern - bei Android handelt es sich also um ein Tablet. 

Die Antwort aus @Vyshnavi funktioniert auf allen Geräten, die wir getestet haben, jedoch nicht für Mega 6.3. 

@Helton Isac Antwort oben gibt den Mega 6.3 als Telefon zurück. Da das Gerät jedoch immer noch Ressourcen von sw600dp bezieht, kann dies zu anderen Problemen führen. Wenn Sie beispielsweise einen Viewpager für Telefone und nicht für Tablets verwenden, können Sie sich darauf verlassen mit NPE-Fehlern. 

Am Ende scheint es, dass es zu viele Bedingungen gibt, auf die Sie prüfen können, und wir müssen vielleicht akzeptieren, dass einige Telefone tatsächlich Tablets sind :-P

0
bkurzius

Ich musste das Smartphone/Tablet nur in der Layoutdatei erkennen, da ich den Navigationscode verwende.

Zuerst habe ich ein layout-sw600dp-Verzeichnis erstellt, aber es funktionierte nicht gut, da es auf meinem Nokia 8 im Querformat aktiviert wurde, aber die Bildschirmhöhe zu klein wäre.

Also habe ich das Verzeichnis in layout-sw600dp-h400dp umbenannt und dann den gewünschten Effekt erzielt. Der Parameter h-xxxdp sollte davon abhängen, wie viel Inhalt Sie in Ihrem Layout ablegen möchten, und daher anwendungsabhängig sein.

0
Dominique Lorre

warum das benutzen?

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

ich sehe viele Möglichkeiten oben. Die Konfigurationsklasse hat unten genau die richtige Antwort:

    /**
 * 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;
}

ruf einfach an :

 getResources().getConfiguration().
 isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);

es ist in Ordnung?

0
alei long

die Methode unten berechnet die Diagonallänge des Geräts, um zu entscheiden, ob es sich bei dem Gerät um ein Telefon oder Tablet handelt. Das einzige Problem bei dieser Methode ist der Schwellenwert für die Entscheidung, ob das Gerät ein Tablet ist oder nicht. Im Beispiel unten habe ich 7 Zoll und mehr eingestellt.

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 );
}
0
MinFu

com.sec.feature.multiwindow.tablet im Paket-Manager ist nur für Tablets und com.sec.feature.multiwindow.phone spezifisch für das Telefon.

0
RBz

Ich weiß, dass dies keine direkte Antwort auf Ihre Frage ist, aber andere Antworten geben eine gute Vorstellung davon, wie Sie die Bildschirmgröße bestimmen. Sie haben in Ihrer Frage geschrieben, dass Sie Probleme mit dem Neigen haben, und das ist auch mir passiert.

Wenn Sie den Gyroskop (oder den Rotationssensor) auf einem Smartphone ausführen, können die X- und Y-Achse je nach der Standardausrichtung des Geräts unterschiedlich definiert werden (z. B. Samsung GS2 ist das Standardporträt, Samsung GT-7310.) Standardmäßig ist das neue Google Nexus 7 Standardportrait, obwohl es ein Tablet ist!).

Nun, wenn Sie Gyroscope verwenden möchten, erhalten Sie möglicherweise eine funktionierende Lösung für Smartphones, bei einigen Tablets jedoch Achskonfusion oder umgekehrt.

Wenn Sie eine der Lösungen von oben verwenden, wählen Sie nur die Bildschirmgröße und wenden Sie sich an

SensorManager.remapCoordinateSystem(inputRotationMatrix, SensorManager.AXIS_X, 
    SensorManager.AXIS_Y, outputRotationMatrix);

um die Achse umzudrehen, wenn sie eine große oder große Bildschirmgröße hat, kann dies in 90% der Fälle funktionieren, aber beispielsweise beim Nexus 7 führt dies zu Problemen (weil sie eine Standard-Hochformat-Ausrichtung und eine große Bildschirmgröße hat).

Die einfachste Möglichkeit, dies zu beheben, wird in RotationVectorSample bereitgestellt, das im Lieferumfang der API-Demos enthalten ist, indem Sie sceenOrientation in Ihrem Manifest auf nosensor setzen:

<activity
    ...
    Android:screenOrientation="nosensor">
...
</activity>
0
Alexander Pacha

Dies ist die Methode, die ich verwende:

public static boolean isTablet(Context ctx){    
    return = (ctx.getResources().getConfiguration().screenLayout 
    & Configuration.SCREENLAYOUT_SIZE_MASK) 
    >= Configuration.SCREENLAYOUT_SIZE_LARGE; 
}

Mit:

Configuration. SCREENLAYOUT_SIZE_MASK

Configuration. SCREENLAYOUT_SIZE_LARGE

Dies ist die empfohlene Methode!

0
Elenasys