<br />

Your app works great on phones in portrait orientation, so you've restricted the
app to portrait only. But you see an opportunity to do more on large screens in
landscape orientation.

How can you have it both ways---restrict the app to portrait orientation on
small screens, but enable landscape on large?

This guide is a temporary measure until you can improve your app to
provide full support for all device configurations.

## Manage app orientation

To enable landscape orientation on large screens, set your app manifest to
handle orientation changes by default. At runtime, determine the app window
size. If the app window is small, restrict the app's orientation by overriding
the manifest orientation setting.

### 1. Specify orientation setting in the app manifest

You can either avoid declaring the [`screenOrientation`](https://developer.android.com/guide/topics/manifest/activity-element#screen) element of the app
manifest (in which case orientation defaults to `unspecified`) or set screen
orientation to `fullUser`. If the user has not locked sensor-based rotation,
your app will support all device orientations.  

    <activity
        android:name=".MyActivity"
        android:screenOrientation="fullUser">

| **Note:** `screenOrientation` is ignored (or is equivalent to `unspecified`) when apps run in multi‑window mode. So, if you restrict your app to one orientation, the app might not work properly in multi‑window mode.

The difference between `unspecified` and `fullUser` is subtle but important. If
you don't declare a `screenOrientation` value, the system chooses the
orientation, and the policy the system uses to define the orientation might
differ from device to device. On the other hand, specifying `fullUser` matches
more closely the behavior the user defined for the device: if the user has
locked sensor-based rotation, the app follows the user preference; otherwise,
the system allows any of the four possible screen orientations (portrait,
landscape, reverse portrait, or reverse landscape). See [`screenOrientation`](https://developer.android.com/guide/topics/manifest/activity-element#screen).

### 2. Determine screen size

With the manifest set to support all user‑permitted orientations, you can
specify app orientation programmatically based on screen size.

Add the [Jetpack WindowManager](https://developer.android.com/jetpack/androidx/releases/window) libraries to the module's `build.gradle` or
`build.gradle.kts` file:  

### Kotlin

```kotlin
implementation("androidx.window:window:<var translate="no">version</var>")
implementation("androidx.window:window-core:<var translate="no">version</var>")
```

### Groovy

```groovy
implementation 'androidx.window:window:<var translate="no">version</var>'
implementation 'androidx.window:window-core:<var translate="no">version</var>'
```

Use the Jetpack WindowManager
[`WindowMetricsCalculator#computeMaximumWindowMetrics()`](https://developer.android.com/reference/kotlin/androidx/window/layout/WindowMetricsCalculator#computeMaximumWindowMetrics(android.app.Activity)) method to obtain the
device screen size as a [`WindowMetrics`](https://developer.android.com/reference/kotlin/androidx/window/layout/WindowMetrics) object. The window metrics can be
compared to window size classes to decide when to restrict orientation.

[Windows size classes](https://developer.android.com/develop/ui/compose/layouts/adaptive/use-window-size-classes) provide the breakpoints between small and large
screens.

Use the [`WindowWidthSizeClass#COMPACT`](https://developer.android.com/reference/kotlin/androidx/window/core/layout/WindowWidthSizeClass#COMPACT()) and
[`WindowHeightSizeClass#COMPACT`](https://developer.android.com/reference/kotlin/androidx/window/core/layout/WindowHeightSizeClass#COMPACT()) breakpoints to determine the screen size:  

### Kotlin

```kotlin
/** Determines whether the device has a compact screen. **/
fun compactScreen() : Boolean {
    val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
    val width = metrics.bounds.width()
    val height = metrics.bounds.height()
    val density = resources.displayMetrics.density
    val windowSizeClass = WindowSizeClass.compute(width/density, height/density)

    return windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT ||
        windowSizeClass.windowHeightSizeClass == WindowHeightSizeClass.COMPACT
}
```

### Java

```java
/** Determines whether the device has a compact screen. **/
private boolean compactScreen() {
    WindowMetrics metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this);
    int width = metrics.getBounds().width();
    int height = metrics.getBounds().height();
    float density = getResources().getDisplayMetrics().density;
    WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density);
    return windowSizeClass.getWindowWidthSizeClass() == WindowWidthSizeClass.COMPACT ||
                windowSizeClass.getWindowHeightSizeClass() == WindowHeightSizeClass.COMPACT;
}
```

**Note:**
- The examples are implemented as methods of an activity; and so, the activity is dereferenced as `this` in the argument of `computeMaximumWindowMetrics()`.
- The `computeMaximumWindowMetrics()` method is used instead of [`computeCurrentWindowMetrics()`](https://developer.android.com/reference/kotlin/androidx/window/layout/WindowMetricsCalculator) because the app can be launched in multi‑window mode, which ignores the screen orientation setting. There's no point in determining the app window size and overriding the orientation setting unless the app window is the entire device screen.

See [WindowManager](https://developer.android.com/jetpack/androidx/releases/window#declaring_dependencies) for instructions about declaring dependencies to make the
`computeMaximumWindowMetrics()` method available in your app.

### 3. Override app manifest setting

When you've determined that the device has compact screen size, you can call
[`Activity#setRequestedOrientation()`](https://developer.android.com/reference/kotlin/android/app/Activity#setrequestedorientation) to override the manifest's
`screenOrientation` setting:  

### Kotlin

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    requestedOrientation = if (compactScreen())
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else
        ActivityInfo.SCREEN_ORIENTATION_FULL_USER
    ...
    // Replace with a known container that you can safely add a
    // view to where the view won't affect the layout and the view
    // won't be replaced.
    val container: ViewGroup = binding.container

    // Add a utility view to the container to hook into
    // View.onConfigurationChanged. This is required for all
    // activities, even those that don't handle configuration
    // changes. You can't use Activity.onConfigurationChanged,
    // since there are situations where that won't be called when
    // the configuration changes. View.onConfigurationChanged is
    // called in those scenarios.
    container.addView(object : View(this) {
        override fun onConfigurationChanged(newConfig: Configuration?) {
            super.onConfigurationChanged(newConfig)
            requestedOrientation = if (compactScreen())
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else
                ActivityInfo.SCREEN_ORIENTATION_FULL_USER
        }
    })
}
```

### Java

```java
@Override
protected void onCreate(Bundle savedInstance) {
    super.onCreate(savedInstanceState);
    if (compactScreen()) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
    }
    ...
    // Replace with a known container that you can safely add a
    // view to where the view won't affect the layout and the view
    // won't be replaced.
    ViewGroup container = binding.container;

    // Add a utility view to the container to hook into
    // View.onConfigurationChanged. This is required for all
    // activities, even those that don't handle configuration
    // changes. You can't use Activity.onConfigurationChanged,
    // since there are situations where that won't be called when
    // the configuration changes. View.onConfigurationChanged is
    // called in those scenarios.
    container.addView(new View(this) {
        @Override
        protected void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            if (compactScreen()) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
            }
        }
    });
}
```
| **Note:** The manifest setting is not changed, just overridden.

By adding the logic to the `onCreate()` and `View.onConfigurationChanged()`
methods, you're able to obtain the maximum window metrics and override the
orientation setting whenever the activity is resized or moved between displays,
such as after a device rotation or when a foldable device is folded or unfolded.
For more information about when configuration changes occur and when they cause
activity recreation, refer to [Handle configuration changes](https://developer.android.com/guide/topics/resources/runtime-changes).
| **Note:** If you did not specify `android:screenOrientation` in the manifest, replace the occurrences of `ActivityInfo.SCREEN_ORIENTATION_FULL_USER` with `ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED` to match the defaults.

## Key points

- [`screenOrientation`](https://developer.android.com/guide/topics/manifest/activity-element#screen): App manifest setting that enables you to specify how your app responds to device orientation changes
- [Jetpack WindowManager](https://developer.android.com/jetpack/androidx/releases/window): Set of libraries that enable you to determine the size and aspect ratio of the app window; backward compatible to API level 14
- [`Activity#setRequestedOrientation()`](https://developer.android.com/reference/kotlin/android/app/Activity#setrequestedorientation): Method with which you can change the app orientation at runtime

## Results

Your app should now remain in portrait orientation on small screens regardless
of device rotation. On large screens, the app should support landscape and
portrait orientations.

## Collections that contain this guide

This guide is part of these curated Quick Guide collections that cover broader
Android development goals:  
![](https://developer.android.com/static/images/quick-guides/collection-illustration.png)  
![](https://developer.android.com/static/images/picto-icons/collection.svg)  

### Optimize for large screens

Enable your app to support an optimized user experience on tablets, foldables, and ChromeOS devices.  
[Quick guide collection](https://developer.android.com/quick-guides/collections/optimize-for-large-screens)
![](https://developer.android.com/static/images/picto-icons/help.svg)  

## Have questions or feedback

Go to our frequently asked questions page and learn about quick guides or reach out and let us know your thoughts.  
[Go to FAQ](https://developer.android.com/quick-guides/faq) [Leave feedback](https://issuetracker.google.com/issues/new?component=1573691&template=1993320)