Проверьте ориентацию на телефоне Android


Ответы:


676

Текущая конфигурация, используемая для определения, какие ресурсы получить, доступна из Configurationобъекта Resources :

getResources().getConfiguration().orientation;

Вы можете проверить ориентацию, посмотрев на ее значение:

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

Более подробную информацию можно найти в Android Developer .


2
Извините, я неправильно понял, я думал, что вы говорите, что служба не увидит изменения конфигурации, если изменения конфигурации. То, что вы описываете, это то, что ... ну, он ничего не видит, потому что ничего не меняется, потому что программа запуска заблокировала ориентацию экрана и не позволяет ему измениться. Так что это правильно, что .orientation не меняется, потому что ориентация не изменилась. Экран все еще портретный.
hackbod

Самое близкое, что я могу сделать, это прочитать ориентацию с датчиков, которая включает в себя математику, которую я на самом деле не очень хочу выяснить в данный момент.
Архимед Траяно

13
Здесь нечего раздражать. Экран не вращался, он все еще в портретной ориентации, вращение не видно. Если вы хотите следить за тем, как пользователь перемещает свой телефон, независимо от того, как поворачивается экран, то да, вам нужно непосредственно следить за датчиком и решать, как вы хотите интерпретировать полученную информацию о том, как движется устройство.
hackbod

4
Это не удастся, если ориентация экрана будет фиксированной.
AndroidDev

7
Если действие блокирует display ( 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

С другой стороны, width () и height () всегда корректны (они используются оконным менеджером, так что должно быть лучше). Я бы сказал, что лучшая идея - ВСЕГДА проверять ширину / высоту. Если вы думаете о мгновении, это именно то, что вы хотите - узнать, если ширина меньше высоты (портрет), наоборот (пейзаж) или они одинаковы (квадрат).

Тогда все сводится к следующему простому коду:

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со следующим содержанием:

Рез / ценности-земля / layouts.xml:

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

RES / значения порта / 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 [] values) вычисляет ориентацию устройства на основе матрицы вращения.
user1914692

29

Вот пример кода, как получить ориентацию экрана, рекомендованный hackbod и Martijn :

❶ Триггер при изменении ориентации:

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

❷ Получить текущую ориентацию, как рекомендуют hackbod :

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

AreЕсть альтернативное решение для получения текущей ориентации экрана ❷ придерживайтесь решения 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

Прошло некоторое время с тех пор, как большинство этих ответов было опубликовано, а некоторые используют устаревшие методы и константы.

Я обновил код Jarek, чтобы больше не использовать эти методы и константы:

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
Lester

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 (Configuration newConfig) и используйте newConfig, direction, если вы хотите получать уведомление о новой ориентации перед вызовом 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, что означает приложение в портрете :)
Исаак Набиль

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если вы делаете это по причинам компоновки, поскольку поддержка многооконных окон, представленная в 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.