How to disable Screen Auto-Rotation on Android

By default, most Android apps re-orient themselves when the user rotates the screen on their device.

Many app developers don’t need to think about this at all for their apps, but for the ones who do, you need to understand what Android is doing behind the scenes. Not only is it important for implementing screen rotation yourself, but also for avoiding mysterious bugs and crashes relating to screen rotation.

What Android Normally Does

Android attempts to provide a base means of implementing auto-rotation, so that every app does not have to implement it.

Normally, when the user rotates the device, Android “transparently” handles this situation by destroying the current Activity, and instantiating a new instance of the same activity. For most apps, this works just fine, but there can be some side effects.

By default, the new activity won’t have the runtime state of the old. Your activity must override onSaveInstanceState() to save runtime state from the old instance into a Bundle object. Android passes this bundle into the onCreate() method of the new activity instance, where you can use it to re-populate your member variables and onscreen controls.

Handling Orientation Changes Yourself

If you don’t like Android’s default method for handling screen rotation, you can take matters into your own hands. Set the android:ConfigChanges attribute for your activity in the AndroidManifest.xml file:

<activity android:name="com.myapp.MyActivity"
          android:label="@string/app_name"
          android:configChanges="orientation"
          >
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Here, the orientation flag in android:configChanges tells the system that the Activity wishes to handle rotation on its own. Android will invoke the onConfigurationChanged() method of your Activity instead, which allow you to handle the screen rotation yourself. It will no longer kill and restart your Activity.

Here’s an example onConfigurationChanged() which replaces the main content view for the currently running Activity:

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

	// Set a new layout - framework will automatically choose portrait or landscape as needed
	setContentView( R.layout.my_activity_layout );

	// Reconnect all listeners for controls in the layout
	a.findViewById( R.id.exit_button ).setOnClickListener( mListener );
}

Odds are, your onConfigurationChanged() method will need to do almost exactly the same kind of work as your Activity’s onCreate() method, so it’s probably a good idea to DRY out your code by factoring out your layout setup into a separate helper method that you invoke from both onCreate() and onConfigurationChanged().

Forcing Orientation at Build Time

If you wish to force an Activity to always be a particular orientation, you can simply specify its orientation in its entry in AndroidManifest.xml:

<activity android:name="com.myapp.MyActivity"
          android:label="@string/app_name"
          android:screenOrientation="landscape"
          android:configChanges="orientation"
          >
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

The android:screenOrientation attribute forces this activity to be in landscape mode always.

If you use android:screenOrientation to hammer the orientation to portrait or landscape, I highly recommend you combine it with the android:configChanges="orientation" flag to ensure that Android will not kill/restart your Activity on rotation. I have seen some obscure bugs in my app caused by an activity being restarted on rotation, even though android:screenOrientation was set.

When you combine the two flags, you can likely leave your implementation of onConfigurationChanged() blank, as your Activity has nothing to do on screen rotations. (It’s worth noting that onConfigurationChanged() is a more general mechanism that notifies the activity of several other device configuration changes, such as opening/closing a sliding keyboard, and Android will still invoke this callback for the other changes. So obviously your code may vary).

Finally, the android:screenOrientation attribute has some other nifty flags that do nifty things. For instance, you can have the orientation match the orientation of the previous Activity on the activity stack. This is useful if you want to force a particular orientation, but want to do so in the context of other Activities in your app flow.

Forcing Orientation at Run Time

You might have a need to dynamically lock the orientation – that is, choose between landscape or portrait at runtime, rather than build time. You can use the method Activity#setRequestedOrientation() for this purpose.

Here’s a code example for a method on an Activity subclass, that hammers the activity orientation to portrait at runtime:

protected void setOrientation() {
	int current = getRequestedOrientation();
	// only switch the orientation if not in portrait
	if ( current != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ) {
		setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT );
	}
}

If you invoke setRequestedOrientation(), Android assumes you have opted out of screen orientation updates altogether for this activity, and it will no longer invoke onConfigurationChanged() to notify your Activity of screen rotation changes.

This entry was posted in Android. Bookmark the permalink. Both comments and trackbacks are currently closed.

One Comment

  1. Tuan Viet Le
    Posted May 19, 2012 at 3:28 pm | Permalink

    Your explain are very detail.
    Thanks so much.