59

I would like to find out the detailed orientation of a device, preferably one of SCREEN_ORIENTATION_LANDSCAPE, SCREEN_ORIENTATION_PORTRAIT, SCREEN_ORIENTATION_REVERSE_LANDSCAPE, SCREEN_ORIENTATION_REVERSE_PORTRAIT from ActivityInfo or equivalent.

Some of the answers here on StackOverflow included

getWindowManager().getDefaultDisplay().getRotation()

but this doesn't really tell me whether the device is in portrait or landscape mode, only how it's turned with reference to its natural position - which in turn can be landscape or portrait in the first place.

getResources().getConfiguration().orientation

returns one of the following three: ORIENTATION_LANDSCAPE, ORIENTATION_PORTRAIT, ORIENTATION_SQUARE, which then doesn't really tell me which way the phone is turned (whether it's upside down or which of the sides it's turned to).

I know I could use the latter in combination with DisplayMetrics to find out the device's natural orientation, but is there really no better way?

Zoltán
  • 21,321
  • 14
  • 93
  • 134

8 Answers8

91

I ended up using the following solution:

private int getScreenOrientation() {
    int rotation = getWindowManager().getDefaultDisplay().getRotation();
    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);
    int width = dm.widthPixels;
    int height = dm.heightPixels;
    int orientation;
    // if the device's natural orientation is portrait:
    if ((rotation == Surface.ROTATION_0
            || rotation == Surface.ROTATION_180) && height > width ||
        (rotation == Surface.ROTATION_90
            || rotation == Surface.ROTATION_270) && width > height) {
        switch(rotation) {
            case Surface.ROTATION_0:
                orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                break;
            case Surface.ROTATION_90:
                orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                break;
            case Surface.ROTATION_180:
                orientation =
                    ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                break;
            case Surface.ROTATION_270:
                orientation =
                    ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                break;
            default:
                Log.e(TAG, "Unknown screen orientation. Defaulting to " +
                        "portrait.");
                orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                break;              
        }
    }
    // if the device's natural orientation is landscape or if the device
    // is square:
    else {
        switch(rotation) {
            case Surface.ROTATION_0:
                orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                break;
            case Surface.ROTATION_90:
                orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                break;
            case Surface.ROTATION_180:
                orientation =
                    ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                break;
            case Surface.ROTATION_270:
                orientation =
                    ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                break;
            default:
                Log.e(TAG, "Unknown screen orientation. Defaulting to " +
                        "landscape.");
                orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                break;              
        }
    }

    return orientation;
}

NOTE: Some users (Geltrude and holtaf in the comments below) pointed out that this solution will not work on all devices as the direction of rotation from the natural orientation is not standardized.

Zoltán
  • 21,321
  • 14
  • 93
  • 134
  • 4
    This will fail if your activity has a fixed screen orientation. getRotation only reports a value when the screen orientation is not locked. – Johann Jul 30 '13 at 14:12
  • 2
    Fair enough, but if you locked the screen orientation, then you most probably know whether it's locked to landscape or portrait - so you don't need this code to figure it out. – Zoltán Jul 30 '13 at 14:28
  • Right for most of my users, this will fail with Xperia Tablet Z – Geltrude Sep 20 '13 at 10:27
  • 1
    @Geltrude how does it fail? Could you elaborate? – Zoltán Sep 20 '13 at 13:32
  • @Zoltan - screen is swapped of 180 degrees – Geltrude Sep 27 '13 at 13:24
  • 8
    This is great when you need to figure out to which direction to rotate the image captured from the Camera intent... Android sucks. – daniel.gindi Oct 17 '13 at 11:23
  • This will work in most cases. But, for example in landscape mode when you have rotation of 90 or 270 you don't know which one is the reversed landscape. It's very device specific. – holtaf Apr 16 '14 at 14:22
  • @holtaf: Thanks. I added a note about it. – Zoltán Apr 24 '14 at 07:26
  • I am using this code to set orientation metadata in recorded videos on background. If the screen is locked, it always returns the default orientation display and not the current one. – Bruno Siqueira Aug 14 '15 at 09:14
20

Simple approach would be to use

getResources().getConfiguration().orientation

1 is for Potrait and 2 for Landscape.

Nilesh
  • 532
  • 7
  • 13
  • 5
    The question asks for more detailed information, i.e. including reverse portrait and reverse landscape, which these functions do not provide. – Zoltán May 05 '14 at 17:44
16
public static int getScreenOrientation(Activity activity) {
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        int orientation = activity.getResources().getConfiguration().orientation;
        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
          if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270) {
            return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
          } else {
            return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
          }
        }
        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
          if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
            return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
          } else {
            return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
          }
        }
        return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
      }
8

I think your problem is that you can detect landscape and portrait but not reverse landscape and reverse protrait as they are not supported in older versions. To detect what you can do is that you can use both oreintation and rotation. I am giving you an idea it may be useful for you.

try this i think it may solve your problem.

            int orientation = getResources().getConfiguration().orientation;
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            int actual_orientation = -1;
            if (orientation == Configuration.ORIENTATION_LANDSCAPE
            &&  (rotation == Surface.ROTATION_0 
            ||  rotation == Surface.ROTATION_90)){
                orientation = Configuration.ORIENTATION_LANDSCAPE;
            } else if (orientation == Configuration.ORIENTATION_PORTRAIT
                  &&  (rotation == Surface.ROTATION_0 
                   ||  rotation == Surface.ROTATION_90)) {
                orientation = Configuration.ORIENTATION_PORTRAIT;
            } else if (orientation == Configuration.ORIENTATION_LANDSCAPE
                  &&  (rotation == Surface.ROTATION_180 
                   ||  rotation == Surface.ROTATION_270)){
                orientation = //any constant for reverse landscape orientation;
            } else {
                if (orientation == Configuration.ORIENTATION_PORTRAIT
                        &&  (rotation == Surface.ROTATION_180 
                         ||  rotation == Surface.ROTATION_270)){
                      orientation = //any constant for reverse portrait orientation;
                }
            }
Bharat Sharma
  • 3,926
  • 2
  • 17
  • 29
7

getResources().getConfiguration().orientation is the standard way of knowing current orientation being used. However, if it doesn't fulfill your needs then perhaps you may use Sensors to calculate it in terms of angle. Read this and this

waqaslam
  • 67,549
  • 16
  • 165
  • 178
  • Yes, I am aware of that. I just wanted to know if there was a single method which would return me complete information about the orientation of the screen including the side which it's turned to (not just landscape or portrait), i.e. upside down, or left side or right side. – Zoltán Apr 30 '12 at 09:28
  • Yes, i got your point. So what you can do is to make your own single static method by using these sensors... – waqaslam Apr 30 '12 at 09:38
2

I ended up using Zoltán's answer above, which works great, except when I tried it on a tablet (a Samsung P6210 Galaxy Tab 7.0 Plus). In portrait mode, it returned SCREEN_ORIENTATION_REVERSE_PORTRAIT. So in the else statement (if natural orientation is landscape) I swapped the cases for ROTATION_90 and ROTATION_270, and everything seems to work fine. (I don't have enough reputation to post this as a comment to Zoltán's answer.)

pfalstad
  • 216
  • 1
  • 2
  • Do you know if this happens on other landscape tablets as well? Maybe these two cases should be swapped for all naturally-landscape devices? – Zoltán Jan 18 '14 at 16:02
  • Confirmed, it happens also on a Asus Transformer prime, swapping the cases fixed it. – tru7 Jun 14 '14 at 13:24
0

You could do it in a very simple way: get the screen widhtand height. screen width will be always higher when device is in landscape orientation.

Display display = getWindowManager().getDefaultDisplay();
    int width = display.getWidth(); 
    int height = display.getHeight();
    Toast.makeText(getApplicationContext(), "" + width + "," + height,
            Toast.LENGTH_SHORT).show();
    if (width > height) {
        Toast.makeText(getApplicationContext(), "LandScape",
                Toast.LENGTH_SHORT).show();
    }
Vettiyanakan
  • 7,957
  • 6
  • 37
  • 55
  • 3
    The question is really how to get the detailed orientation, i.e. including which way the device is turned. The method you are suggesting doesn't differentiate between opposite orientations, e.g. portrait and upside down portrait, etc. – Zoltán Sep 15 '14 at 09:04
-1

Does this solve your problem?

public static int getscrOrientation(Activity act)
{
    Display getOrient = act.getWindowManager()
            .getDefaultDisplay();

    int orientation = getOrient.getOrientation();

    // Sometimes you may get undefined orientation Value is 0
    // simple logic solves the problem compare the screen
    // X,Y Co-ordinates and determine the Orientation in such cases
    if (orientation == Configuration.ORIENTATION_UNDEFINED) {

        Configuration config = act.getResources().getConfiguration();
        orientation = config.orientation;

        if (orientation == Configuration.ORIENTATION_UNDEFINED) {
            // if height and widht of screen are equal then
            // it is square orientation
            if (getOrient.getWidth() == getOrient.getHeight()) {
                orientation = Configuration.ORIENTATION_SQUARE;
            } else { // if widht is less than height than it is portrait
                if (getOrient.getWidth() < getOrient.getHeight()) {
                    orientation = Configuration.ORIENTATION_PORTRAIT;
                } else { // if it is not any of the above it will defineitly
                            // be landscape
                    orientation = Configuration.ORIENTATION_LANDSCAPE;
                }
            }
        }
    }
    return orientation; // return value 1 is portrait and 2 is Landscape
                        // Mode
}
Conscious
  • 1,603
  • 3
  • 18
  • 16
  • 1
    Like I said in my question. I need to know which way the screen is turned. Portrait or landscape is insufficient info. E.g. if it's a tall or portrait device, if it's in landscape orientation, I need to know whether it's turned on it's left or right side, etc. – Zoltán Apr 30 '12 at 09:26