11

I want to find the camera screen orientation in locked portrait orientation mode, well I am using camera in my fragment class and I have already set my screen orientation as portrait, but the problem I am facing is, when I turn my camera from portrait to landscape its getting changed and I need to set capture button visible only when the camera is in portrait mode. Can anyone help me to get the orientation changes in portrait mode? Below is my code:

getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

sensorManager.registerListener(new SensorEventListener() {

    int orientation=-1;;

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.values[1] < 6.5 && event.values[1] > -6.5) {
            if (orientation!=1) {
                Log.d("Sensor", "Landscape");
            }
            orientation = 1;
        } else {
            if (orientation!=0) {
                Log.d("Sensor", "Portrait");
            }
            orientation = 0;
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
}, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);

if (orientation == 0) {
    // capture button visisble
} else {
    // invisible
}
MysticMagicϡ
  • 28,593
  • 16
  • 73
  • 124
Vicky
  • 921
  • 1
  • 11
  • 33

3 Answers3

38

You can use OrientationEventListener for this. this is class that customise it.

public abstract class SimpleOrientationListener extends OrientationEventListener {

        public static final int CONFIGURATION_ORIENTATION_UNDEFINED = Configuration.ORIENTATION_UNDEFINED;
        private volatile int defaultScreenOrientation = CONFIGURATION_ORIENTATION_UNDEFINED;
        public int prevOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
        private Context ctx;
        private ReentrantLock lock = new ReentrantLock(true);

        public SimpleOrientationListener(Context context) {
            super(context);
            ctx = context;
        }

        public SimpleOrientationListener(Context context, int rate) {
            super(context, rate);
            ctx = context;
        }

        @Override
        public void onOrientationChanged(final int orientation) {
            int currentOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
            if (orientation >= 330 || orientation < 30) {
                currentOrientation = Surface.ROTATION_0;
            } else if (orientation >= 60 && orientation < 120) {
                currentOrientation = Surface.ROTATION_90;
            } else if (orientation >= 150 && orientation < 210) {
                currentOrientation = Surface.ROTATION_180;
            } else if (orientation >= 240 && orientation < 300) {
                currentOrientation = Surface.ROTATION_270;
            }

            if (prevOrientation != currentOrientation && orientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
                prevOrientation = currentOrientation;
                if (currentOrientation != OrientationEventListener.ORIENTATION_UNKNOWN)
                    reportOrientationChanged(currentOrientation);
            }

        }

        private void reportOrientationChanged(final int currentOrientation) {

            int defaultOrientation = getDeviceDefaultOrientation();
            int orthogonalOrientation = defaultOrientation == Configuration.ORIENTATION_LANDSCAPE ? Configuration.ORIENTATION_PORTRAIT
                    : Configuration.ORIENTATION_LANDSCAPE;

            int toReportOrientation;

            if (currentOrientation == Surface.ROTATION_0 || currentOrientation == Surface.ROTATION_180)
                toReportOrientation = defaultOrientation;
            else
                toReportOrientation = orthogonalOrientation;

            onSimpleOrientationChanged(toReportOrientation);
        }

        /**
         * Must determine what is default device orientation (some tablets can have default landscape). Must be initialized when device orientation is defined.
         *
         * @return value of {@link Configuration#ORIENTATION_LANDSCAPE} or {@link Configuration#ORIENTATION_PORTRAIT}
         */
        private int getDeviceDefaultOrientation() {
            if (defaultScreenOrientation == CONFIGURATION_ORIENTATION_UNDEFINED) {
                lock.lock();
                defaultScreenOrientation = initDeviceDefaultOrientation(ctx);
                lock.unlock();
            }
            return defaultScreenOrientation;
        }

        /**
         * Provides device default orientation
         *
         * @return value of {@link Configuration#ORIENTATION_LANDSCAPE} or {@link Configuration#ORIENTATION_PORTRAIT}
         */
        private int initDeviceDefaultOrientation(Context context) {

            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Configuration config = context.getResources().getConfiguration();
            int rotation = windowManager.getDefaultDisplay().getRotation();

            boolean isLand = config.orientation == Configuration.ORIENTATION_LANDSCAPE;
            boolean isDefaultAxis = rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180;

            int result = CONFIGURATION_ORIENTATION_UNDEFINED;
            if ((isDefaultAxis && isLand) || (!isDefaultAxis && !isLand)) {
                result = Configuration.ORIENTATION_LANDSCAPE;
            } else {
                result = Configuration.ORIENTATION_PORTRAIT;
            }
            return result;
        }

        /**
         * Fires when orientation changes from landscape to portrait and vice versa.
         *
         * @param orientation value of {@link Configuration#ORIENTATION_LANDSCAPE} or {@link Configuration#ORIENTATION_PORTRAIT}
         */
        public abstract void onSimpleOrientationChanged(int orientation);

    }

Then where you want to detect orientation just call

SimpleOrientationListener mOrientationListener = new SimpleOrientationListener(
                context) {

            @Override
            public void onSimpleOrientationChanged(int orientation) {
                if(orientation == Configuration.ORIENTATION_LANDSCAPE){

                }else if(orientation == Configuration.ORIENTATION_PORTRAIT){

                }
            }
        };
        mOrientationListener.enable();
Suhail Mehta
  • 5,514
  • 2
  • 23
  • 37
  • what am i supposed to declare inside onSimpleOrientatioChanged method? – Vicky Dec 23 '14 at 09:23
  • onCreate() will do. You have to write your code in this method what you want to do with Orientation change – Suhail Mehta Dec 23 '14 at 09:25
  • well i need when screen changes from portrait to landscape button should be invisible and visible only when screen is in portrait orientation – Vicky Dec 23 '14 at 09:32
  • how can i detect whether the changed orientation is portrait or landscape? if i declare my code inside it will call whenever everytime changes either from PORT to LAND or LAND to PORT. – Vicky Dec 23 '14 at 09:35
  • i think we should boolean instead of int i am getting error. – Vicky Dec 23 '14 at 09:41
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/67523/discussion-between-rinnegan-naruto-and-suhail-mehta). – Vicky Dec 23 '14 at 09:47
  • Great answer @SuhailMehta. For others... don't forget to call `mOrientationListener.disable();` in your `onStop()` (if you enabled it in `onCreate()` ) – Tim Mar 24 '15 at 12:23
  • Thanks @SuhailMehta for great answer but how i can differ betweeen landscape and reverse landscape with this code? – Antwan Oct 02 '15 at 17:04
  • You are a life saver man .. I was stuck in his for a week . Just now fund ur post .. really happy .. keep up going – karthik kolanji Mar 18 '16 at 06:22
  • weird, this is not working for me. The callback onOrientationChanged was not being called. – Neon Warge Jul 08 '16 at 05:24
  • How to adapt this code to handle normal and reverse orientation ? – Antwan Mar 15 '17 at 05:51
0

You gonna have to use:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);


    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {

    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        //do your stuff with the button
    }
}

If you want your activity not to be recreated during orientation then use

android:configChanges="orientation|keyboardHidden|screenSize"

If you want your activity to be forced to stay portrait then you gonna have to use

in your manifest file in the activity you would like just try android:screenOrientation="portrait"

Hope it helps!!!

Kostas Drak
  • 3,222
  • 6
  • 28
  • 60
  • i am getting nullpointer exception @if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) – Vicky Dec 23 '14 at 06:13
  • well, its not getting the right one eventhough when i rotate the screen to landscape, it gets detected as portrait. – Vicky Dec 23 '14 at 07:10
  • above my code is working but it keeps on changing the value a little change could wake the code i just correct value to set for portrait and landscape if (event.values[1] < ? && event.values[1] > ?) – Vicky Dec 23 '14 at 09:11
  • What about `onOrientationChanged()` callback? – IgorGanapolsky Oct 26 '15 at 02:59
0

You can achieve the orientation change value, when your activity set to only Portrait or Landscape specific and you want to perform some action when orientation changes.

private OrientationEventListener orientationEventListener;

initialize this variable in your class and implement it's listener in onCreate

orientationEventListener = new OrientationEventListener(this) {
        @Override
        public void onOrientationChanged(int orientation) {

            Log.d("Orientation", orientation + " - " + currentOrientation);

            if (orientation >= 330 || orientation < 30) {
                currentOrientation = Surface.ROTATION_0;

            } else if (orientation >= 60 && orientation < 120) {
                currentOrientation = Surface.ROTATION_90;

            } else if (orientation >= 150 && orientation < 210) {
                currentOrientation = Surface.ROTATION_180;

            } else if (orientation >= 240 && orientation < 300) {
                currentOrientation = Surface.ROTATION_270;

            }
        }
    };

currentOrentation is integer value for later use in the activity other units.