293

I have an application that I just would like to use in portrait mode, so I have defined android:screenOrientation="portrait" in the manifest XML. This works OK for the HTC Magic phone (and prevents orientation changes on other phones as well).

But I have a problem with the HTC G1 phone as I open the hardware QWERTY keyboard (not the virtual keyboard). My activity stays in portrait mode, but it seems to get restarted and loses all its states. This does not happen with the HTC Hero version.

My application is quite big, so I don't want it to restart and lose all its states when the keyboard is opened. How can I prevent that?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Vidar Vestnes
  • 41,116
  • 28
  • 81
  • 97
  • 2
    Try looking here also: http://stackoverflow.com/questions/2366706/how-to-lock-orientation-during-runtime/10488012#10488012 – Andy Weinstein May 07 '12 at 19:56
  • possible duplicate of [How to make application completely ignore screen orientation change in Android?](http://stackoverflow.com/questions/1410504/how-to-make-application-completely-ignore-screen-orientation-change-in-android) – Peter O. Feb 15 '13 at 18:19

13 Answers13

322

Update April 2013: Don't do this. It wasn't a good idea in 2009 when I first answered the question and it really isn't a good idea now. See this answer by hackbod for reasons:

Avoid reloading activity with asynctask on orientation change in android

Add android:configChanges="keyboardHidden|orientation" to your AndroidManifest.xml. This tells the system what configuration changes you are going to handle yourself - in this case by doing nothing.

<activity android:name="MainActivity"
     android:screenOrientation="portrait"
     android:configChanges="keyboardHidden|orientation">

See Developer reference configChanges for more details.

However, your application can be interrupted at any time, e.g. by a phone call, so you really should add code to save the state of your application when it is paused.

Update: As of Android 3.2, you also need to add "screenSize":

<activity
    android:name="MainActivity"
    android:screenOrientation="portrait"
    android:configChanges="keyboardHidden|orientation|screenSize">

From Developer guide Handling the Configuration Change Yourself

Caution: Beginning with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion and targetSdkVersion attributes), you must include the "screenSize" value in addition to the "orientation" value. That is, you must declare android:configChanges="orientation|screenSize". However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).

Prags
  • 2,277
  • 2
  • 18
  • 32
Intrications
  • 16,182
  • 9
  • 47
  • 50
  • 37
    Just to add to this and be really explicit, Android can mercilessly kill your application at any time, regardless of orientation changes, so you should use onPause() and onSaveInstanceState() to save state, no matter what. – Eric Mill Oct 03 '09 at 03:11
  • The 3.2 update was very useful and was what was blocking me. I had no idea why my onConfigurationChanged handler wasn't firing and this was it. Thanks! – sweetlilmre Apr 16 '12 at 07:31
  • the third param - screenSize cannot be found in 2.3.x , should i change to screenLayout? – deadfish Apr 23 '12 at 10:45
  • 2
    @Lumma No, "screenSize" is only needed for Android 3.2 and newer. What level API are you targeting? I think you only need to add it if you are targeting level 13 or above. I will update the answer to clarify. – Intrications Apr 23 '12 at 14:19
  • 1
    Just in case it is helpful to other people, I have found you both <...android:configchanges> to override changes and <...android:screenorientation> to define the default. – Sogger Feb 15 '13 at 22:38
  • What if the user choose on the settings of the OS to lock the orientation? this seems to ignore this setting, and rotate the screen even in this case... – android developer Jun 02 '14 at 06:48
  • I DO save my screen state but the reason I block orientation changes is something as trivial as the lack of background images that are appropriate for the landscape orientation. So it is useful for me to prevent that orientation being displayed! – Brian Reinhold Mar 04 '18 at 11:04
97

You need to modify AndroidManifest.xml as Intrications (previously Ashton) mentioned and make sure the activity handles the onConfigurationChanged event as you want it handled. This is how it should look:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Community
  • 1
  • 1
ubershmekel
  • 9,570
  • 6
  • 62
  • 78
  • As noted by Dmitry Zaitsev, it is better to put the `setRequestedOrientation()` in `onCreate()`. – Timmmm Sep 11 '12 at 09:25
  • 3
    Does not `onConfigurationChanged()` get called before `onCreate()` if so setting orientation before setting contentViews in oncreate is **better** approach, setting configuration where it belongs is also **cleaner** so this answer still stands good. – Samuel Sep 02 '13 at 02:19
40

I've always found you need both

android:screenOrientation="nosensor" android:configChanges="keyboardHidden|orientation"
m00sey
  • 679
  • 6
  • 6
22

As said, set android:configChanges of your Activity (in manifest file) to keyboardHidden|orientation and then:

1) Override onConfigurationChanged()

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //here you can handle orientation change
}

2) Add this line to your activity's onCreate()

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

It's better than add same line to onConfigurationChanged, because your app will turn to portrait mode and then back to landscape (it will happen only one time, but it's annoying).

Also you can set android:screenOrientation="nosensor" for your activity (in manifest). But using this way you're a not able to handle orientation changes at all.

Dmitry Zaytsev
  • 22,662
  • 13
  • 89
  • 139
  • What should I do if I want to avoid re-creation of the activity upon rotation, yet I wish to allow the user to lock the orientation via the OS's settings ? – android developer Jun 02 '14 at 06:57
  • @androiddeveloper that a separate question, which already has an answer: http://stackoverflow.com/a/14771495/926907 – Dmitry Zaytsev Jun 02 '14 at 07:06
  • Your link is about changing the content by myself when the configuration changes, yet I wish to avoid the rotation of the activity (so that it will stay exactly the way it looks like) in case the user has chosen to lock the orientation via the OS's settings (available on some devices via the quick-settings, in the notification drawer). – android developer Jun 02 '14 at 07:40
  • @androiddeveloper ah, I think I understood. Then take a look at this link: http://developer.android.com/reference/android/R.attr.html#screenOrientation According to the docs, default orientation should already take user preference into account. If that's not the case, then I suspect that it's a OS specific behavior. I would be glad to hear about your results - now I'm also interested in it :) – Dmitry Zaytsev Jun 02 '14 at 08:57
  • I know the default will handle the user's preferences, but it also re-creates the activity when you rotate the screen, which is something I don't want to have. – android developer Jun 02 '14 at 17:30
  • Anyway, I've found the correct value: android:screenOrientation="user" . I also wrote about it here, thinking I've tried all of the values (probably missed it) : http://stackoverflow.com/questions/24000361/how-to-avoid-activity-re-creation-when-being-rotated-while-also-respecting-orie/24004340#24004340 – android developer Jun 02 '14 at 22:34
20

Use this..

    android:screenOrientation="portrait"
Muhammad Aamir Ali
  • 18,753
  • 9
  • 62
  • 54
13

In OnCreate method of your activity use this code:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Now your orientation will be set to portrait and will never change.

Numenor
  • 1,628
  • 12
  • 20
  • 4
    With that you don't prevent restarting the activity every time the orientation configuration changes. – AxeEffect Mar 08 '13 at 20:08
  • Also, this doesn't work if you enter the Activity from a previous Activity in landscape orientation. – w3bshark Feb 15 '18 at 03:32
10

In the AndroidManifest.xml file, for each activity you want to lock add the last screenOrientation line:

android:label="@string/app_name"
android:name=".Login"
android:screenOrientation="portrait" >

Or android:screenOrientation="landscape".

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Gil Allen
  • 1,065
  • 13
  • 22
8

In your androidmanifest.xml file:

   <activity android:name="MainActivity" android:configChanges="keyboardHidden|orientation">

or

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Jorgesys
  • 114,263
  • 22
  • 306
  • 247
7

To lock the screen by code you have to use the actual rotation of the screen (0, 90, 180, 270) and you have to know the natural position of it, in a smartphone the natural position will be portrait and in a tablet, it will be landscape.

Here's the code (lock and unlock methods), it has been tested in some devices (smartphones and tablets) and it works great.

public static void lockScreenOrientation(Activity activity)
{   
    WindowManager windowManager =  (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);   
    Configuration configuration = activity.getResources().getConfiguration();   
    int rotation = windowManager.getDefaultDisplay().getRotation(); 

    // Search for the natural position of the device    
    if(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&  
       (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) ||  
       configuration.orientation == Configuration.ORIENTATION_PORTRAIT &&   
       (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270))   
    {   
        // Natural position is Landscape    
        switch (rotation)   
        {   
            case Surface.ROTATION_0:    
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);    
                break;      
            case Surface.ROTATION_90:   
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
            break;      
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
                break;
        }
    }
    else
    {
        // Natural position is Portrait
        switch (rotation) 
        {
            case Surface.ROTATION_0: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
            break;   
            case Surface.ROTATION_90: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
            break;   
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;
        }
    }
}

public static void unlockScreenOrientation(Activity activity)
{
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
PoOk
  • 615
  • 7
  • 17
  • what paramater should be passed as activity? – WISHY Jan 16 '14 at 04:52
  • The Activity that calls the method to lock/unlock its orientation. That's a public static utility method to be called from differents Activities. – PoOk Jan 16 '14 at 09:08
  • 1
    Works great, but, seriously, Android, why do we have to do all that s*** just for lock screen orientation ?!!! – Cocorico Jul 03 '14 at 13:56
  • yes. This one locks the orientation as we do in the manifest. This will prevent the onConfigurationChanged from being invoked anymore. Is there a method that locks UI to Landscape and still invokes the onConfigurationChanged. Just like the camera app in android does – Ajith Memana Nov 11 '14 at 13:13
  • There is a SCREEN_ORIENTATION_LOCKED flag on SDK 18+ which seems to work but you'd still want to use the code above to support every device – DominicM Feb 22 '15 at 14:08
2

In Visual Studio Xamarin:

  1. Add:

using Android.Content.PM; to you activity namespace list.

  1. Add:

[Activity(ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)]

as an attribute to you class, like that:

[Activity(ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : Activity
{...}
Roy Doron
  • 1,099
  • 9
  • 22
1

Add

android:configChanges="keyboardHidden|orientation|screenSize" 

to your manifest.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
saurabh
  • 199
  • 1
  • 3
  • 16
0

Please note, none of the methods seems to work now!

In Android Studio 1 one simple way is to add android:screenOrientation="nosensor".

This effectively locks the screen orientation.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
kephalian
  • 21
  • 3
0

You can simply use like below in the application class if you want only PORTRAIT mode for all activities in your app.

class YourApplicationName : Application() {

override fun onCreate() {
    super.onCreate()

    registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {

        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
            activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }

        override fun onActivityStarted(activity: Activity) {

        }

        override fun onActivityResumed(activity: Activity) {

        }

        override fun onActivityPaused(activity: Activity) {

        }

        override fun onActivityStopped(activity: Activity) {

        }

        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

        }

        override fun onActivityDestroyed(activity: Activity) {

        }

    })

}

}

Elaa_sekar
  • 31
  • 6