Wykryj programowo 7-calowy i 10-calowy tablet

94

Czy istnieje sposób, aby programowo sprawdzić, czy urządzenie, na którym jest zainstalowana aplikacja, to 7-calowy tablet, czy 10-calowy tablet?

Rekrut
źródło
Na przykład: layout-sw600dp szuka najmniejszego rozmiaru szerokości 600dp.
Debiutant
Rozumiem, ale czego szukasz programowo?
Geobits,
Muszę programowo pobrać te urządzenia ... ponieważ są pewne właściwości, których nie mogę zdefiniować w xml ... te właściwości są zdefiniowane w samym kodzie ... więc jeśli po prostu wstawię kod, będzie on dotyczył wszystkich urządzeń ... ale Nie chcę tego ...
Debiutant
@Raghav próbowałeś z matrycą wyświetlacza, aby uzyskać rozmiar ekranu, a następnie możesz porównać. Chociaż nie jest to czysty sposób, ale możesz go użyć.
PiyushMishra
Możesz uzyskać wymiary ekranu i stamtąd poćwiczyć ... stackoverflow.com/questions/1016896/…
Raj,

Odpowiedzi:

234

Możesz użyć, DisplayMetricsaby uzyskać całą masę informacji o ekranie, na którym działa Twoja aplikacja.

Najpierw tworzymy DisplayMetricsobiekt metryk:

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

Na tej podstawie możemy uzyskać informacje wymagane do rozmiaru wyświetlacza:

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

Zwróci to bezwzględną wartość szerokości i wysokości w pikselach, czyli 1280x720 dla Galaxy SIII, Galaxy Nexus itp.

Zwykle nie jest to pomocne samo w sobie, ponieważ podczas pracy na urządzeniach z Androidem zwykle wolimy pracować w pikselach niezależnych od gęstości, dip.

Dostajesz densityekranu używając metricsznowu w formie współczynnika skali dla urządzenia, który jest oparty na Android projekt Zasoby dla mdpi, hdpietc. Skale DPI

float scaleFactor = metrics.density;

Na podstawie tego wyniku możemy obliczyć liczbę pikseli niezależnych od gęstości dla określonej wysokości lub szerokości.

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

Wynik uzyskany dzięki temu pomoże Ci zdecydować, z jakim typem ekranu pracujesz, w połączeniu z przykładami konfiguracji Androida , które podają względną wartość dp dla każdego rozmiaru ekranu:

  • 320dp: typowy ekran telefonu (240x320 ldpi, 320x480 mdpi, 480x800 hdpi itp.).
  • 480dp: tablet z funkcją tweenera, taki jak Streak (480x800 mdpi).
  • 600dp: 7-calowy tablet (600x1024 mdpi).
  • 720dp: 10-calowy tablet (720x1280 mdpi, 800x1280 mdpi itp.).

Korzystając z powyższych informacji wiemy, że jeśli najmniejsza szerokość urządzenia jest większa niż 600dp, to urządzenie jest tabletem 7 ", jeśli jest większe niż 720dp, urządzeniem jest tablet 10".

Możemy obliczyć najmniejszą szerokość za pomocą minfunkcji Mathclass, przekazując heightDpi widthDpzwracając smallestWidth.

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

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

Jednak nie zawsze zapewnia to dokładne dopasowanie, zwłaszcza podczas pracy z mało znanymi tabletami, które mogą błędnie przedstawiać swoją gęstość jako hdpi, gdy tak nie jest, lub które mogą mieć tylko 800 x 480 pikseli, ale nadal są wyświetlane na 7-calowym ekranie .

Oprócz tych metod, jeśli kiedykolwiek będziesz musiał znać dokładne wymiary urządzenia w calach, możesz to również rozwiązać, używając metricsmetody określającej liczbę pikseli przypadających na cal ekranu.

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

Możesz wykorzystać wiedzę o liczbie pikseli w każdym calu urządzenia i łącznej liczbie pikseli, aby obliczyć, ile cali ma urządzenie.

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

Spowoduje to zwrócenie wysokości i szerokości urządzenia w calach. To znowu nie zawsze jest pomocne w określeniu, jakiego rodzaju jest to urządzenie, ponieważ reklamowany rozmiar urządzenia to przekątna, jedyne, co mamy, to wysokość i szerokość.

Wiemy jednak również, że biorąc pod uwagę wysokość trójkąta i szerokość, możemy użyć twierdzenia Pitagorasa do obliczenia długości przeciwprostokątnej (w tym przypadku wielkości przekątnej ekranu).

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

Na tej podstawie możemy ustalić, czy urządzenie jest tabletem, czy nie:

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

I w ten sposób obliczasz, z jakim urządzeniem pracujesz.

Sean O'Toole
źródło
3
Doskonałe wskazówki Sean. Kiedyś sprawdzałem z px dla tabletów, ale w niektórych przypadkach są problemy (Galaxy 3, 4, Note, ma równe lub większe piksele niż Nexus 7). Teraz mogę też sprawdzić cal. Oto lista wielu popularnych specyfikacji ekranu urządzeń: en.wikipedia.org/wiki/List_of_displays_by_pixel_density
Pelanes,
8
Nie używaj xdpi ani ydpi. Są one opcjonalne i zostaną ustawione przez producenta, a nie obliczone. Często są niewykorzystane lub niedokładne.
Sturrockad
2
Używając Twojej metody uzyskania szerokości w dpi, otrzymuję różne wyniki w zależności od orientacji. np. dla Nexusa 7: PORTRET: najmniejsza szerokość = 600,9; KRAJOBRAZ: najmniejsza szerokość = 552,8; Jaki jest tego powód?
Christopher Masser
3
Logika if (smallestWidth > 600) { /* 7" */ } else if (smallestWidth > 720) { /* 10" */ }jest błędna: 10-calowy tablet jest rozpoznawany jako 7-calowy. Pozwoliłem sobie to naprawić.
Jonik,
21
Ostatecznie poszedłem z resources.getConfiguration().smallestScreenWidthDpod odpowiedzi DeeV za który jest jedyną metodą, która daje taką samą wartość zarówno w pionowym i poziomym na moim Nexus 7 (600dp). Został dodany na poziomie API 13.
Jonik,
32

Nic nie mówi 7"ani 10"AFAIK. Istnieją z grubsza dwa sposoby uzyskania wymiarów ekranu, których system używa podczas dekodowania map bitowych i tak dalej. Oba znajdują się w obiekcie aplikacji Resourcesznajdującym się w Context.

Pierwsza to Configurationprzedmiot, który można zdobyć za pomocą getContext().getResources().getConfiguration(). Masz w nim:

Configuration#densityDpi - Docelowa gęstość ekranu, do której jest renderowany, odpowiadająca kwalifikatorowi zasobu gęstości.

Configuration#screenHeightDp - Bieżąca wysokość dostępnego miejsca na ekranie w jednostkach dp, odpowiadająca kwalifikatorowi zasobu wysokości ekranu.

Configuration#screenWidthDp - Bieżąca szerokość dostępnego miejsca na ekranie, w jednostkach dp, odpowiadająca kwalifikatorowi zasobu szerokości ekranu.

Configuration#smallestScreenWidthDp - Najmniejszy rozmiar ekranu, jaki aplikacja zobaczy podczas normalnej pracy, odpowiadający najmniejszemu kwalifikatorowi zasobu szerokości ekranu.

Z tym, można bardzo dużo skorzystać ze wskazówkami na ekranie, aby dowiedzieć się, czy urządzenie jest ciągnięcie od odpowiednich folderach zasobów specjalistycznych ( hdpi, xhdpi, large, xlarge, itd.).

Pamiętaj, to są niektóre z nich:

  • Duże ekrany mają co najmniej 960dp x 720dp
  • duże ekrany mają co najmniej 640 x 480 dpi
  • normalne ekrany mają co najmniej 470 x 320 dpi
  • małe ekrany mają co najmniej 426dp x 320dp

  • 320dp: typowy ekran telefonu (240x320 ldpi, 320x480 mdpi, 480x800 hdpi itp.).

  • 480dp: tablet z funkcją tweenera, taki jak Streak (480x800 mdpi).
  • 600dp: 7-calowy tablet (600x1024 mdpi).
  • 720dp: 10-calowy tablet (720x1280 mdpi, 800x1280 mdpi itp.).

Więcej informacji

Drugi to DisplayMetricsprzedmiot uzyskany przez getContext().getResources().getDisplayMetrics(). W tym masz:

DisplayMetrics#density - Logiczna gęstość wyświetlacza.

DisplayMetrics#densityDpi - Gęstość ekranu wyrażona w punktach na cal.

DisplayMetrics#heightPixels - Bezwzględna wysokość wyświetlacza w pikselach.

DisplayMetrics#widthPixels - Bezwzględna szerokość wyświetlacza w pikselach.

DisplayMetrics#xdpi - Dokładne fizyczne piksele na cal ekranu w wymiarze X.

DisplayMetrics#ydpi - Dokładne fizyczne piksele na cal ekranu w wymiarze Y.

Jest to przydatne, jeśli potrzebujesz dokładnej liczby pikseli ekranu, a nie gęstości. Należy jednak pamiętać, że to wszystkie piksele ekranu. Nie tylko te dostępne dla Ciebie.

DeeV
źródło
4
+1, najlepsze wyniki osiągam z smallestScreenWidthDp. W przeciwieństwie do innych rozwiązań daje tę samą wartość na moim Nexusie 7 (600 dp) niezależnie od orientacji . Jako bonus jest to również najprostszy kod!
Jonik,
1
Myślę, że nadal jest to najlepszy sposób, ponieważ powinien pasować do notacji sw ??? dp na ścieżkach zasobów. Spójność jest ważna.
lilbyrdie
13

umieść tę metodę w onResume () i może sprawdzić.

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;

    }

zwykle tabletki zaczynają się od rozmiaru 6 cali.

PiyushMishra
źródło
8

Powyższe nie zawsze działa podczas przełączania trybu pionowego na poziomy.

Jeśli celujesz w interfejs API na poziomie 13+, jest to łatwe, jak opisano powyżej - użyj Configuration.smallestScreenWidthDp, a następnie przetestuj odpowiednio:

resources.getConfiguration().smallestScreenWidthDp

W przeciwnym razie, jeśli możesz sobie na to pozwolić, użyj następującej metody, która jest bardzo dokładnym podejściem do wykrywania 600 dp (np. 6 cali) w porównaniu z 720 dp (np. 10 cali), pozwalając systemowi powiedzieć ci:

1) Dodaj do layout-sw600dp i layout-sw720dp (i jeśli ma to zastosowanie, jego krajobrazu) niewidoczny widok z odpowiednim identyfikatorem, na przykład:

Dla 720, w układzie-sw720dp:

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

W przypadku modelu 600 w układzie layout-sw600dp:

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

2) Następnie na kodzie, na przykład Activity, przetestuj odpowiednio:

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
źródło
4
Nie musisz tworzyć osobnego układu, uważam, że możesz mieć osobny plik strings.xml oparty na rozmiarze, mając różne foldery wartości, takie jak values-sw600dp itp. Zdefiniuj ciąg znaków <string name = 'screenize' > 600dp </string> w folderze sw600dp itd. Nie musi to nawet być ciągiem znaków, może znajdować się w ints.xml lub dimens.xml.
ajacian81
7

Świetna informacja, właśnie to, czego szukałem! Jednak po wypróbowaniu tego stwierdziłem, że korzystając z wymienionych tutaj danych, raporty Nexusa 7 (model z 2012 r.) Mają wymiary 1280 x 736. Mam też Motorolę Xoom z Jelly Bean i niepoprawnie podaje rozdzielczość 1280x752. Natknąłem się na ten post , który to potwierdza. Zasadniczo w ICS / JB obliczenia wykorzystujące wspomniane powyżej metryki wydają się wykluczać wymiary paska nawigacji. Trochę dalszych badań doprowadziło mnie do odpowiedzi Franka Nguyena, która wykorzystuje różne metody, które dadzą ci surowe (lub rzeczywiste) wymiary ekranu w pikselach. Moje wstępne testy wykazały, że poniższy kod od Franka Correclty podaje wymiary Nexusa 7 (model z 2012 roku z JB) i mojego Motorola Xoom z 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
źródło
3

Mam dwa urządzenia z Androidem o tej samej rozdzielczości

Urządzenie1 -> rozdzielczość 480x800 przekątna ekranu -> 4,7 cala

Urządzenie2 -> rozdzielczość 480x800 przekątna ekranu -> 4,0 cala

Daje to przekątną ekranu obu urządzeń -> 5,8

rozwiązaniem Twojego problemu jest ...

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

zobacz szczegóły tutaj ..

AndroidGeek
źródło
2

Sposób, w jaki Android określa rozmiary ekranu, to cztery uogólnione rozmiary: mały , normalny , duży i bardzo duży .

Podczas gdy dokumentacja systemu Android stwierdza, że ​​grupy rozmiarów są przestarzałe

... te grupy rozmiarów są przestarzałe na rzecz nowej techniki zarządzania rozmiarami ekranu na podstawie dostępnej szerokości ekranu. Jeśli programujesz dla Androida 3.2 i nowszych, zobacz [Deklarowanie układów tabletu dla Androida 3.2] (hdpi (wysoka) ~ 240dpi), aby uzyskać więcej informacji.

Ogólnie kwalifikator rozmiaru duży określa tablet 7- calowy, a kwalifikator rozmiaru xlarge określa tablet 10- calowy :

wprowadź opis obrazu tutaj

Zaletą wyzwalania kwalifikatora rozmiaru jest to, że możesz zagwarantować, że Twoje zasoby i kod są zgodne co do tego, którego zasobu użyć lub ścieżki kodu do aktywacji.

Aby pobrać kwalifikator rozmiaru w kodzie, wykonaj następujące wywołania:

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);
Benzoes
źródło
2

Możesz skorzystać z poniższej metody, aby uzyskać rozmiar ekranu w calach, na podstawie tego po prostu możesz sprawdzić, który tablet lub telefon to urządzenie.

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
źródło
2

Przechowywałem wartość w folderze wartości która daje mi ekran to 7 cali lub 10 inc, ale możemy to zrobić dla dowolnego urządzenia za pomocą folderu wartości.

na przykład utwórz folder wartości różne-2 dla różnych urządzeń-2. Ale to zależy od wymagań.

sharma_kunal
źródło
1

Będziesz musiał wykonać trochę obliczeń, korzystając z danych podanych przez klasę DisplayMetrics .

Masz heightPixel i widthPixels (rozdzielczość ekranu w pikselach)

Potrzebujesz przekątnej, ponieważ „calowy rozmiar ekranu” zawsze opisuje długość przekątnej. Możesz uzyskać przekątną ekranu w pikselach (używając pythagore)

diagonalPixel = √ (heightPixel² + widthPixels²)

następnie możesz przekonwertować wartość piksela na cale dzięki wartości DPI density:

inchDiag = diagonalPixel / densityDPI.

Mam nadzieję, że nie popełniłem tutaj błędów, pamiętaj, że wartości, które otrzymujesz z klasy DisplayMetrics, podaje konstruktor, okazuje się (w bardzo rzadkich przypadkach), że nie są one dobrze ustawione zgodnie z materiałem fizycznym ...

Zapewni to fizyczny rozmiar ekranu, ale prawdopodobnie nie jest to lepszy sposób na zarządzanie wieloma układami. Więcej na ten temat

Guian
źródło
1

Inny sposób:

  • Utwórz jeszcze 2 foldery: wartości-duże + wartości-duże

  • Umieść: <string name="screentype">LARGE</string>w folderze wartości-duży (strings.xml)

  • Umieść: <string name="screentype">XLARGE</string>w folderze values-xlarge (strings.xml)

  • W kodzie:

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

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

    // od 4 ~ 7 cali

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

    // od 7 do 10 cali

    }

Frank Nguyen
źródło
1

Voila! 😀 To wszystko, czego potrzebujesz, aby odróżnić tablety od telefonów

1. Funkcja pomocnicza, aby uzyskać szerokość ekranu:

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

2. Funkcja sprawdzania, czy urządzenie to tablet

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

3. Na koniec, jeśli chcesz wykonać różne operacje dla różnych rozmiarów urządzeń:

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

boolean is10InchTablet() {
    return getScreenWidth() >= 720;
}
Sagar
źródło
0

Oto kilka przydatnych rozszerzeń 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
    }

Danimate
źródło
To działa! Ale należy używać właściwych DisplayMetrics, na przykład od Resourcesw Context: resources.displayMetrics.isTablet() lub od WindowManagerktórych przechowywane są w Activity: val displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getMetrics(displayMetrics) displayMetrics.isTablet()
Akbolat SSS