[Hot-bug ]:Android SafeAreaProvider Top Edge Not Working on Android 15+ Devices (e.g., Samsung S21 Ultra, OnePlus 11R)
Description
On newer Android devices running Android 15 and above, the react-native-safe-area-context SafeAreaProvider's top inset does not correctly account for the status bar and display cutouts (notches). This results in UI content overlapping the status bar or the device's notch area, especially on devices like Samsung Galaxy S21 Ultra and OnePlus 11R.
#633
Details : info Fetching system and libraries information... System: OS: macOS 15.3.1 CPU: (8) arm64 Apple M2 Memory: 130.59 MB / 8.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 22.14.0 path: ~/.nvm/versions/node/v22.14.0/bin/node Yarn: version: 3.6.4 path: ~/.yarn/bin/yarn npm: version: 10.9.2 path: ~/.nvm/versions/node/v22.14.0/bin/npm Watchman: version: 2025.04.28.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.16.2 path: /Users/mac/.gem/ruby/3.4.0/bin/pod SDKs: iOS SDK: Platforms: - DriverKit 24.4 - iOS 18.4 - macOS 15.4 - tvOS 18.4 - visionOS 2.4 - watchOS 11.4 Android SDK: API Levels: - "33" - "34" - "35" Build Tools: - 33.0.1 - 34.0.0 - 35.0.0 - 35.0.1 System Images: - android-29 | Google APIs ARM 64 v8a - android-35 | Google APIs ARM 64 v8a - android-35 | Google Play ARM 64 v8a Android NDK: Not Found IDEs: Android Studio: 2024.2 AI-242.23726.103.2422.13016713 Xcode: version: 16.3/16E140 path: /usr/bin/xcodebuild Languages: Java: version: 17.0.14 path: /usr/bin/javac Ruby: version: 3.4.2 path: /opt/homebrew/opt/ruby/bin/ruby npmPackages: "@react-native-community/cli": installed: 18.0.0 wanted: 18.0.0 react: installed: 19.0.0 wanted: 19.0.0 react-native: installed: 0.79.2 wanted: 0.79.2 react-native-macos: Not Found npmGlobalPackages: "react-native": Not Found Android: hermesEnabled: true newArchEnabled: true iOS: hermesEnabled: true newArchEnabled: true
Steps to reproduce
Install apk in Android 15 +
Snack or a link to a repository
https://stackoverflow.com/questions/79638900/android-safeareaprovider-top-edge-not-working-on-android-15-devices-e-g-sams
Safe Area Context version
5.4.1
React Native version
0.79.2
Platforms
Android
Architecture
Fabric (New Architecture)
Build type
None
Device
Real device
Device model
oneplus 11 r , samsung 21 ultra , Android Emulator - Pixel_9_Pro_XL_AP|_35:5554
Acknowledgements
Yes
temporary solution, you can add windowOptOutEdgeToEdgeEnforcement in styles.xml this option will be removed later in Android 16 (https://developer.android.com/about/versions/16/behavior-changes-16#edge-to-edge)
thanks did the trick
const isAndroid15 = Platform.OS == 'android' && Platform.Version >= 35
return (
<SafeAreaProvider
style={
isAndroid15
? {
marginBottom: initialWindowMetrics?.insets.bottom,
}
: {}
}>
Cannot reproduce it using both the latest image of the Android 15 emulator, or a physical device running Android 15 (a Pixel 8).
"react-native-edge-to-edge": "1.6.1"
"react-native-safe-area-context": "5.5.0"
export const App = () => (
<SafeAreaProvider>
<SafeAreaView style={{ backgroundColor: "red", flex: 1 }}>
<View style={{ backgroundColor: "green", flex: 1 }} />
</SafeAreaView>
</SafeAreaProvider>
);
- 1 same issue, if you run same code on 13 android and 15
Faced the same problem on Android 15+. So far the solution for me was to add padding using insets data:
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
export const App = () {
const insets = useSafeAreaInsets()
return (
<SafeAreaProvider>
<View style={{
paddingBottom: insets.bottom,
paddingTop: insets.top,
}}>
<View/>
</View>
</SafeAreaProvider>
)};
When navigation is used, the padding has to be applied on the screens.
Same here, using react-native-safe-area-context 5.0.0 and targetSDKVersion 35
Android 12:
Android 15:
When using targetSDKVersion 34 the problem disappears but PlayStore requires app segmentation to 35
doesnt work to me
same problem,
<style name="OptOutEdgeToEdgeEnforcement">
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
in styes.xml worked for now.
same problem,
<style name="OptOutEdgeToEdgeEnforcement"> <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item> </style>in styes.xml worked for now.
but in android 16. we can not use it any more. @chr4ss1 what can we do right now? :(
@ngocdinhalobridge just to clarify, as long as you target API level 35 (which I do), this fix will continue to work for Android 16 devices too. The problem will probably come around August next year when Android wants everyone to target API level 36 but by then this would be fixed for sure. If you need to target API level 36 right now, I am not sure what the solution is.
Can we can a timeline on when this bug will be fixed? New versions of React Native use api 36, but this bug makes those versions unusable. Using the insets doesn't seem to work well especially when switching from portrait to landscape.
Hello everyone 👋 I finally found a solution to enable edge-to-edge support in my React Native app! 🎉
I’ve written a step-by-step guide here: https://medium.com/@ajprince0607/android-edge-to-edge-supportreact-native-app-966c8f80803c
doesnt work to me 对我不起作用
我也是 请问你现在解决了吗?
same problem,
<style name="OptOutEdgeToEdgeEnforcement"> <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item> </style>in styes.xml worked for now.
but in android 16. we can not use it any more. @chr4ss1 what can we do right now? :(
![]()
Hi everyone, what worked for me was adding the following inside my styles.xml on Android:
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
Since I’m using Expo, I had to create a plugin to insert this tag. The local build worked perfectly, but for some reason the Expo build didn’t apply the tag (or maybe the solution just didn’t take effect — I’m not sure why). In the end, I generated the bundle manually and uploaded it to the Play Store.
same problem,
<style name="OptOutEdgeToEdgeEnforcement"> <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item> </style>in styes.xml worked for now.
but in android 16. we can not use it any more. @chr4ss1 what can we do right now? :(
![]()
Hi everyone, what worked for me was adding the following inside my styles.xml on Android:
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>Since I’m using Expo, I had to create a plugin to insert this tag. The local build worked perfectly, but for some reason the Expo build didn’t apply the tag (or maybe the solution just didn’t take effect — I’m not sure why). In the end, I generated the bundle manually and uploaded it to the Play Store.
windowOptOutEdgeToEdgeEnforcement only works on Android 15, not Android 16.
Facing the same issue on the Pixel 8 device(Android version:15). react-native-safe-area-context: 5.4.0 react: 19.0.0 react-native: 0.79.2
export default function RootLayout() {
const [themeMode, setThemeMode] = useState<ThemeMode>('light');
const getCurrentTheme = () => {
if (themeMode === 'highContrast') {
return HighContrastTheme;
}
return DefaultTheme;
};
const currentTheme = getCurrentTheme();
// Inner component to access insets
const LayoutWithInsets = () => {
const insets = useSafeAreaInsets();
return (
<View style={{ flex: 1, paddingBottom: Math.max(insets.bottom, 16) }}>
<Stack>
<Stack.Screen name="index" options={{ headerShown: false }} />
<Stack.Screen name="camera" options={{ headerShown: false }} />
<Stack.Screen name="Reading" options={{ headerShown: false }} />
<Stack.Screen name="profile" options={{ headerShown: false }} />
<Stack.Screen name="hello-world" options={{ headerShown: false }} />
<Stack.Screen name="propertydetails" options={{ headerShown: false }} />
<Stack.Screen name="property/[propertyId]" options={{ headerShown: false }} />
<Stack.Screen name="modal" options={{ presentation: 'modal', headerShown: false }} />
<Stack.Screen name="properties" options={{ headerShown: false }} />
</Stack>
</View>
);
};
return (
<ThemeContext.Provider value={{ themeMode, setThemeMode, theme: currentTheme }}>
<AuthProvider>
<ReadingSettingsProvider>
<RoutingProvider>
<ThemeProvider value={currentTheme}>
<SafeAreaProvider>
<LayoutWithInsets />
</SafeAreaProvider>
<StatusBar style={themeMode === 'highContrast' ? 'light' : 'dark'} />
</ThemeProvider>
</RoutingProvider>
</ReadingSettingsProvider>
</AuthProvider>
</ThemeContext.Provider>
);
}
Here is my _layout.tsx file. Wrapping the stack in a View with the correct insets for where you are experiencing the overlap, whether it be padding top or padding bottom, fixes the issue for me on Android.
You could try using this. https://www.npmjs.com/package/react-native-navbar-listener