Ориентация экрана Android на сенсор - PullRequest
10 голосов
/ 19 января 2011

Я хочу принудительно установить ориентацию экрана при нажатии кнопки, установив

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Работает нормально. Теперь я хочу, чтобы приложение следовало за датчиком, чтобы ориентация возвращалась к портрету при наклоне назад к портрету. Я знаю, что это возможно, установив setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);, но не знаю, где его установить. Если ориентация принудительная в альбомной ориентации, ориентация останется в альбомной ориентации независимо от того, наклонен ли вы в любом направлении. Кто-нибудь может указать, как сбросить флаг ориентации?

Ответы [ 3 ]

11 голосов
/ 26 февраля 2015

Текущее приложение YouTube делает то, что вы просите.
Я столкнулся с такой же проблемой в моем приложении для воспроизведения видео.

Если пользователь вынуждает ориентироваться в альбомной ориентации, когда он / она находится в портретной ориентации, инициализируйте OrientationEventListener , который уведомляет вас об ориентации устройства от SensorManager в диапазоне от 0 до 360.

Наблюдайте, наклоняется ли устройство к диапазону альбомной ориентации, который будет около (orientation >= 60 && orientation <= 120) || (orientation >= 240 && orientation <= 300), и сохраняйте это состояние в перечислении или флаге, а затем, если устройство возвращается в диапазон книжной ориентации (orientation <= 40 || orientation >= 320), проверьте перечисление / установите флажок и наберите setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);, сбросьте флажок / перечисление и отключите датчик до тех пор, пока пользователь снова не установит ориентацию.

Вот демонстрационный код:

private enum SensorStateChangeActions {
        WATCH_FOR_LANDSCAPE_CHANGES, SWITCH_FROM_LANDSCAPE_TO_STANDARD, WATCH_FOR_POTRAIT_CHANGES, SWITCH_FROM_POTRAIT_TO_STANDARD;
}

private SensorStateChangeActions mSensorStateChanges;

public void goFullScreen() {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
        mSensorStateChanges = SensorStateChangeActions.WATCH_FOR_LANDSCAPE_CHANGES;
        if (null == sensorEvent)
            initialiseSensor(true);
        else
            sensorEvent.enable();
}

public void shrinkToPotraitMode() {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        mSensorStateChanges = SensorStateChangeActions.WATCH_FOR_POTRAIT_CHANGES;
        if (null == sensorEvent)
            initialiseSensor(true);
        else
            sensorEvent.enable();
}
/**
 * Initialises system sensor to detect device orientation for player changes.
 * Don't enable sensor until playback starts on player
 *
 * @param enable if set, sensor will be enabled.
 */
private void initialiseSensor(boolean enable) {
    sensorEvent = new OrientationEventListener(this,
            SensorManager.SENSOR_DELAY_NORMAL) {

        @Override
        public void onOrientationChanged(int orientation) {
            /*
             * This logic is useful when user explicitly changes orientation using player controls, in which case orientation changes gives no callbacks.
             * we use sensor angle to anticipate orientation and make changes accordingly.
             */
            if (null != mSensorStateChanges
                    && mSensorStateChanges == SensorStateChangeActions.WATCH_FOR_LANDSCAPE_CHANGES
                    && ((orientation >= 60 && orientation <= 120) || (orientation >= 240 && orientation <= 300))) {
                mSensorStateChanges = SensorStateChangeActions.SWITCH_FROM_LANDSCAPE_TO_STANDARD;
            } else if (null != mSensorStateChanges
                    && mSensorStateChanges == SensorStateChangeActions.SWITCH_FROM_LANDSCAPE_TO_STANDARD
                    && (orientation <= 40 || orientation >= 320)) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
                mSensorStateChanges = null;
                sensorEvent.disable();
            } else if (null != mSensorStateChanges
                    && mSensorStateChanges == SensorStateChangeActions.WATCH_FOR_POTRAIT_CHANGES
                    && ((orientation >= 300 && orientation <= 359) || (orientation >= 0 && orientation <= 45))) {
                mSensorStateChanges = SensorStateChangeActions.SWITCH_FROM_POTRAIT_TO_STANDARD;
            } else if (null != mSensorStateChanges
                    && mSensorStateChanges == SensorStateChangeActions.SWITCH_FROM_POTRAIT_TO_STANDARD
                    && ((orientation <= 300 && orientation >= 240) || (orientation <= 130 && orientation >= 60))) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
                mSensorStateChanges = null;
                sensorEvent.disable();
            }
        }
    };
    if (enable)
        sensorEvent.enable();
}

Это работает аналогично функциональности YouTube, надеюсь, это поможет.

4 голосов
/ 19 января 2011

Я думаю, что здесь вы должны использовать setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)

1 голос
/ 19 января 2011

Это зависит от того, когда вы хотите, чтобы датчик снова обнаружил вращение.

Лично в приложении, которое я разрабатываю, у меня есть одно конкретное занятие, в котором я должен быть в портретном режиме, поэтому я использую setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);в onResume() этого действия и setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); в onPause(), и оно работает просто отлично, когда я вхожу в действие, оно устанавливает портрет, если это не так и не позволяет измениться, и при выходе из датчика снова работает ...

Где вы пытаетесь включить и отключить датчик?

...