Перевірте орієнтацію на телефоні Android


Відповіді:


676

Поточна конфігурація, яка використовується для визначення ресурсів для отримання, доступна в Configurationоб’єкті Resources :

getResources().getConfiguration().orientation;

Ви можете перевірити орієнтацію, подивившись його значення:

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

Більше інформації можна знайти в розробнику Android .


2
Пробачте, я неправильно зрозумів, я подумав, що ви говорите, що служба не побачить зміни конфігурації, якщо зміниться конфігурація. Те, що ви описуєте, це те, що ... ну, він нічого не бачить, тому що нічого не змінюється, тому що пускач заблокував орієнтацію екрана і не дозволяє йому змінюватися. Отже, правильно .орієнтація не змінюється, оскільки орієнтація не змінилася. Екран все ще портрет.
хакбод

Найближче, що я можу зробити, - це прочитати орієнтацію з датчиків, що передбачає математику, яку я не дуже захоплююсь з'ясуванням на даний момент.
Архімед Траяно

13
Драмати нема чого. Екран не обертався, він все ще знаходиться в портреті, обертання не видно. Якщо ви хочете відслідковувати, як користувач рухається своїм телефоном, незалежно від того, як повертається екран, то так, вам потрібно безпосередньо спостерігати за датчиком і вирішити, як ви хочете інтерпретувати отриману інформацію про те, як рухається пристрій.
хакбод

4
Це не вдасться, якщо орієнтація екрана виправлена.
AndroidDev

7
Якщо активність блокує дисплей ( android:screenOrientation="portrait"), цей метод поверне те саме значення незалежно від того, як користувач повертає пристрій. У цьому випадку ви використовуєте акселерометр або датчик сили тяжіння, щоб правильно визначити орієнтацію.
Кіт

169

Якщо ви використовуєте орієнтацію getResources (). GetConfiguration (). На деяких пристроях, ви отримаєте помилку. Цей підхід ми використовували спочатку в http://apphance.com . Завдяки віддаленому веденню журналу Apphance ми могли бачити його на різних пристроях, і ми побачили, що тут фрагментація грає свою роль. Я бачив дивні випадки: наприклад чергування портрета та квадрата (?!) на 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

або зовсім не змінюють орієнтацію:

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

З іншого боку, ширина () та висота () завжди правильні (її використовує менеджер вікон, тому так краще бути). Я б сказав, що найкраща ідея - ЗАВЖДИ робити перевірку ширини / висоти. Якщо ви задумаєтесь про якусь мить, це саме те, що ви хочете - знати, чи ширина менша за висоту (портрет), протилежну (пейзаж) чи вони однакові (квадрат).

Тоді зводиться до цього простого коду:

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

3
Дякую! Ініціалізація «орієнтації» є зайвою.
MrMaffen

getWidthі getHeightне застаріли.
FindOut_Quran

3
@ user3441905, так вони є. Використовуйте getSize(Point outSize)замість цього. Я використовую API 23.
WindRider

@ jarek-potiuk застаріло.
Аїд

53

Ще один спосіб вирішення цієї проблеми - це не покладатися на правильне значення повернення з дисплея, а покладатися на вирішення ресурсів Android.

Створіть файл layouts.xmlу папках res/values-landтаres/values-port із наступним вмістом:

res / values-land / layouts.xml:

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

res / values-port / layouts.xml:

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

Тепер у своєму вихідному коді ви можете отримати доступ до поточної орієнтації наступним чином:

context.getResources().getBoolean(R.bool.is_landscape)

1
Мені це подобається, оскільки він використовує будь-який спосіб, коли система вже визначає орієнтацію
KrustyGString

1
Найкраща відповідь для перевірки пейзажу / портрета!
vtlinh

Яким буде його значення у файлі значень за замовчуванням?
Шашанк Мішра

46

Повний спосіб вказати поточну орієнтацію телефону:

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

Шар Бінь Нгуен


6
У вашому дописі є помилка друку - вона повинна сказати .getRotation () not getOrientation
Кіт

1
+1 для цього. Мені потрібно було знати точну орієнтацію, а не лише пейзаж проти портрета. getOrientation () правильна, якщо ви не перебуваєте на SDK 8+ і в цьому випадку ви повинні використовувати getRotation (). Режими "зворотного" підтримуються в SDK 9+.
Пол

6
@Keith @Paul Я не пам’ятаю, як це getOrientation()працює, але це неправильно, якщо використовується getRotation(). Отримайте "Returns the rotation of the screen from its "natural" orientation." джерело обертання . Отже, по телефону, який говорить ROTATION_0 - портрет, швидше за все, правильно, але на планшеті його "природна" орієнтація - це, ймовірно, пейзаж, і ROTATION_0 повинен повертати пейзаж замість портрета.
jp36

Схоже, це найкращий метод приєднатися вперед: developer.android.com/reference/android/view/…
jaysqrd

Це неправильна відповідь. Чому за нього проголосували? getOrientation (float [] R, float [] значення) обчислює орієнтацію пристрою на основі матриці обертання.
користувач1914692

29

Ось демонстраційний фрагмент коду, як отримати орієнтацію на екран, рекомендували hackbod та Martijn :

❶ Запуск при зміні орієнтації:

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

Recommend Отримати поточну орієнтацію як hackbod рекомендують:

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

Є альтернативне рішення для отримання поточної орієнтації екрана ❷ дотримуйтесь рішення Martijn :

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

Примітка : я намагався реалізувати ❷ & ❸, але в RealDevice (NexusOne SDK 2.3) орієнтація повертає неправильну орієнтацію.

★ Тому я рекомендую застосовувати рішення ❷, щоб отримати орієнтацію на екран, які мають більшу перевагу: чітко, просто та працюють як шарм.

★ Перевірте ретельно повернення орієнтації, щоб гарантувати правильність, як ми очікували (може бути обмеженою, залежно від специфікації фізичних пристроїв)

Сподіваюся, це допоможе,


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

13

Використовуйте getResources().getConfiguration().orientationправильний шлях.

Вам просто потрібно стежити за різними типами ландшафтів, ландшафтом, який пристрій зазвичай використовує, та іншими.

Досі не розумію, як це впоратися.


12

Минуло деякий час з часу опублікування більшості цих відповідей, а деякі використовують тепер застарілі методи та константи.

Я оновив код Ярека, щоб більше не використовувати ці методи та константи:

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

Зауважте, що режим Configuration.ORIENTATION_SQUAREбільше не підтримується.

Я вважав це надійним на всіх пристроях, на яких я тестував, на відміну від методу, що пропонує використання getResources().getConfiguration().orientation


Зауважте, що для getOrient.getSize (розмір) потрібен рівень 13 api
Лестер,

6

Перевірте орієнтацію екрана під час виконання.

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

5

Є ще один спосіб зробити це:

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


4

Випробуваний у 2019 році на API 28, незалежно від того, користувач встановив портретну орієнтацію чи ні, і з мінімальним кодом у порівнянні з іншою, застарілою відповіддю , наступне забезпечує правильну орієнтацію:

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

2

Я думаю, що цей код може працювати після зміни в орієнтації

Display getOrient = getWindowManager().getDefaultDisplay();

int orientation = getOrient.getOrientation();

перекрийте функцію Activity.onConfigurationChanged (Конфігурація newConfig) та використовуйте newConfig, орієнтацію, якщо ви хочете отримувати сповіщення про нову орієнтацію перед викликом setContentView.


2

Я думаю, що використання getRotationv () не допомагає, оскільки http://developer.android.com/reference/android/view/Display.html#getRotation%28%29 getRotation () Повертає обертання екрана від його "природного" орієнтація.

тому, якщо ви не знаєте "природну" орієнтацію, обертання є безглуздим.

я знайшов простіший шлях,

  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

скажіть, будь ласка, чи є проблема з цим у когось?


2

таке перекриття всіх телефонів, таких як oneplus3

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

правильний код наступним чином:

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

1

Старий пост я знаю. Незалежно від того, яка орієнтація може бути або змінена і т. Д. Я розробив цю функцію, яка використовується для встановлення пристрою в правильній орієнтації, без необхідності знати, як організовані функції портрету та пейзажу на пристрої.

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

    }

Працює як шарм!


1

Використовуйте цей спосіб,

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

у Рядок у вас є Оріант


1

Є багато способів зробити це, цей фрагмент коду працює для мене

 if (this.getWindow().getWindowManager().getDefaultDisplay()
                .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
             // portrait mode
} else if (this.getWindow().getWindowManager().getDefaultDisplay()
                .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
                      // landscape
        }

1

Я думаю, що це рішення легке

if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
  user_todat_latout = true;
} else {
  user_todat_latout = false;
}

Як правило, відповіді набагато корисніші, якщо вони включають пояснення того, що призначений для виконання коду та чому це вирішує проблему, не вводячи інших.
Том Аранда

так вибачте за це, я думав, що не потрібно пояснювати саме цей блок перевірки коду, якщо рівний Configuration.ORIENTATION_PORTRAIT, це середній додаток у портреті :)
Issac Nabil

1

Просто простий дворядковий код

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
    // do something in landscape
} else {
    //do in potrait
}

0

Просто і легко :)

  1. Зробіть 2 xml макети (тобто портрет та пейзаж)
  2. У файлі java напишіть:

    private int intOrientation;

    по onCreateспособу і перед setContentViewзаписом:

    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.

0

Варто також зазначити, що в даний час є менш вагомих причин перевірити чітку орієнтацію, getResources().getConfiguration().orientationякщо ви робите це з міркувань, так як підтримка Multi-Window, впроваджена в Android 7 / API 24+, може трохи повозитися з вашими макетами. орієнтація. Краще розглянути можливість використання <ConstraintLayout>і альтернативних макетів в залежності від доступної ширини або висоти , поряд з іншими трюками для визначення , який макет використовується, наприклад , наявність або відсутність певних фрагментів прив'язуючись до вашої діяльності.


0

Ви можете скористатися цим (на основі тут ):

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.