SCREEN_ORIENTATION_LANDSCAPE вверх дном - Почему?

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

 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) на всех устройствах?

Чтобы сделать это более понятным и понятным, выполните следующие действия:

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

Ответ 1

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

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

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

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

Ответ 2

Попробуйте отключить и активировать ориентацию с помощью кода (это будет работать с уровнем 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);
}

Ответ 3

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

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

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

  </application>

Ответ 4

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

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