Sprawdź orientację na telefonie z Androidem

Odpowiedzi:

676

Bieżąca konfiguracja używana do określenia, które zasoby należy pobrać, jest dostępna z Configurationobiektu Resources :

getResources().getConfiguration().orientation;

Możesz sprawdzić orientację, patrząc na jej wartość:

int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
    // In landscape
} else {
    // In portrait
}

Więcej informacji można znaleźć w Android Developer .

hackbod
źródło
2
Och, przepraszam, źle zrozumiałem, myślałem, że mówisz, że usługa nie zobaczy zmiany konfiguracji, jeśli zmieni się konfiguracja. Opisujesz, że ... cóż, nic nie widać, ponieważ nic się nie zmienia, ponieważ program uruchamiający zablokował orientację ekranu i nie pozwala na zmianę. Prawidłowe jest więc, że orientacja się nie zmienia, ponieważ orientacja się nie zmieniła. Ekran jest nadal pionowy.
hackbod
Najbliższe, co mogę zrobić, to odczytać orientację z czujników, która wiąże się z matematyką, której tak naprawdę nie lubię w tej chwili rozgryzać.
Archimedes Trajano
13
Nie ma się czym denerwować. Ekran nie został obrócony, nadal jest w pionie, nie można go obrócić. Jeśli chcesz monitorować, w jaki sposób użytkownik porusza telefonem, niezależnie od tego, w jaki sposób obracany jest ekran, to tak, musisz bezpośrednio obserwować czujnik i zdecydować, w jaki sposób chcesz interpretować informacje o ruchu urządzenia.
hackbod
4
Nie powiedzie się, jeśli orientacja ekranu jest ustalona.
AndroidDev
7
Jeśli aktywność zablokuje display ( android:screenOrientation="portrait"), ta metoda zwróci tę samą wartość niezależnie od tego, w jaki sposób użytkownik obraca urządzenie. W takim przypadku użyjesz akcelerometru lub czujnika grawitacji, aby poprawnie ustalić orientację.
Cat
169

Jeśli użyjesz orientacji getResources (). GetConfiguration (). Na niektórych urządzeniach, popełnisz błąd. Takie podejście zastosowaliśmy początkowo w http://apphance.com . Dzięki zdalnemu rejestrowaniu Apphance widzieliśmy go na różnych urządzeniach i widzieliśmy, że fragmentacja odgrywa tutaj swoją rolę. Widziałem dziwne przypadki: na przykład na przemian portret i kwadrat (?!) w telefonie HTC Desire HD:

CONDITION[17:37:10.345] screen: rotation: 270 orientation: square
CONDITION[17:37:12.774] screen: rotation: 0 orientation: portrait
CONDITION[17:37:15.898] screen: rotation: 90
CONDITION[17:37:21.451] screen: rotation: 0
CONDITION[17:38:42.120] screen: rotation: 270 orientation: square

lub wcale nie zmieniając orientacji:

CONDITION[11:34:41.134] screen: rotation: 0
CONDITION[11:35:04.533] screen: rotation: 90
CONDITION[11:35:06.312] screen: rotation: 0
CONDITION[11:35:07.938] screen: rotation: 90
CONDITION[11:35:09.336] screen: rotation: 0

Z drugiej strony, szerokość () i wysokość () jest zawsze poprawna (jest używana przez menedżera okien, więc powinna być lepsza). Powiedziałbym, że najlepszym pomysłem jest ZAWSZE sprawdzanie szerokości / wysokości. Jeśli myślisz o chwili, właśnie tego chcesz - wiedzieć, czy szerokość jest mniejsza niż wysokość (portret), przeciwnie (krajobraz) lub czy są one takie same (kwadrat).

Sprowadza się to do tego prostego kodu:

public int getScreenOrientation()
{
    Display getOrient = getWindowManager().getDefaultDisplay();
    int orientation = Configuration.ORIENTATION_UNDEFINED;
    if(getOrient.getWidth()==getOrient.getHeight()){
        orientation = Configuration.ORIENTATION_SQUARE;
    } else{ 
        if(getOrient.getWidth() < getOrient.getHeight()){
            orientation = Configuration.ORIENTATION_PORTRAIT;
        }else { 
             orientation = Configuration.ORIENTATION_LANDSCAPE;
        }
    }
    return orientation;
}
Jarek Potiuk
źródło
3
Dzięki! Inicjowanie „orientacji” jest jednak zbyteczne.
MrMaffen
getWidthi getHeightnie są przestarzałe.
FindOut_Quran
3
@ user3441905, tak, są. Użyj getSize(Point outSize)zamiast tego. Używam API 23.
WindRider
@ jarek-potiuk jest przestarzałe.
Hades
53

Innym sposobem rozwiązania tego problemu jest nie poleganie na poprawnej wartości zwracanej z wyświetlacza, ale poleganie na rozwiązaniu zasobów Androida.

Utwórz plik layouts.xmlw folderach res/values-landi res/values-porto następującej treści:

res / values-land / layouts.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="is_landscape">true</bool>
</resources>

res / wartości-port / layouts.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="is_landscape">false</bool>
</resources>

W kodzie źródłowym możesz teraz uzyskać dostęp do bieżącej orientacji w następujący sposób:

context.getResources().getBoolean(R.bool.is_landscape)
Paweł
źródło
1
Podoba mi się to, ponieważ używa dowolnego sposobu, w jaki system już określa orientację
KrustyGString
1
Najlepsza odpowiedź na sprawdzenie krajobrazu / portretu!
vtlinh
Jaka będzie jego wartość w pliku wartości domyślnych?
Shashank Mishra
46

Pełny sposób na określenie aktualnej orientacji telefonu:

    public String getRotation(Context context){
    final int rotation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();
           switch (rotation) {
            case Surface.ROTATION_0:
                return "portrait";
            case Surface.ROTATION_90:
                return "landscape";
            case Surface.ROTATION_180:
                return "reverse portrait";
            default:
                return "reverse landscape";
            }
        }

Chear Binh Nguyen

Nguyen Minh Binh
źródło
6
W twoim poście jest literówka - powinien powiedzieć: .getRotation () not getOrientation
Keith
1
+1 za to. Musiałem znać dokładną orientację, nie tylko krajobraz kontra portret. getOrientation () jest poprawny, chyba że korzystasz z SDK 8+, w takim przypadku powinieneś użyć getRotation (). Tryby „wstecznego” są obsługiwane w SDK 9+.
Paul
6
@Keith @Paul Nie pamiętam, jak to getOrientation()działa, ale nie jest to poprawne, jeśli używasz getRotation(). Uzyskaj "Returns the rotation of the screen from its "natural" orientation." źródło rotacji . Tak więc na telefonie z informacją, że ROTATION_0 jest portretem, prawdopodobnie jest prawidłowa, ale na tablecie jego „naturalna” orientacja jest prawdopodobnie pozioma, a ROTATION_0 powinien zwrócić krajobraz zamiast pionowej.
jp36
Wygląda na to, że jest to preferowana metoda dołączania do przodu: developer.android.com/reference/android/view/…
jaysqrd
To zła odpowiedź. Dlaczego został poddany głosowaniu? getOrientation (wartości float [] R, wartości float []) oblicza orientację urządzenia na podstawie macierzy obrotu.
user1914692,
29

Oto demo fragmentu kodu, jak uzyskać orientację ekranu, zalecane przez hackbod i Martijn :

❶ Uruchom po zmianie orientacji:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
        int nCurrentOrientation = _getScreenOrientation();
    _doSomeThingWhenChangeOrientation(nCurrentOrientation);
}

❷ Uzyskaj aktualną orientację, ponieważ hackbod zaleca:

private int _getScreenOrientation(){    
    return getResources().getConfiguration().orientation;
}

❸ Istnieją alternatywne rozwiązania pozwalające uzyskać bieżącą orientację ekranu ❷ postępuj zgodnie z rozwiązaniem Martijn :

private int _getScreenOrientation(){
        Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
        return display.getOrientation();
}

Uwaga : Próbowałem zarówno zaimplementować ❷, jak i ❸, ale w RealDevice (NexusOne SDK 2.3) Orientacja zwraca niewłaściwą orientację.

★ Więc polecam zastosowane rozwiązanie ❷, aby uzyskać orientację ekranu, która ma więcej zalet: wyraźnie, prosta i działa jak urok.

★ Sprawdź dokładnie zwrot orientacji, aby upewnić się, że jest zgodny z naszymi oczekiwaniami (może być ograniczony w zależności od specyfikacji urządzeń fizycznych)

Mam nadzieję, że to pomoże

NguyenDat
źródło
16
int ot = getResources().getConfiguration().orientation;
switch(ot)
        {

        case  Configuration.ORIENTATION_LANDSCAPE:

            Log.d("my orient" ,"ORIENTATION_LANDSCAPE");
        break;
        case Configuration.ORIENTATION_PORTRAIT:
            Log.d("my orient" ,"ORIENTATION_PORTRAIT");
            break;

        case Configuration.ORIENTATION_SQUARE:
            Log.d("my orient" ,"ORIENTATION_SQUARE");
            break;
        case Configuration.ORIENTATION_UNDEFINED:
            Log.d("my orient" ,"ORIENTATION_UNDEFINED");
            break;
            default:
            Log.d("my orient", "default val");
            break;
        }
anshul
źródło
13

Użyj getResources().getConfiguration().orientationtego we właściwy sposób.

Trzeba tylko uważać na różne rodzaje krajobrazów, krajobraz normalnie używany przez urządzenie i drugi.

Nadal nie rozumiem, jak sobie z tym poradzić.

Neteinstein
źródło
12

Minęło trochę czasu, odkąd opublikowano większość tych odpowiedzi, a niektórzy używają obecnie nieaktualnych metod i stałych.

Zaktualizowałem kod Jarka, aby nie używać już tych metod i stałych:

protected int getScreenOrientation()
{
    Display getOrient = getWindowManager().getDefaultDisplay();
    Point size = new Point();

    getOrient.getSize(size);

    int orientation;
    if (size.x < size.y)
    {
        orientation = Configuration.ORIENTATION_PORTRAIT;
    }
    else
    {
        orientation = Configuration.ORIENTATION_LANDSCAPE;
    }
    return orientation;
}

Pamiętaj, że ten tryb Configuration.ORIENTATION_SQUAREnie jest już obsługiwany.

Przekonałem się, że jest to niezawodne na wszystkich urządzeniach, na których testowałem, w przeciwieństwie do metody sugerującej użycie getResources().getConfiguration().orientation

Baz
źródło
Zauważ, że getOrient.getSize (rozmiar) wymaga 13 poziomu interfejsu API
Lester
6

Sprawdź orientację ekranu w czasie wykonywania.

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();

    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();        
    }
}
Kumar
źródło
5

Jest na to jeszcze jeden sposób:

public int getOrientation()
{
    if(getResources().getDisplayMetrics().widthPixels>getResources().getDisplayMetrics().heightPixels)
    { 
        Toast t = Toast.makeText(this,"LANDSCAPE",Toast.LENGTH_SHORT);
        t.show();
        return 1;
    }
    else
    {
        Toast t = Toast.makeText(this,"PORTRAIT",Toast.LENGTH_SHORT);
        t.show();
        return 2;
    }       
}
maximus
źródło
4

Zestaw SDK systemu Android może to dobrze powiedzieć:

getResources().getConfiguration().orientation
Single i szukam
źródło
4

Przetestowany w 2019 roku na API 28, niezależnie od tego, czy użytkownik ustawił orientację pionową, czy nie, a przy minimalnym kodzie w porównaniu z inną, nieaktualną odpowiedzią , poniższe zapewnia prawidłową orientację:

/** @return The {@link Configuration#ORIENTATION_SQUARE}, {@link Configuration#ORIENTATION_PORTRAIT}, {@link Configuration#ORIENTATION_LANDSCAPE} constants based on the current phone screen pixel relations. */
private int getScreenOrientation()
{
    DisplayMetrics dm = context.getResources().getDisplayMetrics(); // Screen rotation effected

    if(dm.widthPixels == dm.heightPixels)
        return Configuration.ORIENTATION_SQUARE;
    else
        return dm.widthPixels < dm.heightPixels ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
}
ManuelTS
źródło
2

Myślę, że ten kod może działać po wejściu zmiany orientacji

Display getOrient = getWindowManager().getDefaultDisplay();

int orientation = getOrient.getOrientation();

zastąp funkcję Activity.onConfigurationChanged (Configuration newConfig) i użyj newConfig, orientacji, jeśli chcesz otrzymywać powiadomienia o nowej orientacji przed wywołaniem setContentView.

Daniel
źródło
2

myślę, że użycie getRotationv () nie pomaga, ponieważ http://developer.android.com/reference/android/view/Display.html#getRotation%28%29 getRotation () Zwraca obrót ekranu z jego „naturalnego” orientacja.

więc jeśli nie znasz orientacji „naturalnej”, obrót jest bez znaczenia.

znalazłem łatwiejszy sposób,

  Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
  Point size = new Point();
  display.getSize(size);
  int width = size.x;
  int height = size.y;
  if(width>height)
    // its landscape

proszę powiedz mi, czy jest z tym problem?

Steveh
źródło
2

taka jest nakładka na wszystkie telefony, takie jak oneplus3

public static boolean isScreenOriatationPortrait(Context context) {
         return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
         }

odpowiedni kod w następujący sposób:

public static int getRotation(Context context){
        final int rotation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();

        if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180){
            return Configuration.ORIENTATION_PORTRAIT;
        }

        if(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270){
            return Configuration.ORIENTATION_LANDSCAPE;
        }

        return -1;
    }
yueyue_projects
źródło
1

Stary post, który znam. Niezależnie od tego, jaka jest orientacja lub która zostanie zamieniona itp. Zaprojektowałem tę funkcję, która służy do ustawiania urządzenia we właściwej orientacji, bez potrzeby wiedzieć, jak zorganizowane są funkcje portretu i krajobrazu w urządzeniu.

   private void initActivityScreenOrientPortrait()
    {
        // Avoid screen rotations (use the manifests android:screenOrientation setting)
        // Set this to nosensor or potrait

        // Set window fullscreen
        this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

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

         // Test if it is VISUAL in portrait mode by simply checking it's size
        boolean bIsVisualPortrait = ( metrics.heightPixels >= metrics.widthPixels ); 

        if( !bIsVisualPortrait )
        { 
            // Swap the orientation to match the VISUAL portrait mode
            if( this.activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT )
             { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); }
            else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); }
        }
        else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); }

    }

Działa jak marzenie!

Codebeat
źródło
1

Użyj tego sposobu

    int orientation = getResources().getConfiguration().orientation;
    String Orintaion = "";
    switch (orientation)
    {
        case Configuration.ORIENTATION_UNDEFINED: Orintaion = "Undefined"; break;
        case Configuration.ORIENTATION_LANDSCAPE: Orintaion = "Landscrape"; break;
        case Configuration.ORIENTATION_PORTRAIT:  Orintaion = "Portrait"; break;
        default: Orintaion = "Square";break;
    }

w Sznurku masz Oriantion


źródło
1

jest na to wiele sposobów, ten fragment kodu działa dla mnie

 if (this.getWindow().getWindowManager().getDefaultDisplay()
                .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
             // portrait mode
} else if (this.getWindow().getWindowManager().getDefaultDisplay()
                .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
                      // landscape
        }
Mehroz Munir
źródło
1

Myślę, że to rozwiązanie jest łatwe

if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
  user_todat_latout = true;
} else {
  user_todat_latout = false;
}
Issac Nabil
źródło
Zasadniczo odpowiedzi są o wiele bardziej pomocne, jeśli zawierają wyjaśnienie, do czego służy kod i dlaczego rozwiązuje problem bez przedstawiania innych.
Tom Aranda,
tak, przepraszam za to, pomyślałem, że nie trzeba dokładnie wyjaśniać tego bloku sprawdzania kodu, jeśli jest równy Configuration.ORIENTATION_PORTRAIT, co oznacza, że ​​aplikacja jest portretowa :)
Issac Nabil
1

Po prostu prosty dwuliniowy kod

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
    // do something in landscape
} else {
    //do in potrait
}
Rezaul Karim
źródło
0

Proste i łatwe :)

  1. Utwórz 2 układy xml (tj. Pionowo i Poziomo)
  2. W pliku Java napisz:

    private int intOrientation;

    w onCreatemetodzie i przed setContentViewnapisz:

    intOrientation = getResources().getConfiguration().orientation;
    if (intOrientation == Configuration.ORIENTATION_PORTRAIT)
        setContentView(R.layout.activity_main);
    else
        setContentView(R.layout.layout_land);   // I tested it and it works fine.
Kerelos
źródło
0

Warto również zauważyć, że w dzisiejszych czasach nie ma powodu, aby sprawdzać wyraźną orientację, getResources().getConfiguration().orientationjeśli robisz to z powodów układu, ponieważ obsługa wielu okien wprowadzona w systemie Android 7 / API 24+ może dość popsuć układy w obu orientacja. Lepiej rozważyć użycie <ConstraintLayout>i alternatywne układy zależne od dostępnej szerokości lub wysokości , wraz z innymi sztuczkami w celu ustalenia, który układ jest używany, np. Obecność lub brak niektórych fragmentów dołączanych do działania.

qix
źródło
0

Możesz użyć tego (na podstawie tutaj ):

public static boolean isPortrait(Activity activity) {
    final int currentOrientation = getCurrentOrientation(activity);
    return currentOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT || currentOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}

public static int getCurrentOrientation(Activity activity) {
    //code based on https://www.captechconsulting.com/blog/eric-miles/programmatically-locking-android-screen-orientation
    final Display display = activity.getWindowManager().getDefaultDisplay();
    final int rotation = display.getRotation();
    final Point size = new Point();
    display.getSize(size);
    int result;
    if (rotation == Surface.ROTATION_0
            || rotation == Surface.ROTATION_180) {
        // if rotation is 0 or 180 and width is greater than height, we have
        // a tablet
        if (size.x > size.y) {
            if (rotation == Surface.ROTATION_0) {
                result = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            } else {
                result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
            }
        } else {
            // we have a phone
            if (rotation == Surface.ROTATION_0) {
                result = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
            } else {
                result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
            }
        }
    } else {
        // if rotation is 90 or 270 and width is greater than height, we
        // have a phone
        if (size.x > size.y) {
            if (rotation == Surface.ROTATION_90) {
                result = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            } else {
                result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
            }
        } else {
            // we have a tablet
            if (rotation == Surface.ROTATION_90) {
                result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
            } else {
                result = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
            }
        }
    }
    return result;
}
programista Androida
źródło