Ориентация экрана пейзаж вверх ногами-почему?

я использую следующий код для установки блокировки ориентации в соответствии с предпочтениями пользователя:

 private void doLock(boolean locked) {
     if (locked) {
       int o = getResources().getConfiguration().orientation;
       if (o == Configuration.ORIENTATION_LANDSCAPE)
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);       
       else if (o == Configuration.ORIENTATION_PORTRAIT)
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);       
     } 
     else {
       setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
     }
 }

он работает, за исключением случая, когда я нахожусь в разблокированном режиме (SCREEN_ORIENTATION_SENSOR) с отображением экрана LANDSCAPE правильно (!), затем вызвать doLock(true) и...

вместо блокировки экрана на LANDSCAPE в текущем (правильном) ландшафтном представлении он блокируется на вниз ландшафтный вид. т. е. то же самое точное, но перевернуть вертикально (y будет -y).

почему это и как мне подойти к этой проблеме, чтобы исправить ее?

мой первоначальный запрос показывает, что есть несколько возможности, отличные от общих двух (portrait, landscape), в том числе reverseLandscape, но моя интуиция говорит мне, что эта проблема может быть зависит от устройства и поэтому, используя его, я могу исправить проблему только для своего телефона, но не для всех других устройств.

есть ли способ заставить правильно landscape ориентация (при переключении с sensor) во всех устройствах?

чтобы сделать это яснее и проще воспроизвести, вот шаги, которые показывают проблему:

  1. начните с телефона, повернутого вправо (стрелки), в разблокированном режиме (SCREEN_ORIENTATION_SENSOR) с отображением экрана LANDSCAPE правильно (!),
  2. затем вызвать doLock(true)
  3. вместо блокировки экрана на LANDSCAPE в его текущем (правильном) ландшафте view, он блокируется на вниз ландшафтный вид. т. е. то же самое точное, но перевернуть вертикально (y становится -y).

4 ответов


то, что вы описываете, не является ошибкой, а скорее ожидаемым поведением от Android 2.2 или ниже.

@forgivegod предоставил теоретически правильный подход, за исключением того, что для Android 2.2 или ниже screenOrientation.reverseLandscape и screenOrientation.reversePortrait значения не распознаются, даже если они поддельные (как это делает код @forgivegod).

Я уверен, что вы видите эту проблему, когда вы поворачиваете телефон по часовой стрелке (вращение=3), но не против часовой стрелки (вращение=1).

попробуйте с Android 2.3 или выше и посмотрим, что получится.


попробуйте следующее, Чтобы отключить и включить ориентацию с помощью кода (это будет работать на уровне API 7 и выше) :

public static void disableRotation(Activity activity) {
    final int orientation = activity.getResources().getConfiguration().orientation;
    final int rotation = activity.getWindowManager().getDefaultDisplay()
            .getOrientation();

    // Copied from Android docs, since we don't have these values in Froyo
    // 2.2
    int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
    int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;

    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO) {
        SCREEN_ORIENTATION_REVERSE_LANDSCAPE = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        SCREEN_ORIENTATION_REVERSE_PORTRAIT = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
    }

    if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
    } else if (rotation == Surface.ROTATION_180
            || rotation == Surface.ROTATION_270) {
        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
        } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
            activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
        }
    }
}

public static void enableRotation(Activity activity) {
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}

простой и функциональный>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

    <activity
        android:screenOrientation="sensorLandscape"
    </activity>

  </application>

попробуйте с универсальной альбомной ориентацией

private static final int ORIENTATION_90 = 1;
private static final int ORIENTATION_0 = 0;
private static final int ORIENTATION_180 = 2;
private static final int ORIENTATION_270 = 3;

switch (orientation)
    {
      default:
      case ORIENTATION_0: // Portrait
        //dostuff
        break;
      case ORIENTATION_90: // Landscape left
        //do stuff
        break;
      case ORIENTATION_180: // Upside down.
        //do stuff
        break;
      case ORIENTATION_270: // Landscape right
        //do stuff
        break;
      }