353

I have one of my activities which I would like to prevent from rotating because I'm starting an AsyncTask, and screen rotation makes it restart.

Is there a way to tell this activity "DO NOT ROTATE the screen even if the user is shaking his phone like mad"?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sephy
  • 50,022
  • 30
  • 123
  • 131
  • 3
    http://stackoverflow.com/questions/1512045/how-to-disable-orientation-change-in-android – Dan Lew Apr 28 '10 at 15:30
  • http://clamernotes.blogspot.com/2011/04/disable-screen-rotation-at-runtime-on.html – lexis Apr 04 '11 at 20:08
  • 11
    You can deal with screen orientation change *and* AsyncTasks. Preventing screen orientation changes is just a lazy workaround. And it's not hard to keep an AsyncTask alive across orientation changes :) – Romain Guy Apr 28 '10 at 18:17
  • 73
    It would be a lot more helpful to actually provide a solution or some code, Romain, rather than just asserting "a solution exists and it is not hard". – Peter vdL Mar 28 '13 at 00:20
  • 7
    you can use `setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);` – mcy Mar 29 '16 at 12:40

16 Answers16

528

Add

android:screenOrientation="portrait" 

or

 android:screenOrientation="landscape" 

to the <activity> element/s in the manifest and you're done.

Tupio
  • 432
  • 7
  • 19
lbedogni
  • 7,917
  • 8
  • 30
  • 51
  • 104
    Please note this is just hiding a bug in your app, making it less likely for users to trip over it. But they still will. Any configuration change can cause your activity to restart. You really need to write your activity correctly to deal with the async task as it restarts. – hackbod Apr 28 '10 at 17:06
  • 1
    This did not work for me in one case. I had the screen set to landscape before opening the app. When I opened the app, the screen rotated to portrait and caused a second call to asynctask. – user522559 Aug 02 '11 at 14:04
  • 2
    You need to set things to "open in portrait mode" *AND* "always stay in portrait mode". Doing only 1 is pointless. – Carol Jun 07 '12 at 16:24
  • @ibedogni - My God thank you!!! i have been wracking my brains over screen rotation problems when using `MediaRecorder` because screen rotation causes the required `SurfaceView` to be lost which breaks the recording task. Forcing this screen orientation solves my problem...this after after trying SO MANY other hacks ... i can't believe i didn't find this solution till now haha. Cheers, truly. – wired00 Dec 04 '12 at 07:08
  • 1
    @hackbod regardless, this is the number #1 google hit for "android app prevent screen rotation," my need has nothing to do with async tasks – chiliNUT Jan 26 '15 at 04:02
  • 7
    @hackbod How do we then write our activity correctly to deal with this problem? – user41805 Oct 02 '15 at 14:58
  • As @Sara points out you need to add this to the tag for each activity you want to lock rather than to the tag. – meesern Dec 15 '15 at 10:03
  • This is not the correct answer. What if one wants her activity not to rotate in any situation, regardless of being initially opened in each portrait/landscape modes. – Amin Mar 10 '16 at 10:19
  • Landscape should only be used in games, and video player. I have no idea why people support both modes. – slaviboy Mar 09 '21 at 09:30
  • This was my solution for a long time until I started using "loading screens" that would have a transparent background and spinning icon. If your screen orientation is not the original "landscape" or "portrait," meaning the screen is flipped, this code will flip your screen over when the loading starts. The user will have to flip their device or turn it over again to re-orient the screen after. – FoxDonut Jul 08 '21 at 22:32
  • Note : When you turn on auto rate from the top menu, your app will still rotate – Sambhav Khandelwal Jan 13 '22 at 16:04
134

You can follow the logic below to prevent auto rotate screen while your AsyncTask is running:

  1. Store your current screen orientation inside your activity using getRequestedOrientation().
  2. Disable auto screen orientation using setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR).
  3. Run/execute your AsyncTask.
  4. At the end of your AsyncTask restore your previous orientation status using setRequestedOrientation(oldOrientation).

Please note that there are several ways to access Activity (which runs on UI thread) properties inside an AsyncTask. You can implement your AsyncTask as an inner class or you can use message Handler that poke your Activiy class.

Fattie
  • 27,874
  • 70
  • 431
  • 719
Emre Yazici
  • 10,136
  • 6
  • 48
  • 55
  • 4
    great idea :) you don't have store your current screen orientation you can use ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED – fligant Apr 22 '14 at 14:07
  • This seems incredible, @emre, thanks! It seems **"Too good to be true!"** Notice the huge amount of discussion about the issue: http://stackoverflow.com/q/3821423/294884 ... android experts, is there any downside here?! Thanks again .. so much. – Fattie May 19 '14 at 14:54
  • 4
    Crap!! This **DOES NOT WORK** if the device happens to BEGIN IN LANDSCAPE MODE. What the hell! Sux :O – Fattie May 19 '14 at 15:53
  • @Emre, This code doesn't work in certain cases. E.g. if the user changed his orientation between the start of your AsyncTask and the end of it. You would have saved and restored the wrong orientation then. – Pacerier Nov 20 '14 at 04:24
35

The easiest way I found to do this was to put

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

within onCreate, just after

setContentView(R.layout.activity_main);

so...

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Richard
  • 56,349
  • 34
  • 180
  • 251
Paul Alexander
  • 2,686
  • 4
  • 33
  • 69
28

In your Manifest file, for each Activity that you want to lock the screen rotation add: if you want to lock it in horizontal mode:

<activity
        ...
        ...
        android:screenOrientation="landscape">

or if you want to lock it in vertical mode:

<activity
            ...
            ...
            android:screenOrientation="portrait">
Sara
  • 1,844
  • 22
  • 18
8

Rather than going into the AndroidManifest, you could just do this:

screenOrientation = getResources().getConfiguration().orientation;
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
... AsyncTask

screenOrientation = getResources().getConfiguration().orientation;


@Override
protected void onPostExecute(String things) {
    context.setRequestedOrientation(PlayListFragment.screenOrientation);
    or 
    context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
}

The only drawback here is that it requires API level 18 or higher. So basically this is the tip of the spear.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • This part is disabling home and recent apps button and even after releasing lock with SCREEN_ORIENTATION_FULL_SENSOR, its in disabled state. In Android N. – kAmol Jun 15 '16 at 04:25
6

Activity.java

@Override     
 public void onConfigurationChanged(Configuration newConfig) {       
        try {     
            super.onConfigurationChanged(newConfig);      
            if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {      
                // land      
            } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {      
               // port       
            }    
        } catch (Exception ex) {       
     }   

AndroidManifest.xml

 <application android:icon="@drawable/icon" android:label="@string/app_name">
  <activity android:name="QRCodeActivity" android:label="@string/app_name"
  android:screenOrientation="landscape" >
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>

 </application>
Daniel Kutik
  • 6,997
  • 2
  • 27
  • 34
Li Che
  • 727
  • 10
  • 24
4

User "portrait" in your AndroidManifest.xml file might seem like a good solution. But it forces certain devices (that work best in landscape) to go into portrait, not getting the proper orientation. On the latest Android version, you will get wearing an error. So my suggestion it's better to use "nosensor".

<activity
        ...
        ...
        android:screenOrientation="nosensor">
Md Imran Choudhury
  • 9,343
  • 4
  • 62
  • 60
3

Add the following to your AndroidManifest.xml

[ app > src > main > AndroidManifest.xml ]

<activity android:name=".MainActivity"
          android:configChanges="orientation"
          android:screenOrientation="portrait"/>

Example:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxx.zzzzzz.yyyyy">

   <uses-permission android:name="A-PERMISSION" />

   <application>
      <activity android:name=".MainActivity"
                android:screenOrientation="portrait"
                android:configChanges="orientation">
      </activity>
   </application>

</manifest>
andrewoodleyjr
  • 2,971
  • 2
  • 21
  • 21
2

The following attribute on the ACTIVITY in AndroidManifest.xml is all you need:

android:configChanges="orientation"

So, the full activity node would be:

<activity android:name="Activity1"
          android:icon="@drawable/icon"
          android:label="App Name"
          android:excludeFromRecents="true"
          android:configChanges="orientation">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ben
  • 861
  • 8
  • 4
2

Add:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
        ...
        ...
        ...
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anas
  • 75
  • 2
  • 9
1

Prevent Screen Rotation just add this following line in your Manifests.

<activity
        android:name=".YourActivity"
        android:screenOrientation="portrait" />

This works for me.

DEVSHK
  • 833
  • 11
  • 10
1

android:screenOrientation="portrait" on application tag <application

and

<activity ... ... android:screenOrientation="locked">

  • It's not really clear what to do with what is written, where to write it. Also, there are similar and more clear answers in the list, so not really needed answer. – Alex Shtromberg Sep 23 '21 at 08:36
0

If you are using Android Developer Tools (ADT) and Eclipse you can go to your AndroidManifest.xml --> Application tab --> go down and select your activity. Finally, select your preferred orientation. You can select one of the many options.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Husam
  • 131
  • 1
  • 5
0

You have to add the following code in the manifest.xml file. The activity for which it should not rotate, in that activity add this element

android:screenOrientation="portrait"

Then it will not rotate.

Richard
  • 56,349
  • 34
  • 180
  • 251
Simon Chius
  • 476
  • 5
  • 18
0

You can try This way

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itclanbd.spaceusers">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".Login_Activity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Muhaiminur Rahman
  • 3,066
  • 20
  • 27
0

Use AsyncTaskLoader to keep your data safe even if the activity changes, instead of using AsyncTask that is a better way to build apps than preventing screen rotation.

Argus Waikhom
  • 186
  • 6
  • 14