ionic-framework icon indicating copy to clipboard operation
ionic-framework copied to clipboard

feat: Support new edge-to-edge enforcement introduced in Android 15 (API 35)

Open dpalou opened this issue 11 months ago • 31 comments

Prerequisites

Describe the Feature Request

When running an app targeting SDK 35 in an Android 15 device, now the app fills the whole screen (it no longer leaves some margins for the bottom Android buttons for example). This means that some content might be behind the Android buttons, making that content unclickable.

I'm not sure if the best solution is that cordova-android applies margins to the WebView so it doesn't fill the full screen, making it behave similar to how it behaves in Android 14, or it should be Ionic the one handling those margins (I guess using the "safe area"). I'd prefer the latter because it will look similar to a native Android app, that's why I open this issue.

Right now cordova-android only supports SDK 34, it still doesn't support SDK 35.

To reproduce the issue, just add this in your config.xml and run an app in a device with Android 15:

<preference name="android-targetSdkVersion" value="35" />

For now, this change can be disabled by adding an option in the themes.xml file, but this option is temporary and will be removed in the future:

<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>

More information about this change:

https://developer.android.com/develop/ui/views/layout/edge-to-edge https://developer.android.com/about/versions/15/behavior-changes-15#edge-to-edge

Describe the Use Case

The new edge-to-edge display should be supported, otherwise some content can become unclickable because it's behind the Android buttons.

Describe Preferred Solution

I guess the easiest solution is to handle this case using the "safe area".

Describe Alternatives

No response

Related Code

No response

Additional Information

No response

dpalou avatar Dec 18 '24 14:12 dpalou

I'll chime in too, just to highlight that this needs some attention. I've been experimenting with migrating to SDK 35 to support Android 15 and have run into this edge-to-edge problem as well. Targeting SDK 35 in variables.gradle:

compileSdkVersion = 35
targetSdkVersion = 35

And running the Ionic "sidemenu" starter template app in the Android 15 emulator produces this display: (I changed the ion-toolbar background color to "warning" (i.e. yellow) for emphasis) Screenshot 2024-12-23 at 10 28 26 AM Note the Ionic toolbar renders underneath the Android status bar at the top, and the app's main page renders under the navigation bar at the bottom (with gesture navigation turned off). This is Android's edge-to-edge display paradigm.

As @dpalou mentions you can work-around this issue by adding the windowOptOutEdgeToEdgeEnforcement attribute to android/app/src/main/res/values-v35/styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <!-- Base application theme. -->
  <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
  </style>

  <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:background">@null</item>
    <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
  </style>
</resources>

Which produces this display: Screenshot 2024-12-23 at 10 55 36 AM

moose4lord avatar Dec 23 '24 15:12 moose4lord

Just experienced the same problem and the fix above worked. Question, though -- I would think this belongs in the capacitor repository not the ionic one? Seems like the fix might be around Java code to detect the inset sizes and react appropriately (as indicated here: https://developer.android.com/develop/ui/views/layout/edge-to-edge#java. . I'm happy to create the bug there if you agree.

davideshay avatar Dec 25 '24 06:12 davideshay

There's already an issue flagged on the capacitor GitHub page ionic-team/capacitor#7804. It was added pretty recently, so not much activity so far.

I think this should also be flagged in this repository, because using the windowOptOutEdgeToEdgeEnforcement attribute as a temporary work-around should be added to the Ionic Android scaffolding until Capacitor can make some progress with insets.

moose4lord avatar Dec 25 '24 17:12 moose4lord

Any news? There are problems with existing capacitor plugins like splash screen as well, because of new edge-to-edge.

Tomjech16 avatar Jan 09 '25 11:01 Tomjech16

I have the same issue, the app is unusable starting with Android 15

danpercic86 avatar Jan 22 '25 07:01 danpercic86

@moose4lord this solution worked on my device API 34 but the low-end device with API 29 not. Just for the record. I will try to use the community plugin for the API 29.

mfcarneiro avatar Jan 23 '25 00:01 mfcarneiro

pls fix

danielehrhardt avatar Jan 27 '25 18:01 danielehrhardt

Also waiting for a fix. Just updated our application to Capacitor 7, using minSDK 31, Target 35, tested on a Samsung Galaxy A23 running 34, the Navigation bar goes above our design. And same goes for the top part, which goes behind the status bar. Any quick fix?

mla03 avatar Jan 30 '25 15:01 mla03

I am facing the same issue , some times footer is also overlapped

AvniAnay avatar Jan 31 '25 04:01 AvniAnay

bump - same

DevDianDankie avatar Feb 01 '25 19:02 DevDianDankie

I've just published the Android Edge-to-Edge Support plugin, which applies an insert to the web view to restore the previous look. You just need to install it, and your done:

npm i @capawesome/capacitor-android-edge-to-edge-support

Optionally, you can also change the background color of the status and navigation bar. Let me know if you encounter any problems by creating an issue or discussion in capawesome-team/capacitor-plugins.

robingenz avatar Feb 06 '25 13:02 robingenz

Update: A GitHub PR (#7871) in the Capacitor repository has been approved to address this issue. I hacked the changes to the CapacitorWebView.java file and the PR seems to work well.

This fix has not been released yet, but look for it in the upcoming Capacitor v7.0.2 release. I doubt they will backport the code to Capacitor 6, so you'll probably have to migrate to Capacitor 7 if you haven't done so already.

Many thanks to @markemer for the fix.

moose4lord avatar Feb 07 '25 22:02 moose4lord

@moose4lord do we know, when Capacitor v7.0.2 will be released?

donqemal avatar Feb 10 '25 09:02 donqemal

I'm not sure when the next release will happen. They tend to make releases on a monthly cadence, so since 7.0.1 was released about 3 weeks ago, I'm guessing it will be pretty soon. On the other hand, there's a nasty bug (#7866) in the current Android dependencies that needs to get worked out before the next release. So who knows?

moose4lord avatar Feb 10 '25 14:02 moose4lord

@markemer Thanks for https://github.com/ionic-team/capacitor/pull/7871.

Although the PR successfully maintains current functionality (and I look forward to the release of 7.0.2) 🎉, how might we configure our apps to take advantage of the new edge-to-edge feature going forward?

For example, our app displays a map, which would happily go full height at the top of the display, for a more modern, native look. As I understand it, with this PR that won't be possible now?

Image

rossholdway avatar Feb 12 '25 16:02 rossholdway

@markemer Thanks for ionic-team/capacitor#7871.

Although the PR successfully maintains current functionality (and I look forward to the release of 7.0.2) 🎉, how might we configure our apps to take advantage of the new edge-to-edge feature going forward?

For example, our app displays a map, which would happily go full height at the top of the display, for a more modern, native look. As I understand it, with this PR that won't be possible now?

Image

Agreed with @rossholdway. Please, at the very least, make it optional by allowing enabling or disabling it in the Capacitor config file, as some people might want to utilize the edge-to-edge feature.

ckoon-infopro avatar Feb 13 '25 06:02 ckoon-infopro

Just FYI, I played with @markemer's edge-to-edge fix and did notice a small bug.

With Capacitor 6 when a device with a camera notch is rotated to landscape mode, the display would correctly leave space on the left side for the camera notch. Like so:

Image

Unfortunately, using Capacitor 7 with @markemer's edge-to-edge fix, there's no longer extra space on the left of the display to accommodate the camera notch:

Image

moose4lord avatar Feb 13 '25 12:02 moose4lord

Same here

AntoscencoVladimir avatar Mar 07 '25 14:03 AntoscencoVladimir

After researching and testing community plugins and other tests i found this comment i it work for me https://github.com/ionic-team/capacitor/issues/7846#issuecomment-2638240125 To disable the edge-to-edge:

Add to capacitor.config.ts

const config: CapacitorConfig = {
    plugins: {
        StatusBar: {
            overlaysWebView: false,
        },
    },
};

adriallongarriu avatar Mar 07 '25 15:03 adriallongarriu

After researching and testing community plugins and other tests i found this comment i it work for me ionic-team/capacitor#7846 (comment) To disable the edge-to-edge:

Add to capacitor.config.ts

const config: CapacitorConfig = {
    plugins: {
        StatusBar: {
            overlaysWebView: false,
        },
    },
};

But how is this a fix for the overall problem? This only takes effect in regards to the statusbar, no? The introduction of the edge to edge display also effects the safe-area for the notch/navigation bar

nikqig avatar Mar 08 '25 21:03 nikqig

Just a followup, Ionic 8.5.0 and Capacitor 7.1.0 were released over the past of couple days and unfortunately they don't fix the edge-to-edge (inset) issue we've been discussing. Capacitor issue 7916 has been created to address the latest snafu.

Additionally the latest code seems to have broken the <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item> workaround that has been used to stave off the edge-to-edge mandate. This is what I get when I use windowOptOutEdgeToEdgeEnforcement:

Image

The status bar at the top, which used to work, is now broken.

I would recommend people not upgrade to Capacitor 7.1.0 until this is sorted out.

moose4lord avatar Mar 14 '25 22:03 moose4lord

Hi, what is your solution for app displaying below navigation bar in the bottom of a screen?

Tomjech16 avatar Mar 25 '25 11:03 Tomjech16

I have not released an upgraded app with Capacitor 7 yet, but if I did, I would set adjustMarginsForEdgeToEdge to "force" in your capacitor.config.ts file. It seems to do the best job of working around the edge-to-edge issues.

  android: {
    adjustMarginsForEdgeToEdge: 'force'
  }

moose4lord avatar Mar 25 '25 16:03 moose4lord

I have not released an upgraded app with Capacitor 7 yet, but if I did, I would set adjustMarginsForEdgeToEdge to "force" in your capacitor.config.ts file. It seems to do the best job of working around the edge-to-edge issues.

  android: {
    adjustMarginsForEdgeToEdge: 'force'
  }

Does not work for me.

danielehrhardt avatar Mar 25 '25 16:03 danielehrhardt

There are some Capacitor plugins that are still causing problems. See Capacitor issue 7916. The next Capacitor release should fix at least some of them. Software development is an iterative process. We're gettin' there.

The adjustMarginsForEdgeToEdge=force parameter does a good job recreating the "old" Capacitor 6 non-edge-to-edge display, which is fine for me. If you're trying to create an edge-to-edge app, you probably want to set adjustMarginsForEdgeToEdge=auto.

moose4lord avatar Mar 25 '25 21:03 moose4lord

Just a followup, Ionic 8.5.0 and Capacitor 7.1.0 were released over the past of couple days and unfortunately they don't fix the edge-to-edge (inset) issue we've been discussing. Capacitor issue 7916 has been created to address the latest snafu.

Additionally the latest code seems to have broken the <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item> workaround that has been used to stave off the edge-to-edge mandate. This is what I get when I use windowOptOutEdgeToEdgeEnforcement:

Image

The status bar at the top, which used to work, is now broken.

I would recommend people not upgrade to Capacitor 7.1.0 until this is sorted out.

Hi @moose4lord , Have you succeed to make it work with windowOptOutEdgeToEdgeEnforcement attribute? I read that you have a name conflict for the bridge view. But since then?

It seems that the capacitor config is doing the job but I would like to disable this behavior totally and stay on API 34 behavior but the attribute windowOptOutEdgeToEdgeEnforcement doesn't work :(

TiBz0u avatar Mar 28 '25 16:03 TiBz0u

I'm not sure what you mean when you say "windowOptOutEdgeToEdgeEnforcement doesn't work".

But if you want to avoid the whole edge-to-edge debacle, I think you can just stick with Capacitor 6 and SDK 34. This will likely work until August, the one year anniversary of the release of Android 15, at which point targeting SDK 35 will be required.

moose4lord avatar Mar 28 '25 18:03 moose4lord

If using adjustMarginsForEdgeToEdge: 'force', how can we control the color of status and navigation bar?

Tomjech16 avatar Apr 02 '25 11:04 Tomjech16

@Tomjech16 It seems that the bars are always white, unfortunately.

neave avatar Apr 11 '25 11:04 neave

I shared my current (hopefully temporary) solution here

hoi4 avatar Apr 11 '25 14:04 hoi4