DEV Community

Cover image for I upgraded three Flutter apps to API 36. Here is what actually broke
Emre Polat
Emre Polat

Posted on

I upgraded three Flutter apps to API 36. Here is what actually broke

Google Play's deadline passed on August 31, 2026. Since that date you cannot publish an update to an existing app unless it targets Android 16, API level 36. Not a new app. Any update. A five year old app with a hundred thousand installs cannot ship a one line crash fix until targetSdk goes to 36.

You can request an extension until November 1, 2026, which buys you six weeks and nothing else. The work is the same.

I went through this on three of my own apps: a prayer times app, a jewelry store SaaS and a puzzle game. Changing two numbers in build.gradle.kts took about a minute. Everything after that took two days. Here is the list, in the order it cost me time.

1. The release build broke and debug did not

This one is the reason I am writing the post.

My prayer times app schedules a notification for each prayer. In debug everything worked. In release the notifications simply never fired, with no crash and no log line. The app looked fine. People just stopped getting notified.

The cause was R8. flutter_local_notifications serializes its scheduled notification data with Gson, and Gson needs generic type information at runtime. R8 stripped it, so zonedSchedule threw RuntimeException: Missing type parameter deep inside the plugin, and the exception was swallowed by my own state handling. Immediate notifications kept working, because show() does not go through Gson. That difference is what made it so confusing.

The fix is a few lines in proguard-rules.pro:

-keepattributes Signature
-keep class com.dexterous.** { *; }
-keep class * extends com.google.gson.reflect.TypeToken
Enter fullscreen mode Exit fullscreen mode

Turning off minification also "fixes" it, and that is the advice you find in most issue threads. It is a bad trade. With the keep rules in place and minification back on, my dex went from 14.8 MB to 2.0 MB and the APK from 60.2 MB to 55.1 MB.

If you take one thing from this post: build the release version and install it on a real device before you upload. Debug builds hide this entire class of bug.

2. Plugins that no longer compile

Anything unmaintained since 2023 is a coin flip on the current Android Gradle Plugin. In two cases I replaced the plugin instead of forking it, because a package that has not seen a commit in three years will break again at the next deadline, and there is another deadline every year.

Before you start, run flutter pub outdated and look at the packages with no recent releases. Those are your real work items, not the SDK number.

3. Gradle, AGP and Kotlin disagreeing

Bumping one of the three and not the others produces errors that point at the wrong thing. You get a Kotlin compile error that is actually an AGP version problem, or a Gradle daemon failure that is actually a JDK mismatch.

Do them together, check the official compatibility table, and pin the Java version in gradle.properties so your machine and CI agree.

4. The Data safety form drifts

Your app now pulls newer SDK versions, and newer SDK versions collect different things. The form you filled in two years ago no longer matches what your app actually does, and Play checks this.

Go through the form again with your current dependency list in front of you, especially advertising IDs, crash reporting and analytics.

5. Permissions and service types

Declarations that were fine two API levels ago now need to be explicit. Foreground services need a type. Notifications need a runtime permission. Exact alarms need a separate one, and on Samsung and Xiaomi devices battery optimization will still kill your scheduled work unless you handle it.

The permission audit is also a good moment to delete what you are no longer using. Every permission you remove is one less question on the Data safety form.

A checklist you can actually use

  1. targetSdk and compileSdk to 36
  2. Gradle, AGP and Kotlin to compatible versions, pinned JDK
  3. flutter pub outdated, upgrade or replace the dead packages
  4. Build the release AAB, install it on a real device, exercise the features that rely on background work
  5. Check keep rules if anything silently misbehaves only in release
  6. Permission audit, then update the Data safety form
  7. Upload to a closed test track first, not straight to production

If you are stuck

Most of the pain here is not the SDK bump, it is the archaeology in a project nobody has touched in two years. If your app is blocked and you are hitting one of these, leave a comment with the error and I will tell you what worked for me.

Top comments (0)