maui icon indicating copy to clipboard operation
maui copied to clipboard

[Android] Apps compiled for 15.0 / 35 default displaying as Edge to Edge

Open Redth opened this issue 1 year ago • 2 comments

Description

Starting with Android 15.0 (API 35) apps are displayed 'Edge to Edge' by default. https://developer.android.com/about/versions/15/behavior-changes-15#window-insets

It seems that .NET MAUI still adds content insets when using Shell but when using normal pages it does not. The result is that page content extends underneath the system bars (status and navigation) where it previously did not on older android versions.

There is a way to opting out of the new behaviour: https://medium.com/androiddevelopers/insets-handling-tips-for-android-15s-edge-to-edge-enforcement-872774e8839b

First, you need to add values-v35/styles.xml and values/styles.xml files: android-35-edge-to-edge-opt-out-resources

In the values-v35/styles.xml declare a style:

<?xml version="1.0" encoding="utf-8" ?> 
<resources>
    <style name="OptOutEdgeToEdgeEnforcement">
        <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
    </style>
</resources>

You need to add a style with the same name in the values/styles.xml file (without the attribute):

<?xml version="1.0" encoding="utf-8" ?> 
<resources>
    <style name="OptOutEdgeToEdgeEnforcement">
    </style>
</resources>

Now in your MainActivity.cs override the OnCreate(Bundle? savedInstanceState) and apply the style you created:

[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
    protected override void OnCreate(Bundle? savedInstanceState)
    {
        // Must apply the style before the DecorView setup
        Theme?.ApplyStyle(Resource.Style.OptOutEdgeToEdgeEnforcement, force: false);

        base.OnCreate(savedInstanceState);
    }
}

Version with bug

9.0.0-rc.1.24453.9

Is this a regression from previous behavior?

No, this is something new

Last version that worked well

Android 14.0 and older

Affected platforms

Android

Affected platform versions

Android 15.0 / API 35

Redth avatar Sep 12 '24 16:09 Redth

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

github-actions[bot] avatar Sep 12 '24 16:09 github-actions[bot]

Thanks for the quick solution. @Redth

last-Programmer avatar Sep 23 '24 22:09 last-Programmer

Hi @Redth, thanks for sharing this workaround. I'm on net8.0-android and I have the same issue.

When trying to apply the workaround suggested above, the app won't compile with the following error message: 0>styles.xml(2): Error APT2260 : style attribute 'android:attr/windowOptOutEdgeToEdgeEnforcement' not found.

Is the workaround net9.0-android only?

Thanks

eddieyanez avatar Oct 27 '24 20:10 eddieyanez

Hi @Redth, thanks for sharing this workaround. I'm on net8.0-android and I have the same issue.

When trying to apply the workaround suggested above, the app won't compile with the following error message: 0>styles.xml(2): Error APT2260 : style attribute 'android:attr/windowOptOutEdgeToEdgeEnforcement' not found.

Is the workaround net9.0-android only?

Thanks

It's Android API 35 only, which is technically only supported in .NET 9, however in .NET 8 you could technically still try to target API 35 by adding this to your AndroidManifest.xml file:

<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="35" />

This goes inside the <manifest /> element.

NOTE: This won't allow you to use new API's in your app that are Android 35+ only, but it should make the tooling recognize the new attribute you're trying to use in the style.

Redth avatar Oct 30 '24 16:10 Redth

Thank you!

eddieyanez avatar Oct 31 '24 11:10 eddieyanez

Thank you for the work-around @Redth.

I've noticed the following error in my code for MainActivity however, the app still compiles, builds and runs in both debug and release. Not sure why this isn't found. I am on .NET9 so thought this would be supported.

Image

jveltd avatar Nov 04 '24 21:11 jveltd

We can use https://github.com/dotnet/maui/issues/2342 to track improvements to Safe Area support in .NET MAUI.

Redth avatar Nov 05 '24 19:11 Redth

For someone looking to fix the same issue as me that doesnt have a values-v35 folder yet and no styles file in there. Reminder that Visual studio doesnt set it as an AndroidResource by default if you add an xml file using New Item.

Gekidoku avatar Nov 15 '24 09:11 Gekidoku

Hi @Redth, thanks for sharing this workaround. I'm on net8.0-android and I have the same issue. When trying to apply the workaround suggested above, the app won't compile with the following error message: 0>styles.xml(2): Error APT2260 : style attribute 'android:attr/windowOptOutEdgeToEdgeEnforcement' not found. Is the workaround net9.0-android only? Thanks

It's Android API 35 only, which is technically only supported in .NET 9, however in .NET 8 you could technically still try to target API 35 by adding this to your AndroidManifest.xml file:

This goes inside the `` element.

NOTE: This won't allow you to use new API's in your app that are Android 35+ only, but it should make the tooling recognize the new attribute you're trying to use in the style.

Hi @Redth I have tried to add android:targetSdkVersion="35". It, with .NET8, compiles and I can produce an APK. When I go to install and run it on a device < 35, the app crashes with a log similar to this: Assertion at /__w/1/s/src/mono/mono/metadata/object.c:4410, condition is_ok (error)' not met, function:mono_unhandled_exception_internal, (null) assembly:System.Private.CoreLib.dll type:AggregateException member:(null) 12-04 11:30:15.543 15378 15415 F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 15415 (Finalizer), pid 15378

Going back to android:targetSdkVersion="34", the app does not crash. Is it absolutely necessary to switch to .NET9 to use android:targetSdkVersion="35"?

acaliaro avatar Dec 05 '24 09:12 acaliaro

I'm on .NET 9.0 and I get the following error: 'ResourceConstant.Style' does not contain a definition for 'OptOutEdgeToEdgeEnforcement'

Do need to do something special in the .csproj file to add these new style.xml resource/values?

I have added both styles.xml files in the paths explained above in the workaround. And I added those files as "New Item" per @Gekidoku instructions.

steve3p0 avatar Dec 27 '24 09:12 steve3p0

I'm on .NET 9.0 and I get the following error: 'ResourceConstant.Style' does not contain a definition for 'OptOutEdgeToEdgeEnforcement'

Do need to do something special in the .csproj file to add these new style.xml resource/values?

I have added both styles.xml files in the paths explained above in the workaround. And I added those files as "New Item" per @Gekidoku instructions.

I had the same issue, you need to set the Build Action for the styles.xml files as AndroidResource. See the images below if you are unsure how to do this

Image

Image

nolios avatar Jan 18 '25 09:01 nolios

I'm on .NET 9.0 and I get the following error: 'ResourceConstant.Style' does not contain a definition for 'OptOutEdgeToEdgeEnforcement' Do need to do something special in the .csproj file to add these new style.xml resource/values? I have added both styles.xml files in the paths explained above in the workaround. And I added those files as "New Item" per @Gekidoku instructions.

I had the same issue, you need to set the Build Action for the styles.xml files as AndroidResource. See the images below if you are unsure how to do this

Image

Image

Just logged in to reply with the same. In one project it automatically set the build action iirc. In another VS didnt.

Gekidoku avatar Jan 18 '25 09:01 Gekidoku

These instructions may be outdated as edge-to-edge is opted out by default now as per PR#25517.

We were having trouble working out how to opt in since we use edge-to-edge in our App and finally found that PR which suggests we need to set <item name="maui_edgetoedge_optout">false</item>.

@Redth, that PR has documentation on what's happening; however, it never made it into the release notes or any official docs.

rcarde avatar Jan 19 '25 23:01 rcarde