2

I'm trying to temporarily lock the orientation of the Android device, where most of the time it changes with the sensor. So what I want to do is figure out what the current orientation (landscape, reverse landscape, portrait, reverse portrait) is, change the orientation to that one orientation, and then later change it back to what it was originally.

I am aware that I can use code such as int orientation = this.getResources().getConfiguration().orientation; this.setRequestedOrientation(orientation); The problem with this is that typically the orientation in question is set as "undefined" or perhaps "user" or "sensor," which doesn't help me. How can I find out which of the four possible sides of the screen is "down"?

I know of getRotation(), as described here: how to detect orientation of android device?

The problem with that is that I can find out the actual rotation (0, 90, 180, 270 degrees) from the device's "natural" orientation... but that doesn't help me if I don't know what the original orientation is.

How can I find out which way the device is turned, so I can temporarily fix the device to that orientation?

UPDATE

No, this is not a duplicate question. I suspect there may be different behavior on different devices, but can't be certain of that. I did more experimentation and research. I had thought for some reason that getConfiguration().orientation returned "unspecified". I was mistaken. It does return Landscape or Portrait.

But here's the problem. It wasn't until Gingerbread (2.3, API 9) that REVERSE landscape and reverse portrait were added.

So if the device is in reverse landscape mode, for example, getConfiguration.orientation would tell me that it's in landscape mode. Then when I set the requested orientation to landscape--bam, the screen flips upside down.

I didn't realize this was more difficult in Froyo, so I will rephrase the question I spelled out before:

In Froyo, how can I detect whether the device is in landscape, reverse landscape, portrait or reverse portrait?

The suggestions listed all work--for Gingerbread or higher.

Community
  • 1
  • 1
Chad Schultz
  • 7,770
  • 6
  • 57
  • 96
  • possible duplicate of [Getting orientation of the device?](http://stackoverflow.com/questions/1926626/getting-orientation-of-the-device) – Manse Dec 05 '11 at 16:57
  • see http://stackoverflow.com/questions/8383000/android-configuration-changed/8383094#8383094 – oriolpons Dec 05 '11 at 16:58

5 Answers5

8

I modified diyism's answer in a different post to work for Froyo. Since Froyo doesn't support reverse_landscape it will appear upside down but will return to the proper orientation after you unlock. In Gingerbread and later it should work without problems.

Not a perfect solution but good enough for my needs.

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);
}
Community
  • 1
  • 1
crobicha
  • 1,674
  • 1
  • 16
  • 21
1

I am not sure if the constant is the issue that was no implemented on that API. Have you tried something like this?

 switch (((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay().getRotation()) {
    case Surface.ROTATION_90: 
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
        break;
    case Surface.ROTATION_180: 
        setRequestedOrientation(9); /* ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT */
        break;          
    case Surface.ROTATION_270: 
        setRequestedOrientation(8); /* ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE */
        break;
    default : 
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
    }
OskrSaSi
  • 330
  • 2
  • 4
0

I found another simple solution on this website: http://sagistech.blogspot.ch/2010/12/finding-android-screen-orientation.html

There are multiple way to get Android screen orientation (landscape/portrait), however some of them are problematic: this.getWindowManager().getDefaultDisplay().getOrientation() Is deprecated

this.getWindowManager().getDefaultDisplay().getRotation() Works only from Android 2.2

I Found this to be the best resource until now, since it's exists since API 1 & it's not deprecated, yet: this.getResources().getConfiguration().orientation

Compare it with:

  • Configuration.ORIENTATION_LANDSCAPE
  • Configuration.ORIENTATION_SQUARE
  • Configuration.ORIENTATION_PORTRAIT

For me it worked.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92
0

I'm not exactly sure what your problem is. Are you trying to determine if a device is currently oriented in landscape or portrait mode? If so you can get that information quickly with:

Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point size = new Point();
Display.getSize(size);

boolean isLandscape = size.x > size.y;

If you couple that with Display.getOrientation() you should have access to all the information you need.

slayton
  • 20,123
  • 10
  • 60
  • 89
0

I am having similar problems in Froyo

In the activity section of the manifest file I declare:

<activity ...
    android:configChanges="keyboardHidden|orientation">
</activity>

The main activity has the code to get the information about rotation either when the application is resumed or when a configuration change event is received:

public void onResume() {
    super.onResume();
    showRotation();
    ...
}

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    showRotation();
    ...
}

public void showRotation() {
    // int rotationType = getWindowManager().getDefaultDisplay().getOrientation(); // Deprecated
    int rotationType = getWindowManager().getDefaultDisplay().getRotation(); // API 8+ (Android 2.2.x or higher)
    Log.d(MYTAG, "rotation type: " + rotationType);
}

The problem:

  • If the device is rotated from landscape to portrait and then to reverse landscape, everything works as expected.
  • If the device is rotated from landscape to reverse landscape, the event of configuration change is not fired at all. The program still considers the device being in landscape mode.

So, what is the solution? should the program be continuously asking to get the current orientation?

jap1968
  • 7,747
  • 1
  • 30
  • 37