Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android screen orientation to sensor

I want to force the screen orientation to landscape on button click by setting

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

It works fine. Now I want the application to follow the sensor so that orientation is brought back to portrait when tilted back to portrait. I know this is possible by setting setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); but don't know where to set it. If the orientation is forced to landscape, orientation will remain in landscape no matter you tilt in any direction. Can anyone specify how to reset the orientation flag?

like image 912
Kulai Avatar asked Jan 19 '11 06:01

Kulai


People also ask

What is screen orientation full sensor?

"sensor" - The orientation is determined by the device orientation sensor. The orientation of the display depends on how the user is holding the device; it changes when the user rotates the device. Some devices, though, will not rotate to all four possible orientations, by default.

What sensor gives orientation?

The Android platform provides two sensors that let you determine the position of a device: the geomagnetic field sensor and the accelerometer.

How do I manage screen orientation on Android?

If you want to manually handle orientation changes in your app you must declare the "orientation" , "screenSize" , and "screenLayout" values in the android:configChanges attributes. You can declare multiple configuration values in the attribute by separating them with a pipe | character.


1 Answers

Current YouTube app does what you are asking for.
I've dealt with same kind of problem in my application for video playback.

If user forces orientation to landscape when he/she was in portrait, initialise OrientationEventListener which notifies you on device orientation from SensorManager which ranges from 0 to 360.

Watch if device tilts to landscape orientation range which would be around (orientation >= 60 && orientation <= 120) || (orientation >= 240 && orientation <= 300) and save this state to a enum or a flag and then if device goes back to Portrait orientation range (orientation <= 40 || orientation >= 320), check the enum/flag and call setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); , reset the flag/enum and disable the sensor until user force orientation again.

Here is the demo code:

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

This worked similar to YouTube functionality, hope this helps.

like image 63
CodeFury Avatar answered Sep 21 '22 23:09

CodeFury