Skip to content
App Maintenance & Upgrades

Google Play target API 36: what breaks and how to fix it

Since August 31, Play blocks updates that don't target Android 16. Why it's more than a version bump: edge-to-edge, back gestures, tablets, and the fixes.

Ingenious Techlab Team9 min read
Contents
  1. What the rule actually does
  2. Why “change 34 to 36” is not the fix
  3. Change 1: every screen goes edge-to-edge
  4. Change 2: your back button handler stops being called
  5. Change 3: tablets and foldables ignore your orientation lock
  6. Change 4: the Android 15 changes you may have skipped
  7. Also on the calendar: 16 KB memory pages
  8. Where each framework stands
  9. The order to do it in
  10. If you would rather not do this yourself

If you opened Play Console recently and found a warning that your app must target Android 16 (API level 36), this is what it means, what it will break, and the order to fix it in.

The short version: since 31 August 2026, Google Play will not accept a new app or an app update unless it targets API 36. Your live listing does not disappear. But the next time you need to ship anything — a feature, a price change, an urgent fix for a crash — the upload is refused until the target is raised.

And raising it is not the one-line change it looks like.

What the rule actually does

Play’s requirement has two parts, and they apply to different things:

  • New apps and updates must target Android 16 (API 36) or higher.
  • Existing apps must target at least Android 15 (API 35) to stay available to new users on newer devices. Below that, Play says the app will stop being available to new users whose devices run an Android version higher than the app’s target. People who already installed it can still reinstall and use it.

An extension to 1 November 2026 can be requested from the Policy status page in Play Console. It has to be requested and approved; it is not automatic.

After August 31, 2026: what your latest target API level still allows

Your latest releasePeople who already installed itNew people installing itYou shipping an update or fix
Targets API 36 Yes Yes, on every Android version Yes
Targets API 35 Yes Yes, on every Android version No — until it targets 36, or November 1, 2026 with an approved extension
Targets API 34 or lower Yes — they can still reinstall it Only on devices running Android no newer than the app’s target No
From Google Play’s target API level requirements. Wear OS, Automotive, TV and XR have lower floors. An app on API 35 looks fine in the store right up to the day you need to push a fix.

The middle row is where most apps are sitting today. An app on API 35 is fully available in the store, so nothing looks wrong — until the day it needs an update.

Why “change 34 to 36” is not the fix

The target SDK is not a label. It is a behaviour switch. Android keeps old behaviour for apps that target old versions, and applies each version’s changes only when an app declares it is ready for them. Raising the number is that declaration.

So the Gradle change itself really is two lines:

android {
    compileSdk = 36
    defaultConfig {
        targetSdk = 36
    }
}

What those two lines switch on is the rest of this post. An app coming from API 34 takes on both Android 15’s changes and Android 16’s in one release — which is the usual situation for an app nobody has touched in a year.

Change 1: every screen goes edge-to-edge

This is the change you will see first, on every screen, on day one.

What edge-to-edge enforcement does to an app's layoutThree phones. Targeting API 34, the system reserves space for the status bar and navigation bar. Targeting API 35 or higher without handling insets, the app's header draws underneath the clock and its bottom button sits under the gesture bar where it cannot be tapped reliably. Targeting 35 or higher with insets applied, the header background extends behind the status bar while the title and button are moved clear of both bars.Targets API 34The system reserved space for the barsOrders9:41Pay $24.00What your QA passed onand why nobody noticedTargets 35+, no insetsContent now draws behind the barsOrders9:41title under the clockPay $24.00Button under the gesture bar:swipes go home instead of payingTargets 35+, insets appliedBars filled, content insetOrders9:41Pay $24.00Header colour fills the bar area;title and button padded by the insets
From API 35 the bars are transparent and the layout no longer stops at them; from API 36 the opt-out is gone. The fix is not a setting — it is applying window insets to the parts of each screen that must stay clear.

From API 35, apps are edge-to-edge by default: the status bar and gesture navigation bar become transparent, and your layout no longer stops at them. setStatusBarColor() stops having any effect. Android 15 allowed an opt-out attribute, windowOptOutEdgeToEdgeEnforcement, and plenty of apps used it to defer the work.

On API 36 that attribute is deprecated and disabled. There is no longer a switch.

What that looks like in a real app: the screen title slides under the clock, the bottom “Pay” or “Save” button lands under the gesture bar where a swipe sends the user home instead, and full-screen sheets lose their bottom row. It rarely crashes, so crash reporting will not tell you. Screenshots will.

The fix: apply insets, not colours

The pattern Android’s own templates use — enable edge-to-edge, then pad the views that must stay clear by the size of the system bars:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        enableEdgeToEdge()
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { view, insets ->
            val bars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            view.setPadding(bars.left, bars.top, bars.right, bars.bottom)
            insets
        }
    }
}

The judgement is per screen, and that is where the time goes. Backgrounds, maps, images and scrolling lists usually should run behind the bars. Titles, buttons, text fields and anything tappable should not. Padding the root of every screen is the fast fix and looks noticeably worse than doing it properly.

In React Native, the legacy <SafeAreaView> is deprecated as of 0.81; the replacement is react-native-safe-area-context. In Flutter, the equivalent is SafeArea or the padding from MediaQuery. Flutter’s own note warns that its opt-out might crash your app on Android 16 or later, so if your project still has it, that is the first thing to remove.

Change 2: your back button handler stops being called

This one is quieter and more dangerous, because it fails without an error.

How a back gesture is delivered before and after targeting Android 16Before API 36, a back gesture reaches an activity's onBackPressed() override, where the app can confirm or cancel. When targeting API 36, onBackPressed() is not called and KEYCODE_BACK is not dispatched. The gesture is delivered through registered back callbacks instead, and an app that only overrides onBackPressed() loses its custom behaviour with no error.Targeting API 35 or lowerBack gestureor back buttononBackPressed()your override runs“Discard this draft?”user confirms, nothing is lostTargeting API 36, override not migratedBack gesturepredictive animationonBackPressed()never called — no error, no logScreen closesthe unsaved draft is goneTargeting API 36, migratedBack gesturepredictive animationOnBackPressedCallbackregistered while there is a draft“Discard this draft?”same behaviour, new route
Android’s wording: when targeting Android 16, onBackPressed() is not called and KEYCODE_BACK is not dispatched. The android:enableOnBackInvokedCallback="false" opt-out exists but is described as temporary — it buys time, not a fix.

For apps targeting API 36, predictive back is on by default, and Android’s wording is exact: onBackPressed() is not called and KEYCODE_BACK is not dispatched.

Anything the app did in that override simply stops happening. The common cases:

  • “You have unsaved changes — discard?” dialogs. The user swipes back and the draft is gone.
  • Closing a custom drawer, search overlay or bottom sheet before leaving the screen.
  • Stepping back through a multi-step form or checkout instead of exiting it.
  • Blocking back during a payment in progress.

The fix: decide before the gesture, not during it

The replacement is a callback registered with the back dispatcher. The important difference is conceptual: with predictive back, the system starts animating as the gesture begins, so your app must already know whether it wants to intercept. You enable and disable the callback as state changes, not when back is pressed:

private val discardDraft = object : OnBackPressedCallback(false) {
    override fun handleOnBackPressed() {
        showDiscardDialog()
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    onBackPressedDispatcher.addCallback(this, discardDraft)
}

// Wherever the draft changes:
discardDraft.isEnabled = hasUnsavedChanges

A temporary opt-out exists — android:enableOnBackInvokedCallback="false" on the application or activity. Android describes it as temporary. Use it to ship an urgent update if you must, and schedule the migration in the same breath.

For React Native, the 0.81 release notes say BackHandler keeps working for most cases, but custom native code that overrides onBackPressed() needs migrating — which includes native modules and third-party libraries, not just your own code. Expo SDK 54 leaves predictive back disabled by default, so an Expo app will not see this until it is switched on.

Change 3: tablets and foldables ignore your orientation lock

Many apps lock themselves to portrait and assume that settles the question of layout. On API 36, for large screens, it no longer does.

What happens to a portrait-locked app on a tablet when it targets Android 16On a phone under 600dp wide, a portrait lock is honoured. On a display that is at least sw600dp, an app targeting API 36 has its orientation, resizability and aspect-ratio restrictions ignored, so a portrait-only layout is stretched across a landscape window. A temporary opt-out exists, when you target API level 37 it no longer applies. Games are exempt.Phone, under 600dpPortrait lock still honouredTablet, targeting API 35Letterboxed: dull, but intactTablet, targeting API 36Lock ignored: the window fills the screenone 200dp-wide buttonWhat a phone-only layout typically does when stretched• Fixed-height images crop, or full-width images tower over the screen• Forms and buttons span the whole width and read as broken• Rotation restarts the activity — and loses state nobody savedOur experience, not Android’s list. Test on a large-screen emulator and a foldable.
Ignored on sw600dp displays for API 36 targets: screenOrientation, resizableActivity, minAspectRatio, maxAspectRatio, setRequestedOrientation(). The PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY opt-out stops working when you target API level 37. Exempt: games (by android:appCategory), and screens under 600dp.

On any display at least 600dp wide — tablets, and foldables when unfolded — apps targeting API 36 have screenOrientation, resizableActivity, minAspectRatio and maxAspectRatio ignored, along with setRequestedOrientation(). The window fills the screen and rotates with the device. Games are exempt, and phones below 600dp are unaffected.

There is an opt-out property, PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY. Android is explicit that it stops working when you target API 37. If Play keeps raising its requirement once a year, as it has, that is roughly a year of runway — our reading, not a date Android has published.

Two things make this worse than it sounds. First, rotation now happens, and rotation recreates the activity — any state the app was not saving because “we’re portrait-only” is lost on the turn. Second, the stretched layout is what reviewers and users on those devices see, in screenshots and in reviews.

Change 4: the Android 15 changes you may have skipped

If the app jumps straight from 34, it also inherits everything below. These are the ones that turn up most in real apps — not Android’s full list.

Inherited from API 35: changes you get if you skipped a year

ChangeWhat you would seeImpact
LayoutEdge-to-edge is enforcedContent draws behind the status and navigation bars unless the app applies insets. setStatusBarColor() has no effect.Headers under the clock, buttons under the gesture barBreaks
LayoutscreenWidthDp and screenHeightDp include the system barsConfiguration sizes no longer exclude the bars, so size maths done by hand is off.Breakpoints and custom sizing shift by the bar heightDegrades
NetworkingTLS 1.0 and 1.1 are disallowedConnections to servers that only speak the old versions fail.An old API or payment endpoint stops respondingBreaks
Background workdataSync foreground services capped at 6 hours per 24onTimeout() is called and the service must stop within seconds; starting it again after the limit throws.Long uploads or syncs die part-wayDegrades
Background workBOOT_COMPLETED cannot start several foreground service typesdataSync, camera, mediaPlayback, phoneCall, mediaProjection and microphone throw instead.A crash on boot that never happens in testingDegrades
MediaAudio focus requires being the top app or a foreground serviceOtherwise requestAudioFocus returns AUDIOFOCUS_REQUEST_FAILED.Playback silently refuses to startDegrades
Java runtimeString.format argument index 0 now throwsIllegalFormatArgumentIndexException — indices start at 1.A crash on a screen that formats textDegrades
Java runtimeKotlin removeFirst() / removeLast() resolve to new Java methodsCompiled against SDK 35, they throw NoSuchMethodError on Android 14 and below.Crashes only on older phones — the ones you did not testBreaks
TextelegantTextHeight defaults to trueAffects Arabic, Thai, Tamil and several other scripts; in Android 16 the attribute is ignored.Clipped or re-spaced text in some languagesCosmetic
Selected from Android’s behaviour changes for apps targeting Android 15 — the ones we see most in real apps, not the complete list. Impact ratings are ours.

Two deserve a highlight because they fail somewhere you are not looking. TLS 1.0 and 1.1 are disallowed, so an old payment gateway, CMS or internal API that nobody has upgraded simply stops answering. And Kotlin’s removeFirst() and removeLast(), compiled against SDK 35, throw NoSuchMethodError on Android 14 and older — so the crash only appears on older phones, which are exactly the ones a small team does not test on.

Also on the calendar: 16 KB memory pages

A separate Play requirement applies to apps with native code — C or C++, the NDK, or a third-party native library, which covers a lot of React Native, Flutter, Unity, media and security SDKs. Apps targeting API 35 and higher must support 16 KB memory pages on 64-bit devices. Per Android’s page-size guide, from 1 February 2027, updates that do not support it cannot be released.

This deadline has moved more than once, so check the date Play Console shows for your own app. Apps written only in Java or Kotlin are unaffected. Android Gradle Plugin 8.5.1 and NDK r28 or newer build aligned by default; React Native’s 0.81 notes state that React Native itself is already compliant, but every native dependency still has to be. To check a release build:

zipalign -v -c -P 16 4 app-release.apk
Android deadlines from August 2026 onwardAugust 31, 2026: New apps and updates must target API 36. November 1, 2026: Approved extensions run out. February 1, 2027: Updates without 16 KB page support blocked (native code only). Your first API 37 build: Large-screen opt-out stops working. The large-screen opt-out ends when you target API level 37.PASSEDAHEAD
August 31, 2026
New apps and updates must target API 36
November 1, 2026
Approved extensions run out
February 1, 2027
Updates without 16 KB page support blocked (native code only)
Your first API 37 build
Large-screen opt-out stops working
The first date has passed. The 16 KB date has moved before — it is the one on Android’s page-size guide as of when this post was checked; your Play Console shows the date that applies to your app.

Where each framework stands

If your app is built with a cross-platform framework, the framework version decides your starting point — but not your finishing point.

Framework status for Android 16

React NativeExpoFlutter
Version0.81SDK 543.27 and later
Default targetAndroid 16 (API 36) by defaultAndroid 16 (ships React Native 0.81)3.27 made Android 15 (API 35) the default target — confirm what your version resolves flutter.targetSdkVersion to
Edge-to-edgeRequired on Android 16; new edgeToEdgeEnabled Gradle property extends it to older versionsEnabled in all Android apps and cannot be disabledEdge-to-edge is the default from API 35; Flutter warns the opt-out might crash your app on Android 16 or later
Back gesturePredictive back on by default for API 36; BackHandler keeps working, custom onBackPressed() overrides need migratingPredictive back disabled by default in SDK 54; enable it in app.jsonNot covered by the Flutter breaking-change note — audit plugins and native code that override onBackPressed()
Watch forLegacy <SafeAreaView> deprecated — move to react-native-safe-area-contextreact-native-edge-to-edge is no longer an expo dependencyIf you opted out, move the attribute into a values-35 resource folder, or migrate to edge-to-edge
From the React Native 0.81 release post, the Expo SDK 54 changelog and Flutter’s edge-to-edge breaking-change note. Upgrading the framework sets the target; it does not migrate your screens or your native modules.

The common misunderstanding here is that upgrading the framework is the fix. It sets the target. It does not decide which of your screens should pad for the status bar, move your custom back handling, or make your native modules and plugins compliant. And a framework upgrade that spans several versions — React Native in particular — usually brings its own breaking changes along with the ones above.

The order to do it in

  1. Check where you actually stand. Open Play Console’s Policy status page, confirm your current target, and request the November extension now if a release is due before the fix will be ready. It costs nothing.
  2. Upgrade the framework, then raise the target on a branch — not in the same commit as feature work.
  3. Walk every screen for edge-to-edge, on gesture navigation and three-button navigation, with a display cutout. Screenshot each one.
  4. Search the codebase and dependencies for onBackPressed and migrate each use. Then test every flow where back should not simply leave the screen.
  5. Run it on a large-screen emulator and a foldable. Rotate on every screen with unsaved input.
  6. Test on an Android 14 device, specifically for the Kotlin collection crash and TLS failures against your real backend.
  7. Check native libraries for 16 KB alignment while you are in the build anyway.
  8. Release through a staged rollout and watch crash and ANR rates for the first days — Play’s vitals thresholds apply to the new build from the moment it ships.

How long that takes depends almost entirely on step 3 and on how far behind the framework version is. In our experience, an app already on a recent framework release with a dozen screens is days of work; an app several major versions behind, with custom native modules and a portrait-only design, is weeks. Those are our estimates, not measurements.

If you would rather not do this yourself

This is exactly the kind of work that lands on a team that is busy shipping features: it arrives on a date nobody chose, it touches every screen, and it looks finished long before it is. It is also the work we do most often for existing apps — framework upgrades, platform deadlines and the release that follows, as part of our mobile app development and maintenance.

If your app was built quickly or by a previous team, the upgrade tends to surface other problems at the same time; what usually needs fixing in AI-built apps covers those. And iOS has its own deadline coming, where apps built with the iOS 27 SDK must use the scene life cycle or fail to launch.

Send us your Play Store link and the framework you are on, and we will tell you what the upgrade involves and how long it should take — get in touch.

Sources

Verified

This post is part of our work onApp maintenance that keeps you ahead of every deadline

Related reading

Let's talk

Tell us what you are building

Send us the scope and we will come back with an honest assessment: what it takes, roughly what it costs, and whether we are the right people for it.

  • A written reply from an engineer
  • No call required
  • No obligation