As an Android developer with apps on the Google Play Store, you should have received an email from Google regarding the requirement to update your apps to target SDK 35 by the end of August. According to StatCounter, SDK 35 is currently present on 20% of Android devices.
In case you haven't decided to abandon your apps, there is no option but to update them. As is often the case with Android, Google tends to break things, so targeting SDK 35 also causes issues. In this post, I will focus on the enforced edge-to-edge app layout and the easiest way to opt out of it.
After updating the targetSDK and compileSDK to version 35 in your app's build.gradle file, you may have thought you were nearly finished with the necessary updates. However, upon running the app on an SDK 35 device, you might be surprised to discover that your app's layout is now rendered beneath the action bar and navigation buttons. Check out the image below for a visual reference.
Let's resolve this with minimal code changes and move on with our lives.
My demo app is quite simple, and it uses the Theme.Material3.DayNight theme. This theme is referenced directly in the AndroidManifest.xml file as follows:
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.Material3.DayNight"
>
You might be referencing another theme directly, or you are defining your own theme, inheriting from an existing one. We are going exactly in that direction, as we will need to define our own theme anyway.
First, we'll add a themes.xml file to our res/values/ directory (if it isn't there already). In that file, we'll define BaseTheme, in this example inheriting from Theme.Material3.DayNight. You will be adding general theme customizations to the BaseTheme. We will then inherit our final AppTheme from the BaseTheme (you'll see in a moment why another theme inheritance is necessary). So, themes.xml will look something like the following (you can use the styles.xml file instead, I prefer separating layout element styles from themes):
<style name="BaseTheme" parent="Theme.Material3.DayNight">
<!-- General theme customizations go here. -->
</style>
<style name="AppTheme" parent="BaseTheme" />
</resources>
Now, we'll create the res/values-v35 directory and add another themes.xml file to it. In this file, our AppTheme will inherit from the BaseTheme as well, but it will opt out of edge-to-edge enforcement for SDK 35 devices. The file will look like the following:
<style name="AppTheme" parent="BaseTheme">
<item
name="android:windowOptOutEdgeToEdgeEnforcement"
tools:targetApi="35">true</item>
</style>
</resources>
Finally, we need to update the AndroidManifest.xml file to reference the AppTheme:
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
>
And that would be it! Happy coding!
Update:
Thanks to Leon Omelan for the heads-up. The windowOptOutEdgeToEdgeEnforcement attribute has been deprecated in SDK 36, and it will not work on SDK 36 devices once you target that API level. Therefore, this solution is only temporary, just like anything else with Android.