Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StatusBar.currentHeight gives incorrect height on Google Pixel 5a (Android 12) #33612

Open
ly-martin opened this issue Apr 11, 2022 · 26 comments
Labels
Component: StatusBar Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project. Needs: Author Feedback Needs: Triage 🔍 Platform: Android Android applications. Type: Unsupported Version Issues reported to a version of React Native that is no longer supported

Comments

@ly-martin
Copy link

Description

StatusBar.currentHeight provides an incorrect value for the height of the status bar on a Google Pixel 5a with Android 12. From basic testing, this does not seem to be an issue on other devices or on an older OS (Android 11)

Screenshot when using StatusBar.currentHeight as the top margin

Expected:
Screen Shot 2022-04-11 at 2 43 54 PM

Version

0.66.0

Output of npx react-native info

example on Expo, this is occurring in multiple versions of react native, notably tested on 0.66.0 and 0.64.2

Steps to reproduce

  1. use StatusBar.currentHeight
  2. compare calculated height on Google Pixel 5a (Android 12) to other Android devices - the height for Pixel 5a Android 12 does not match the full height as it appears on the device while other devices do still work

Snack, code example, screenshot, or link to a repository

https://snack.expo.dev/qXx7COUDg

@cristianoccazinsp
Copy link
Contributor

Not just Pixel 5a, but many devices that may have a notch.

@markholland
Copy link

This started happening for me on my Pixel 4a after the 5 March 2022 Android security update. Before this it was not an issue on Android 12 for me.

@Javierd
Copy link

Javierd commented Apr 26, 2022

I'm also running into this issue

@julienR2
Copy link

Our users also experiences this issue in our app running on an Android 12. After looking a bit around, this is probably not a React Native issue, but most likely a Android 12 issue.

It seems they when through their beta without realising that the native function returning the status bar height, was giving back a wrong value/

Hopefully Android 12 issues a fix soon, in the meantime you'll have to either:

  • add an exception when getting StatusBar.currentHeight when running on Android 12 (although I didn't manage to find the precise height of this Status Bar)
  • wait for an Android fix..
  • some other solution I haven't think of ?

@shmkane
Copy link

shmkane commented May 23, 2022

Bump? Has anyone found a solution for this?

@cristianoccazinsp
Copy link
Contributor

For me, StatusBar ended up being totally unreliable. The only thing that worked was to listen to layout events with a root view; however, that also needed extra care with the keyboard height on android which also needs to be listened to so the screen height is compensated.

@shmkane
Copy link

shmkane commented May 23, 2022

For me, StatusBar ended up being totally unreliable. The only thing that worked was to listen to layout events with a root view; however, that also needed extra care with the keyboard height on android which also needs to be listened to so the screen height is compensated.

Would you be willing to share your implantation for this. Me and others who stumble on this would appreciate it 🙂

@cristianoccazinsp
Copy link
Contributor

It's actually a really ugly work around, shouldn't really share something that ugly!.

Either way, the idea is simple:

  • Wrap your app in a <View this.onRootLayout>....</View> or similar
  • On the onRootLayout just set a global variable, something like:
      let kbHeight = IS_ANDROID
        ? global.keyboardVisible?.endCoordinates?.height
        : 0;
      global.Dimensions = {
        width: e.nativeEvent.layout.width,
        height: e.nativeEvent.layout.height + (kbHeight ? kbHeight : 0),
      };
  • You will notice I'm also globally listening to the keyboard and setting it in another global variable with Keyboard.addListener so for Android I can add the keyboard height as the layout height would otherwise not include it.
  • Lastly, the status bar height could be just the difference between this calculated height and the original's Dimensions height.

@julienR2
Copy link

julienR2 commented May 24, 2022

We ended up using react-native-safe-area-context which were luckily already using (I hate adding lib to palliate a bug in a native function)..

It gives the insets of the devices, with the correct value for the top inset (the status bar). They probably don't rely on StatusBar.currentHeight, but on the native function instead, which makes it perfectly reliable.

It also enforces a better usage of this value which can actually change when rotating the screen. So we shouldn't get it statically, but react to its changes instead. And react-native-safe-area-context provides the tools for it.

Again, not the best solution as it requires to add a lib, but at least the lib provides the right values !

Hope it can help until it's fix on React-Native side !

@JosephVasse
Copy link

We ended up using react-native-safe-area-context which were luckily already using (I hate adding lib to palliate a bug in a native function)..

It gives the insets of the devices, with the correct value for the top inset (the status bar). They probably don't rely on StatusBar.currentHeight, but on the native function instead, which makes it perfectly reliable.

It also enforces a better usage of this value which can actually change when rotating the screen. So we shouldn't get it statically, but react to its changes instead. And react-native-safe-area-context provides the tools for it.

Again, not the best solution as it requires to add a lib, but at least the lib provides the right values !

Hope it can help until it's fix on React-Native side !

Do you have any code snippet that you could share ? I tried to use react-native-safe-area-context (SafeAreaProvider & SafeAreaView) but it does not seems to work

Thanks

@julienR2
Copy link

julienR2 commented Jun 9, 2022

Hi !
We quick fixed it statically until we have time to tackle it properly or it gets fixed. It look like this:

import { initialWindowMetrics } from 'react-native-safe-area-context'
import { hasNotch } from 'react-native-device-info'

const getStatusBarHeight = () => {
  if (isIos) {
    return hasNotch() ? 44 : 20
  }
  return initialWindowMetrics?.insets.top || 0
}

The initialWindowMetrics?.insets.top actually returns the correct insets. (Obviously it would be better to use a useInsets and the context to be sure to have it updated in case it change dynamically)

Let me know if it's unclear !

@jordimas96
Copy link

I'm programming an app with Android Studio and testing it in a virtual Pixel 6, and the functions to get statusbar height return something like 60px, but the real bar is at least 125px

@julienR2
Copy link

julienR2 commented Feb 8, 2023

Arf that's annoying when we can't rely on this value.. Specially on Android were there's a big range of different devices.

Does getStatusbar return always this same value ? If you run the function later, in a useEffect, or delayed in some way, does it still return the wrong value ?

Also side discovery, in android developer option, you can simulate different status bar height: search for Display cutout in the developer options, which let you simulate a notch, and different kind of cutout affecting the status bar height. Practical to debug on real device.

@jordimas96
Copy link

jordimas96 commented Feb 8, 2023

Sizes in Pixel 6 are (measured from a screenshot):
StatusBar: 136px
NavBar (pill): 42px

My functions to get them are:

fun getStatusBarHeight(): Int {
    val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
    return if (resourceId > 0) resources.getDimensionPixelSize(resourceId) else 0
}

fun getNavigationBarHeight(): Int {
    val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
    return if (resourceId > 0) resources.getDimensionPixelSize(resourceId) else 0
}

But they return 63 and 42. I assume with a navbar (not the pill) the result would be correct too, so the main problem here is the statusbar.

I knew the Pixel 3XL had a huge notch (from a internet screenshot I calculated it was less than 140px).
For the moment I put this code:

if (Build.MANUFACTURER == "Google") lp.topMargin = -140;

That assigns the value as if it was 140, in case it's a Pixel. It would be amazing to get the exact value but it's not strictly necessary for my app. I just needto set the exact value or bigger, so this makes the trick in Pixels, for now.

@jordimas96
Copy link

jordimas96 commented Feb 8, 2023

Well finally I managed to get the exact value, using some deprecated functions. What I did was detect the full screen height (2400) and supress the innerheight (2222) from it and the navbar too (42) so I ended with the long awaited 136.

EDIT: Turns out this method only worked on Pixels, so the final result is a mix of those 2:

fun getStatusBarHeight(): Int {
    // Per a Pixels //
    val displayMetrics = DisplayMetrics()
    windowManager.defaultDisplay.getMetrics(displayMetrics)
    val innerHeight = displayMetrics.heightPixels
    windowManager.defaultDisplay.getRealMetrics(displayMetrics)
    val height = displayMetrics.heightPixels
    val statusbarHeight = height - (innerHeight + getNavigationBarHeight());

    if (statusbarHeight > 0) {
        return statusbarHeight;
    } else {
        // Per a no Pixels //
        val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
        return if (resourceId > 0) resources.getDimensionPixelSize(resourceId) else 0
    }
}

fun getNavigationBarHeight(): Int {
    val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
    return if (resourceId > 0) resources.getDimensionPixelSize(resourceId) else 0
}

@kelset kelset added the Type: Unsupported Version Issues reported to a version of React Native that is no longer supported label Feb 9, 2023
@github-actions
Copy link

github-actions bot commented Feb 9, 2023

It looks like your issue or the example you provided uses an unsupported version of React Native. Due to the amount of issues we receive, we're currently accepting only new issues against one of the supported version. Please open your issue on StackOverflow to get further community support.

@edstbbz
Copy link

edstbbz commented Feb 23, 2023

`
Working solution for API 29+
It was with this version that Google introduced edge-to-edge

public void getStatusBarHeight(Promise promise) {

    final Activity curActivity = getCurrentActivity();
    if (curActivity == null) {
        return;
    }

    int topInset = 0;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        View decorView = getCurrentActivity().getWindow().getDecorView();
        WindowInsets windowInsets = decorView.getRootWindowInsets();
        Insets insets;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            insets = windowInsets.getInsets(WindowInsets.Type.statusBars());
            topInset = insets.top;
        } else {
            topInset = windowInsets.getSystemWindowInsetTop();
        }

        Rect visibleRect = new Rect();
        decorView.getGlobalVisibleRect(visibleRect);
        final float height =
                topInset > 0
                        ?  PixelUtil.toDIPFromPixel(Math.max(topInset - visibleRect.top, 0))
                        : 0;
        promise.resolve(height);
    } else {
        promise.resolve(topInset);
    }
}`

@github-actions
Copy link

This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

@github-actions github-actions bot added Stale There has been a lack of activity on this issue and it may be closed soon. and removed Stale There has been a lack of activity on this issue and it may be closed soon. labels Mar 19, 2023
@github-actions
Copy link

This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Apr 12, 2023
@github-actions
Copy link

This issue was closed because the author hasn't provided the requested feedback after 7 days.

@artemis-prime
Copy link

artemis-prime commented May 31, 2023

Stop auto closing these! This is a bug! And why doesn't the RN team respond to something like this?

@its-clem-fandango
Copy link

its-clem-fandango commented Jan 23, 2024

still an issue. anyone figure it out?

@rahulthakurtorum
Copy link

Getting the Incorrect Status bar height on Google pixel 4a

@tonynecula
Copy link

still an issue, managed to find a workaround:

import { Platform, NativeModules } from 'react-native';
const { StatusBarManager } = NativeModules;

const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? 20 : StatusBarManager.HEIGHT;

@Abbondanzo Abbondanzo reopened this May 16, 2024
@github-actions github-actions bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label May 17, 2024
@Abbondanzo Abbondanzo added the Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project. label May 20, 2024
Abbondanzo pushed a commit to Abbondanzo/react-native that referenced this issue May 28, 2024
Summary:
Google has discouraged attempting to read the `status_bar_height` resource [since 2017](https://youtu.be/_mGDMVRO3iE?si=qGQd7gLa_qTmfLGL&t=1079). With the introduction of display cutouts there can be a mismatch between the resource value and the true status bar size (and issues like [this one](facebook#33612) popped up). The recommended approach is to instead call `getInsets` with the proper status bar and navigation flags provided by `WindowInsets`. On older APIs where `getInsets` is not supported, we have access to `systemWindowInsetTop`.

Changelog:
[Android][Fixed] - Fixed StatusBar.currentHeight calculations to honor all cutout sizes

Differential Revision: D57878119
Abbondanzo pushed a commit to Abbondanzo/react-native that referenced this issue May 30, 2024
Summary:

Google has discouraged attempting to read the `status_bar_height` resource [since 2017](https://youtu.be/_mGDMVRO3iE?si=qGQd7gLa_qTmfLGL&t=1079). With the introduction of display cutouts there can be a mismatch between the resource value and the true status bar size (and issues like [this one](facebook#33612) popped up). The recommended approach is to instead call `getInsets` with the proper status bar and navigation flags provided by `WindowInsets`. On older APIs where `getInsets` is not supported, we have access to `systemWindowInsetTop`.

Changelog:
[Android][Fixed] - Fixed StatusBar.currentHeight calculations to honor all cutout sizes

Reviewed By: alanleedev

Differential Revision: D57878119
@Abbondanzo Abbondanzo linked a pull request May 31, 2024 that will close this issue
@Abbondanzo
Copy link
Contributor

👋 I've put a fix in #44697 that relies on window insets to determine status bar height, rather than reading from a potentially mismatched resource value. This should make its way into 0.75

facebook-github-bot pushed a commit that referenced this issue May 31, 2024
Summary:
Pull Request resolved: #44697

Google has discouraged attempting to read the `status_bar_height` resource [since 2017](https://youtu.be/_mGDMVRO3iE?si=qGQd7gLa_qTmfLGL&t=1079). With the introduction of display cutouts there can be a mismatch between the resource value and the true status bar size (and issues like [this one](#33612) popped up). The recommended approach is to instead call `getInsets` with the proper status bar and navigation flags provided by `WindowInsets`. On older APIs where `getInsets` is not supported, we have access to `systemWindowInsetTop`.

Changelog:
[Android][Fixed] - Fixed StatusBar.currentHeight calculations to honor all cutout sizes

Reviewed By: cipolleschi, alanleedev

Differential Revision: D57878119

fbshipit-source-id: 9fadd33d5f9b617a70a052c98dbd53fd29281650
@julienR2
Copy link

julienR2 commented Jun 3, 2024

Thanks for tackling this long-lasting issue @Abbondanzo 🙌

Abbondanzo pushed a commit to Abbondanzo/react-native that referenced this issue Jun 5, 2024
Summary:
Google has discouraged attempting to read the `status_bar_height` resource [since 2017](https://youtu.be/_mGDMVRO3iE?si=qGQd7gLa_qTmfLGL&t=1079). With the introduction of display cutouts there can be a mismatch between the resource value and the true status bar size (and issues like [this one](facebook#33612) popped up). The recommended approach is to instead call `getInsets` with the proper status bar and navigation flags provided by `WindowInsets`. On older APIs where `getInsets` is not supported, we have access to `systemWindowInsetTop`.

Changelog:
[Android][Fixed] - Fixed StatusBar.currentHeight calculations to honor all cutout sizes

Differential Revision: D58088036
Abbondanzo pushed a commit to Abbondanzo/react-native that referenced this issue Jun 5, 2024
Summary:

Google has discouraged attempting to read the `status_bar_height` resource [since 2017](https://youtu.be/_mGDMVRO3iE?si=qGQd7gLa_qTmfLGL&t=1079). With the introduction of display cutouts there can be a mismatch between the resource value and the true status bar size (and issues like [this one](facebook#33612) popped up). The recommended approach is to instead call `getInsets` with the proper status bar and navigation flags provided by `WindowInsets`. On older APIs where `getInsets` is not supported, we have access to `systemWindowInsetTop`.

Changelog:
[Android][Fixed] - Fixed StatusBar.currentHeight calculations to honor all cutout sizes

Differential Revision: D58088036
Abbondanzo pushed a commit to Abbondanzo/react-native that referenced this issue Jun 6, 2024
Summary:

Google has discouraged attempting to read the `status_bar_height` resource [since 2017](https://youtu.be/_mGDMVRO3iE?si=qGQd7gLa_qTmfLGL&t=1079). With the introduction of display cutouts there can be a mismatch between the resource value and the true status bar size (and issues like [this one](facebook#33612) popped up). The recommended approach is to instead call `getInsets` with the proper status bar and navigation flags provided by `WindowInsets`. On older APIs where `getInsets` is not supported, we have access to `systemWindowInsetTop`.

Changelog:
[Android][Fixed] - Fixed StatusBar.currentHeight calculations to honor all cutout sizes

Reviewed By: tdn120

Differential Revision: D58088036
facebook-github-bot pushed a commit that referenced this issue Jun 10, 2024
Summary:
Pull Request resolved: #44805

Google has discouraged attempting to read the `status_bar_height` resource [since 2017](https://youtu.be/_mGDMVRO3iE?si=qGQd7gLa_qTmfLGL&t=1079). With the introduction of display cutouts there can be a mismatch between the resource value and the true status bar size (and issues like [this one](#33612) popped up). The recommended approach is to instead call `getInsets` with the proper status bar and navigation flags provided by `WindowInsets`. On older APIs where `getInsets` is not supported, we have access to `systemWindowInsetTop`.

Changelog:
[Android][Fixed] - Fixed StatusBar.currentHeight calculations to honor all cutout sizes

Reviewed By: tdn120

Differential Revision: D58088036

fbshipit-source-id: 9c035a79cbb96db1cf3b5b5c36242df7453fe205
kosmydel pushed a commit to kosmydel/react-native that referenced this issue Jun 11, 2024
Summary:
Pull Request resolved: facebook#44697

Google has discouraged attempting to read the `status_bar_height` resource [since 2017](https://youtu.be/_mGDMVRO3iE?si=qGQd7gLa_qTmfLGL&t=1079). With the introduction of display cutouts there can be a mismatch between the resource value and the true status bar size (and issues like [this one](facebook#33612) popped up). The recommended approach is to instead call `getInsets` with the proper status bar and navigation flags provided by `WindowInsets`. On older APIs where `getInsets` is not supported, we have access to `systemWindowInsetTop`.

Changelog:
[Android][Fixed] - Fixed StatusBar.currentHeight calculations to honor all cutout sizes

Reviewed By: cipolleschi, alanleedev

Differential Revision: D57878119

fbshipit-source-id: 9fadd33d5f9b617a70a052c98dbd53fd29281650
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: StatusBar Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project. Needs: Author Feedback Needs: Triage 🔍 Platform: Android Android applications. Type: Unsupported Version Issues reported to a version of React Native that is no longer supported
Projects
None yet
Development

Successfully merging a pull request may close this issue.

17 participants