What changed in Android 16, and why this matters
Starting with API level 36, Android applies a new rule on screens where the smallest
width is at least 600dp. It ignores your activity's
android:screenOrientation, android:resizeableActivity,
android:minAspectRatio, and android:maxAspectRatio. The
system treats the activity as fully resizable regardless of what you declared. The
threshold roughly corresponds to "tablet, foldable unfolded, or Chromebook." Anything
bigger than a typical phone. On a regular phone (sw < 600dp), nothing
changes. Your manifest still works the way it did in API 35.
This wasn't done to inconvenience developers. The reasoning, looking at the rollout posts from the Android team, is that the Play Store has been pushing app quality on large screens for several years, and the long tail of apps that lock to portrait or to a fixed aspect ratio looks genuinely terrible on a Galaxy Z Fold or a Pixel Tablet. A portrait-locked shopping app on a foldable in book mode wastes most of the screen. Google's bet is that forcing resizability will produce better-looking apps faster than letting developers opt in voluntarily, which has been the failed strategy since the original Honeycomb tablet push fifteen years ago.
There's an escape hatch. If you really need your orientation lock or aspect-ratio
constraint respected on a large screen, you can add the
PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY property to your
<application> element with android:value="true". That
opts your app out of the forced-resizability behavior. There's a similar property for
user-controlled aspect ratio overrides
(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE) that lets users force
your app into a different aspect ratio from the system UI. You can opt out of that
too.
Both properties work today, but Google has been explicit that they're temporary. The official documentation calls them out as compatibility measures for apps that haven't migrated yet, and at least one Google I/O talk has mentioned they'll be removed in a future release without a fixed date. Use them if you need to, but plan to actually support resizable mode within the next major release cycle.
What "supporting resizable mode" actually means
It's less work than it sounds. The main thing is that your activity's layouts have to
handle onConfigurationChanged properly, or alternatively rely on
Android's default behavior of destroying and recreating the activity when the
configuration changes. The recreation path is simpler. Most apps already handle it
correctly because rotation does the same thing. It's slower and loses scroll
position and other transient state unless you've set up your view models well. If
you're on Compose, the recomposition flow handles most of this automatically. You
mostly need to make sure your layouts use the window-size-class APIs and adapt the
layout for the available space.
Games are the awkward case. A game that runs at fixed 60fps with a 16:9 render
target doesn't want to be "resizable" in the sense of "the user can pinch the window
into a weird letterbox." For games, the right answer is usually to keep the
orientation lock and aspect ratio, set resizeableActivity="false", and
add the opt-out property. That means the game will get letterboxed on a foldable
instead of squashed, which is the lesser evil. Don't try to make a fixed-aspect-ratio
game look good resized. You'll lose either way.
The per-device behavior matrix
The tool above shows behavior per device class because the rules interact in non-obvious ways. Phone is straightforward: whatever you declare wins. Tablet and foldable-unfolded depend on your target SDK. At API 35 and below, your orientation lock works. At API 36+, it's ignored unless you've added the opt-out property. Chromebook is its own thing. Chrome OS has always treated Android apps as resizable windows by default, and the API 36 rule effectively codifies what was already happening there. Android TV and Wear OS have completely different orientation models. TV is always landscape and apps inherit that. Wear is always square or round, and most of the orientation manifest attributes are inapplicable.
What this tool doesn't try to do
It generates the manifest snippet. It doesn't generate the layout-XML changes you'd need to actually support resizable mode well. That's a much bigger conversation involving window size classes, navigation patterns (rail vs. drawer), and content density. It also doesn't validate your whole manifest. If you've got a screen-size declaration somewhere else that conflicts with what's generated here, the tool won't catch it. Treat the output as a starting point for the relevant fragment, not a complete drop-in.
One more thing worth mentioning. The properties added by this tool go in
<application>, not in <activity>. If you've
seen examples where the property is on the activity, those are wrong. Android
ignores the property at the activity level. It's an application-wide opt-out.
The full lineage of "manifest attribute that didn't quite work"
The forced-resizability rule isn't the first time Android overruled a manifest attribute, and it won't be the last. The pattern is consistent. The platform team adds an attribute to give developers control, developers misuse it (or use it for too long after the platform has moved on), and a later API level walks it back. Knowing this lineage helps predict which of your current declarations will be ignored on future Android versions.
android:screenOrientation already had two prior workarounds before API
36. On Android 12L (API 32+) Google introduced a per-device manufacturer opt-in.
Large-screen OEMs could choose to ignore portrait locks on tablets and foldables
even without a code change from the app. Samsung's One UI on the Z Fold series
enabled this immediately. Most other OEMs didn't. The behaviour was a black box from
the app's perspective. Your portrait lock worked on a Pixel Tablet and didn't on a Z
Fold, with no way to tell which from your code. API 36 just makes the behaviour
universal and explicit.
android:resizeableActivity went through a similar arc. When introduced
in Android 7.0 for split-screen multitasking, setting it to false was
the blessed way to opt a fixed-aspect game out. By Android 12, ChromeOS was treating
it as advisory. By API 36 on a large screen, it's ignored. The attribute itself is
still in the manifest schema and the documentation, which makes it tempting to
assume it still does what it did in 2017. It doesn't.
android:minSdkVersion is the rare case that goes the other way: Play
Store policies enforce a minimum higher than your declared value. As of late 2024,
Play requires API 31 (Android 12) for new apps and API 34 (Android 14) for app
updates, regardless of what your manifest says. The manifest value still controls
what runs on a real device, but the gating value for distribution is the Play
policy. Worth knowing when you're staring at "but my minSdk is 21" and
Play is rejecting your build.
Targeting decisions this tool nudges you toward
The form above defaults to the most-resizable, least-locked-down configuration for
the device class you select. That isn't a stylistic choice. It's what the Play Store
quality scoring rewards. Apps that declare aggressive locks
(portrait + maxAspectRatio 1.86 + resizeableActivity false) score worse
in the large-screen quality assessment that gates featuring and recommendation
slots. Two specific moves are worth calling out.
Drop maxAspectRatio unless you genuinely render badly on tall
screens. Setting it caps how tall Android will display your activity, which
made sense in 2017 when 18:9 was unusual and apps still assumed 16:9. With 20:9 the
norm and 21:9 foldables on the market, a 1.86 cap means your app sees a chunk of
forced letterboxing on every modern phone. The legitimate use cases are pixel-art
games and apps whose top-of-screen UI doesn't tolerate stretched layouts. Everything
else should leave it unset.
Avoid android:configChanges="orientation|screenSize|screenLayout"
as a way to skip Activity recreation. It works, in the sense that your
Activity won't be destroyed on rotation. But Compose, the Navigation library, and
most modern view systems are now built around the recreation model, and bypassing it
creates subtle bugs the Android team has stopped optimising for. Save state via
ViewModel or SavedStateHandle instead. If you've been
using configChanges as a performance shortcut, profile first. On
modern hardware the cost is usually under 30ms, which is invisible.
How to test the manifest you generated
Generating the XML is the easy part. Verifying it does what you intended requires a
couple of adb commands per device class. On a real foldable, the path
is: install your build, unfold the device, launch the activity, and run
adb shell dumpsys activity activities | grep -A 3 mResumedActivity to
see the recorded configuration. The mLastReportedConfiguration line
tells you what Android actually applied (orientation, smallest width,
screen layout) versus what you declared in the manifest.
On an emulator without a foldable AVD, you can fake the foldable form factor with
adb shell wm size 1812x2176 and adb shell wm density 380,
then launch your activity and inspect dumpsys the same way. Reset with
adb shell wm size reset and adb shell wm density reset
afterwards, or your emulator will stay in that configuration for future runs and
produce deeply confusing test results an hour later.