Ориентация экрана Android различается на разных устройствах

Описание

У меня есть действие, которое отображает предварительный просмотр камеры на виде поверхности. Я не хочу, чтобы он перезапускался при изменении ориентации (поскольку он постоянно сканирует QR-коды), поэтому ориентация заблокирована в портретной ориентации.

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

Чтобы решить эту проблему, я подключился к диспетчеру датчиков, чтобы считывать ориентацию в реальном времени. (См. код ниже). После прочтения я сам разрабатываю ориентацию и перемещаю свои инструкции по мере необходимости, когда мне присылают каждое обновление. Это работало для меня до недавнего времени. При тестировании на планшетах Asus Transformer Prime и Xoom. Планшет возвращает ориентацию как «90» для портретной ориентации, а не «0», как мои другие 2 телефона. Итак, как вы можете видеть в коде ниже, я проверяю планшеты (большие экраны) и минус лишние 90 градусов.

Проблема

Проблема в том, что новый планшет Nexus 7 не имеет этой дополнительной предвзятости. В портретном режиме он возвращает «0», но я определяю его как планшет, поэтому минус 90 градусов, поэтому результат равен 270, и он размещает мои инструкции, как если бы планшет находился в ландшафтном режиме. Я предполагаю, что причиной этого является то, что Xoom / Transformer был разработан для использования в альбомной ориентации, а Nexus — в портретной, но если я не знаю обо всех затронутых устройствах, это не поможет.

Вопрос

Есть ли надежный способ определить ориентацию на всех устройствах и вернуть результаты в «реальном времени», как в приведенном ниже коде, но принимая во внимание ориентацию устройства по умолчанию (т.е. телефоны + Nexus 7 портретные, но большинство планшетов пейзаж)?

Текущий код

    boolean large = ((getBaseContext().getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE);
    boolean xlarge = ((getBaseContext().getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == 4);       
    isTablet = large || xlarge;
    myOrientationEventListener = new OrientationEventListener(getBaseContext(), SensorManager.SENSOR_DELAY_NORMAL)
    {

        @Override
        public void onOrientationChanged(int orientation)
        {
            if (orientation == -1)
            {
                return;
            }

            if (isTablet)
            {
                orientation += -90;
                if (orientation < 0) // keep the result between 0-360
                {
                    orientation += 360;
                }
            }

            // Work out the orientation

            if (orientation >= 60 && orientation <= 140)
            {
                screenOrientation = ScreenOrientation.Landscape_Reversed;
            }
            else if (orientation >= 140 && orientation <= 220)
            {
                screenOrientation = ScreenOrientation.Portrait_Reversed;
            }
            else if (orientation >= 220 && orientation <= 300)
            {
                screenOrientation = ScreenOrientation.Landscape;
            }
            else
            {
                screenOrientation = ScreenOrientation.Portrait;
            }

            //... Do stuff with new orientation here
        }
    };

person JonWillis    schedule 31.08.2012    source источник


Ответы (1)


Починил это

Заменил код

        if (isTablet)
        {
            orientation += -90;
            if (orientation < 0) // keep the result between 0-360
            {
                orientation += 360;
            }
        }

Со следующим

            //Check "normal" screen orientation and adjust accordingly
            int naturalOrientation = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
            if (naturalOrientation == Surface.ROTATION_0)
            {
                Logging.d(TAG, "Rotation ROTATION_0");
            }
            else if (naturalOrientation == Surface.ROTATION_90)
            {
                Logging.d(TAG, "Rotation ROTATION_90");
                orientation += 90;
            }
            else if (naturalOrientation == Surface.ROTATION_180)
            {
                Logging.d(TAG, "Rotation ROTATION_180");
                orientation += 180;
            }
            else if (naturalOrientation == Surface.ROTATION_270)
            {
                Logging.d(TAG, "Rotation ROTATION_270");
                orientation += 270;
            }

            if (orientation > 360) // Check if we have gone too far forward with rotation adjustment, keep the result between 0-360
            {
                orientation -= 360;
            }
person JonWillis    schedule 31.08.2012
comment
Эта статья для разработчиков содержит несколько полезных также информация по теме. - person FoamyGuy; 31.08.2012
comment
Спасибо FoamGuy. Я никогда не читал блог, только руководство разработчика - person JonWillis; 03.09.2012