When using android:windowSoftInputMode="adjustResize" and env(safe-area-inset-top) in a Cordova app targeting targetSdkVersion 35, the app should behave as before
Bug Report
Problem
What is expected to happen?
When using android:windowSoftInputMode="adjustResize" and env(safe-area-inset-top) in a Cordova app targeting targetSdkVersion 35, the app should behave as before:
The keyboard should resize the WebView content properly.
The env(safe-area-inset-top) variable should apply correct top padding to accommodate notches/status bar.
What does actually happen?
When targeting SDK 35 (Android 15):
The keyboard behavior (adjustResize) no longer works correctly without applying manual WindowInsets handling.
The CSS variable env(safe-area-inset-top) returns 0px or is ignored in Android WebView, resulting in headers and content being overlapped by the status bar or notch.
A manual workaround using ViewTreeObserver and JavaScript is required to restore proper layout and safe-area behavior.
Information
When targeting SDK 35 (Android 15):
The keyboard behavior (adjustResize) no longer works correctly without applying manual WindowInsets handling.
The CSS variable env(safe-area-inset-top) returns 0px or is ignored in Android WebView, resulting in headers and content being overlapped by the status bar or notch.
A manual workaround using ViewTreeObserver and JavaScript is required to restore proper layout and safe-area behavior.
Command or Code
<activity android:name=".MainActivity" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.AppCompat.Light.NoActionBar">
Environment, Platform, Device
Environment: Cordova + Android
Platform: Android 15 (API 35)
Devices: Multiple (Pixel, Samsung, Xiaomi)
Emulator and physical devices tested
Version information
Solution
- Add this Java class to your project: SoftInputAssist.java
This helper listens for keyboard changes and manually adjusts the layout:
** Open SoftInputAssist.java **
package mi.app.cordova;
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
public class SoftInputAssist {
private final View rootView;
private final View contentView;
private int previousHeight;
public SoftInputAssist(Activity activity) {
rootView = activity.getWindow().getDecorView();
contentView = activity.findViewById(android.R.id.content);
rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int heightDiff = rootView.getHeight() - (r.bottom - r.top);
if (previousHeight != heightDiff) {
previousHeight = heightDiff;
contentView.setPadding(0, 0, 0, heightDiff);
}
});
}
}
** Close SoftInputAssist.java **
2. Call SoftInputAssist from MainActivity.java
Modify your MainActivity like this:
```java
** Open MainActivity.java **
package mi.app.cordova;
import android.os.Bundle;
import org.apache.cordova.*;
public class MainActivity extends CordovaActivity {
private SoftInputAssist softInputAssist;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// enable Cordova apps to be started in the background
Bundle extras = getIntent().getExtras();
if (extras != null && extras.getBoolean("cdvStartInBackground", false)) {
moveTaskToBack(true);
}
// Carga el contenido principal de Cordova
loadUrl(launchUrl);
// Inicializa el listener para el teclado
softInputAssist = new SoftInputAssist(this);
}
}
** Close MainActivity.java **
## Checklist
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
- [x] I searched for existing GitHub issues
- [ x] I updated all Cordova tooling to most recent version
- [ x] I included all the necessary information above
The env(safe-area-inset-top) variable should apply correct top padding to accommodate notches/status bar.
The android webview has never correctly handled safe area inset information, even before API 35. (And yes now they are forcing E2E even though it's broken in webviews).
I'd recommend following and +1 https://issues.chromium.org/issues/396827865 so that the chromium/android webview team and properly prioritize the issue and hopefully get an upstream fix sooner than later. This isn't something that Apache Cordova can really resolve.
There are workarounds such as the one that you've suggested, but it looks like it requires manual manipulation of the app template.
I have a plugin that offers a similar workaround: https://github.com/totalpaveinc/cordova-plugin-insets
It however remains un-opinionated, it just provides a way to listen for inset changes in JS. You can use it directly in JS, or map them to custom CSS variables, whatever works best for your application.
Regarding the adjustResize issue, that might be a completely separate issue to the safe area inset issue.
Thanks breautek, I’ve already given a +1 to https://issues.chromium.org/issues/396827865. For now, with this workaround I’ve been able to solve the keyboard issue, but I had to manually fix the header. Thanks again!
Just want to chime in and say
- This is a very major issue now that mandatory Edge to Edge is almost upon us. Without some way to access the safe insets it's going to be impossible to ship an acceptable Android app for most use cases.
- For now, breautek's plugin is a life-saver (thank you!!!). It was very easy to use it to populate CSS variables for handling the insets appropriately.