Rileva i tablet da 7 e 10 pollici a livello di programmazione


93

C'è un modo per scoprire a livello di codice se il dispositivo su cui è installata l'app è un tablet da 7 pollici o un tablet da 10 pollici?


Ad esempio: layout-sw600dp cerca la dimensione di larghezza minima di 600dp.
Rookie

Lo capisco, ma cosa stai cercando a livello di codice?
Geobits

Ho bisogno di recuperare questi dispositivi in ​​modo programmatico..come ci sono alcune proprietà che non posso definire in xml..queste proprietà sono definite nel codice stesso .. quindi se metto semplicemente il codice, si applicherà a tutti i dispositivi..ma Non lo voglio ..
Rookie

@Raghav hai provato con la matrice di visualizzazione per ottenere le dimensioni dello schermo e quindi puoi confrontare. Anche se non è un modo pulito ma puoi usarlo.
PiyushMishra

Potresti ottenere le dimensioni dello schermo e allenarti da lì ... stackoverflow.com/questions/1016896/…
Raj

Risposte:


234

Puoi utilizzare il DisplayMetricsper ottenere un sacco di informazioni sullo schermo su cui è in esecuzione la tua app.

Innanzitutto, creiamo un DisplayMetricsoggetto metriche:

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

Da questo, possiamo ottenere le informazioni necessarie per dimensionare il display:

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

Questo restituirà il valore assoluto della larghezza e dell'altezza in pixel, quindi 1280x720 per Galaxy SIII, Galaxy Nexus ecc.

Questo di solito non è utile da solo, poiché quando lavoriamo su dispositivi Android, di solito preferiamo lavorare in pixel indipendenti dalla densità, dip.

Ottieni densitydi nuovo lo schermo utilizzando metrics, sotto forma di un fattore di scala per il dispositivo, che si basa sulle risorse di progettazione Android per mdpi, hdpiecc. Scale DPI

float scaleFactor = metrics.density;

Da questo risultato, possiamo calcolare la quantità di pixel indipendenti dalla densità presenti per una certa altezza o larghezza.

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

Il risultato che ottieni da questo ti aiuterà a decidere con quale tipo di schermo stai lavorando in combinazione con gli esempi di configurazione Android , che ti danno il dp relativo per ogni dimensione dello schermo:

  • 320dp: uno schermo tipico del telefono (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, ecc.).
  • 480dp: un tablet tweener come lo Streak (480x800 mdpi).
  • 600 dpi: un tablet da 7 "(600x1024 mdpi).
  • 720 dpi: un tablet da 10 "(720 x 1280 mdpi, 800 x 1280 mdpi e così via).

Utilizzando le informazioni di cui sopra, sappiamo che se la larghezza minima del dispositivo è maggiore di 600dp, il dispositivo è un tablet da 7 ", se è maggiore di 720dp, il dispositivo è un tablet da 10".

Possiamo calcolare la larghezza più piccola usando la minfunzione di Mathclass, passando il heightDpe il widthDpper restituire il smallestWidth.

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

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

Tuttavia, questo non ti dà sempre una corrispondenza esatta, specialmente quando lavori con tablet oscuri che potrebbero rappresentare in modo errato la loro densità come hdpi quando non lo è, o potrebbero essere solo 800 x 480 pixel ma essere ancora su uno schermo da 7 " .

Oltre a questi metodi, se hai mai bisogno di conoscere le dimensioni esatte di un dispositivo in pollici, puoi elaborarlo anche tu, usando il metricsmetodo per quanti pixel ci sono per pollice dello schermo.

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

Puoi usare la conoscenza di quanti pixel ci sono in ogni pollice del dispositivo e la quantità di pixel in totale per calcolare quanti pollici è il dispositivo.

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

Ciò restituirà l'altezza e la larghezza del dispositivo in pollici. Anche questo non è sempre così utile per determinare che tipo di dispositivo è, poiché la dimensione pubblicizzata di un dispositivo è la diagonale, tutto ciò che abbiamo è l'altezza e la larghezza.

Tuttavia, sappiamo anche che data l'altezza di un triangolo e la larghezza, possiamo usare il teorema di Pitagora per calcolare la lunghezza dell'ipotenusa (in questo caso, la dimensione della diagonale dello schermo).

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

Da questo, possiamo capire se il dispositivo è un tablet o meno:

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

Ed è così che calcoli il tipo di dispositivo con cui stai lavorando.


3
Ottimi consigli Sean. Ero solito controllare con px per i tablet, ma in alcuni casi ci sono problemi (Galaxy 3, 4, Note, ha px uguale o superiore a Nexus 7). Ora posso anche controllare i pollici. Ecco un elenco delle specifiche dello schermo di molti dispositivi popolari: en.wikipedia.org/wiki/List_of_displays_by_pixel_density
Pelanes

8
Non utilizzare xdpi o ydpi. Questi sono opzionali e verranno impostati dal produttore, non calcolati. Spesso sono inutilizzati o imprecisi.
sturrockad

2
Utilizzando il tuo metodo per ottenere la larghezza in dpi ottengo risultati diversi a seconda dell'orientamento. ad es. per Nexus 7: PORTRAIT: smallestWidth = 600,9; PAESAGGIO: smallestWidth = 552,8; Qual è il motivo?
Christopher Masser

3
La logica if (smallestWidth > 600) { /* 7" */ } else if (smallestWidth > 720) { /* 10" */ }è viziata: il tablet da 10 "viene riconosciuto come 7". Mi sono preso la libertà di aggiustarlo.
Jonik

21
In definitiva sono andato con resources.getConfiguration().smallestScreenWidthDpda risposta di Deev , che è l'unico metodo che dà la stesso valore in verticale e orizzontale sul mio Nexus 7 (600dp). È stato aggiunto nel livello API 13.
Jonik

32

Non c'è niente che dice 7"o 10"AFAIK. Ci sono circa due modi per ottenere le dimensioni dello schermo che il sistema usa per decodificare bitmap e quant'altro. Si trovano entrambi Resourcesnell'oggetto dell'applicazione trovato nel file Context.

Il primo è l' Configurationoggetto che può essere ottenuto getContext().getResources().getConfiguration(). In esso hai:

Configuration#densityDpi - La densità dello schermo di destinazione su cui eseguire il rendering, corrispondente al qualificatore della risorsa di densità.

Configuration#screenHeightDp - L'altezza corrente dello spazio disponibile sullo schermo, in unità dp, corrispondente al qualificatore della risorsa altezza dello schermo.

Configuration#screenWidthDp - La larghezza corrente dello spazio disponibile sullo schermo, in unità dp, corrispondente al qualificatore della risorsa della larghezza dello schermo.

Configuration#smallestScreenWidthDp - La dimensione dello schermo più piccola che un'applicazione vedrà durante il normale funzionamento, corrispondente al qualificatore di risorsa di larghezza dello schermo più piccola.

Con questo, si può tranquillamente utilizzare le linee guida sullo schermo per capire se il dispositivo sta tirando dalle rispettive cartelle di risorse specializzate ( hdpi, xhdpi, large, xlarge, etc.).

Ricorda, questi sono alcuni dei secchi:

  • Gli schermi xlarge sono almeno 960dp x 720dp
  • schermi di grandi dimensioni sono almeno 640dp x 480dp
  • gli schermi normali sono almeno 470dp x 320dp
  • i piccoli schermi sono almeno 426 dpi x 320 dpi

  • 320dp: uno schermo tipico del telefono (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, ecc.).

  • 480dp: un tablet tweener come lo Streak (480x800 mdpi).
  • 600 dpi: un tablet da 7 "(600x1024 mdpi).
  • 720 dpi: un tablet da 10 "(720 x 1280 mdpi, 800 x 1280 mdpi e così via).

Ulteriori informazioni

Il secondo è l' DisplayMetricsoggetto ottenuto da getContext().getResources().getDisplayMetrics(). In quello hai:

DisplayMetrics#density - La densità logica del display.

DisplayMetrics#densityDpi - La densità dello schermo espressa in punti per pollice.

DisplayMetrics#heightPixels - L'altezza assoluta del display in pixel.

DisplayMetrics#widthPixels - La larghezza assoluta del display in pixel.

DisplayMetrics#xdpi - I pixel fisici esatti per pollice dello schermo nella dimensione X.

DisplayMetrics#ydpi - I pixel fisici esatti per pollice dello schermo nella dimensione Y.

Ciò è utile se è necessario il conteggio esatto dei pixel dello schermo anziché la densità. Tuttavia, è importante notare che si tratta di tutti i pixel dello schermo. Non solo quelli a tua disposizione.


4
+1, ottengo i migliori risultati con smallestScreenWidthDp. A differenza delle altre soluzioni, dà lo stesso valore sul mio Nexus 7 (600dp) indipendentemente dall'orientamento . Come bonus, è anche il codice più semplice!
Jonik

1
Penso che questo continui ad essere il modo migliore perché dovrebbe corrispondere alla notazione sw ??? dp sui percorsi delle risorse. La coerenza è importante.
lilbyrdie

13

posiziona questo metodo in onResume () e puoi controllare.

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 le compresse iniziano dopo le dimensioni di 6 pollici.


8

Quanto sopra non funziona sempre quando si passa da verticale a orizzontale.

Se scegli come target API di livello 13+, è facile come descritto sopra: usa Configuration.smallestScreenWidthDp, quindi prova di conseguenza:

resources.getConfiguration().smallestScreenWidthDp

Altrimenti, se te lo puoi permettere, utilizza il seguente metodo che è un approccio molto accurato per rilevare 600dp (come 6 ") contro 720dp (come 10") lasciando che il sistema ti dica:

1) Aggiungi a layout-sw600dp e layout-sw720dp (e se applicabile il suo paesaggio) una vista invisibile con ID appropriato, ad esempio:

Per 720, su layout-sw720dp:

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

Per 600, su layout-sw600dp:

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

2) Quindi sul codice, ad esempio, l'attività, verifica di conseguenza:

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

4
Non è necessario creare un layout separato, credo che si possa semplicemente avere un file strings.xml separato in base alle dimensioni, avendo cartelle di valori differenti, come values-sw600dp, ecc. Avere una stringa definita <string name = 'screensize' > 600dp </string> nella cartella sw600dp, ecc. Non deve nemmeno essere una stringa, potrebbe essere in ints.xml o dimens.xml.
ajacian81

7

Ottime informazioni, proprio quello che stavo cercando! Tuttavia, dopo averlo provato, ho scoperto che quando si utilizzano le metriche qui menzionate, i rapporti Nexus 7 (modello 2012) con dimensioni 1280x736. Ho anche un Motorola Xoom con Jelly Bean e riporta erroneamente una risoluzione di 1280x752. Mi sono imbattuto in questo post qui che lo conferma. Fondamentalmente, in ICS / JB i calcoli che utilizzano le metriche sopra menzionate sembrano escludere le dimensioni della barra di navigazione. Qualche altra ricerca mi ha portato alla risposta di Frank Nguyen qui che utilizza diversi metodi che ti daranno le dimensioni in pixel grezze (o reali) dello schermo. I miei test iniziali hanno dimostrato che il seguente codice di Frank correclty riporta le dimensioni sul Nexus 7 (modello 2012 con JB) e sul mio 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();
}

3

Ho due dispositivi Android con la stessa risoluzione

Dispositivo1 -> risoluzione 480x800 diagonale schermo -> 4,7 pollici

Device2 -> risoluzione 480x800 diagonale schermo -> 4,0 pollici

Fornisce dimensioni dello schermo diagonale a entrambi i dispositivi -> 5,8

la soluzione al tuo problema è ..

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

vedere i dettagli qui ..


2

Il modo in cui Android specifica le dimensioni dello schermo è attraverso quattro dimensioni generalizzate: piccolo , normale , grande e xlarge .

Mentre la documentazione di Android afferma che i gruppi di dimensioni sono deprecati

... questi gruppi di dimensioni sono deprecati a favore di una nuova tecnica per la gestione delle dimensioni dello schermo in base alla larghezza dello schermo disponibile. Se stai sviluppando per Android 3.2 e versioni successive, consulta [Dichiarazione dei layout del tablet per Android 3.2] (hdpi (alto) ~ 240 dpi) per ulteriori informazioni.

In genere, il qualificatore di dimensione grande specifica un tablet da 7 ". Un qualificatore di dimensione di xlarge specifica un tablet da 10":

inserisci qui la descrizione dell'immagine

La cosa bella dell'attivazione sul qualificatore della dimensione è che puoi garantire che le tue risorse e il codice siano d'accordo su quale risorsa utilizzare o percorso del codice da attivare.

Per recuperare il qualificatore di dimensione nel codice, effettuare le chiamate seguenti:

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

2

Puoi utilizzare il metodo seguente per ottenere le dimensioni dello schermo in pollici, in base a questo puoi semplicemente controllare quale tablet o telefono è il 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;
}

2

Stavo memorizzando un valore nella cartella dei valori che mi dà uno schermo da 7 pollici o 10 pollici, ma possiamo farlo per qualsiasi dispositivo utilizzando la cartella dei valori.

come creare una cartella di valori 2 diversi per dispositivi 2 diversi. Ma questa cosa dipende dal requisito.


1

Dovrai fare un po 'di calcolo usando i dati forniti dalla classe DisplayMetrics .

Hai heightPixel e widthPixel (la risoluzione dello schermo in pixel)

È necessaria la diagonale poiché la "dimensione dello schermo in pollici" descrive sempre la lunghezza della diagonale. Puoi ottenere la diagonale dello schermo in pixel (usando pythagore)

diagonalPixel = √ (heightPixel² + widthPixels²)

quindi puoi convertire il valore del pixel in pollici grazie al valore di densityDPI:

inchDiag = diagonalPixel / densitàDPI.

Spero di non aver commesso errori qui, tieni presente che i valori che ottieni dalla classe DisplayMetrics sono dati dal costruttore, sembra (in casi molto rari) che non siano ben impostati in base al materiale fisico ...

Questo ti darà le dimensioni fisiche dello schermo ma probabilmente non è il modo migliore per gestire più layout. Maggiori informazioni su questi argomenti


1

Un altro modo:

  • Crea altre 2 cartelle: values-large + values-xlarge

  • Metti: <string name="screentype">LARGE</string>nella cartella valori-large (strings.xml)

  • Metti: <string name="screentype">XLARGE</string>nella cartella values-xlarge (strings.xml)

  • In codice:

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

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

    // da 4 ~ 7 pollici

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

    // da 7 ~ 10 pollici

    }


1

Ecco! 😀 Questo è tutto ciò di cui hai bisogno per distinguere i tablet dai telefoni

1. Funzione di aiuto per ottenere la larghezza dello schermo:

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

2. Funzione per capire se un dispositivo è un tablet

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

3. Infine, se stai cercando di eseguire operazioni diverse per dispositivi di dimensioni diverse:

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

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

0

Ecco alcune utili estensioni di 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
    }

Che funzioni! Ma dovresti usare DisplayMetrics appropriato, ad esempio da Resourcesin Context: resources.displayMetrics.isTablet() o da WindowManagercui è memorizzato in Activity: val displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getMetrics(displayMetrics) displayMetrics.isTablet()
Akbolat SSS
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.