378

What's the height of the status bar in Android? Is it always the same?

From my measurements it seems that it's 25dp, but I'm not sure if it has the same height on all platforms.

(I want to know this to properly implement a fade transition from an activity that doesn't have status bar to one that does)

hpique
  • 119,096
  • 131
  • 338
  • 476

23 Answers23

397

this question was answered before... Height of statusbar?

Update::

Current method:

ok, the height of the status bar depends on the screen size, for example in a device with 240 X 320 screen size the status bar height is 20px, for a device with 320 X 480 screen size the status bar height is 25px, for a device with 480 x 800 the status bar height must be 38px

so i recommend to use this script to get the status bar height

Rect rectangle = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
int statusBarHeight = rectangle.top;
int contentViewTop = 
    window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight= contentViewTop - statusBarHeight;

   Log.i("*** Elenasys :: ", "StatusBar Height= " + statusBarHeight + " , TitleBar Height = " + titleBarHeight); 

(old Method) to get the Height of the status bar on the onCreate() method of your Activity, use this method:

public int getStatusBarHeight() { 
      int result = 0;
      int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
          result = getResources().getDimensionPixelSize(resourceId);
      } 
      return result;
} 
Community
  • 1
  • 1
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • Not exactly. I'm also asking if I can assume that the status bar has the same height in all devices. – hpique Aug 04 '10 at 22:19
  • 19
    Or use dip? If it always has 25dip then the code is not needed. – hpique Aug 06 '10 at 12:08
  • 11
    you can't assume it's always 25dp (check out the height for example on the kindle fire). – DallinDyer Jan 18 '12 at 23:12
  • @ hgpc, nop! you have to get the height value – Jorgesys Mar 26 '12 at 19:07
  • does this also work with the action bar and the system bar as introduced on android API11+ ? – android developer Jun 04 '12 at 20:39
  • Re: "the height of the status bar depends on the screen size, for example in a device with 240 X 320 screen size the status bar height is 20px, for a device with 320 X 480 screen size the status bar height is 25px, for a device with 480 x 800 the status bar height must be 38px" - are those just measured pixel values for specific devices having those dimensions? Because since density may vary across devices, those might be the same 25 density-independent pixels times the dpi / 160 (standard density). E.g., a device having a dpi of 240 would have a status bar of 25 * (240/160) = 38 – Carl Dec 10 '12 at 21:13
  • 1
    Doesn't work in runnable passed to view.post() in onCreate() - return 0 – User Apr 19 '13 at 20:24
  • the result is in px ? – Paul Jul 14 '13 at 13:34
  • @Paul, yes in in Pixels. – Jorgesys Jul 14 '13 at 15:17
  • In a `View.post(new Runnable(){})`, this is resulting in the line `int titleBarHeight = contentViewTop - statusBarHeight;` computing to `0 = 75 - 75` for me. – MeanderingCode Aug 29 '14 at 15:34
  • If you want to account for fullscreen implementations in your code, you'll perhaps want to check for the system ui visibility flag: `(decorView.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN` – Dallas Jun 16 '15 at 15:18
  • A device with 720 X 1280 (xhdpi) screen size has the status bar of height 50px. – Chintan Shah May 18 '16 at 11:15
  • isn't the statusbar top above the contenttop??? should be... int titleBarHeight= statusBarHeight - contentViewTop; i'm bad at math and all but... – me_ Dec 15 '16 at 17:00
  • @me_ left top is the origin, meaning that value of contentViewTop is more than statusBarHeight. – Sabeeh Jul 13 '17 at 04:34
  • @Jorgesys I have concerns regarding accuracy of your answer. `contentViewTop` is actually the height of `Toolbar` itself, so no need to subtract anything. `(@id/content).getTop()` returns the top relative to its parent and only child above the `@id/content` is the `toolbar` (`status bar` is not the child in current parent). Hence the value returned by `window.findViewById(Window.ID_ANDROID_CONTENT).getTop()` is in fact the toolbar height. I've verified this in emulator. Please correct me, if i am wrong. – Sabeeh Jul 13 '17 at 05:10
  • 9
    `window.getDecorView().getWindowVisibleDisplayFrame(rectangle)` is not a correct way to get status bar height if you are in multi-window mode + portrait rotation + second window. You will get a huge value (include the 1st height). – Tuan Chau Jun 07 '18 at 07:40
  • In Multi-Window (Resizeable activity), the new method not works properly. Better one is the old method. – HF_ Feb 06 '19 at 15:37
  • Updated answer is quite good. The only thing I would change is ```statusBarHeight``` to ```statusBarTop``` – Leo DroidCoder Jul 01 '19 at 14:12
234

Out of all the code samples I've used to get the height of the status bar, the only one that actually appears to work in the onCreate method of an Activity is this:

public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

Apparently the actual height of the status bar is kept as an Android resource. The above code can be added to a ContextWrapper class (e.g. an Activity).

Found at http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Ben Clayton
  • 80,996
  • 26
  • 120
  • 129
  • Instead of hard coding it, better to calculate dynamically. The above method worked for me! – alchemist Jul 05 '13 at 07:20
  • shouldn't you use getDimension(...) instead ? – android developer Nov 19 '13 at 15:04
  • 8
    A word of caution - this does not work on all devices. E.g. on Transformer TF201 (as well as TF101, TF300 and some other devices) the height is reported as 25 where there is no status bar. – Błażej Czapp Nov 28 '13 at 12:15
  • 4
    Based on the comments above, it seems to me that the code is telling you what the height of the status bar is on a particular device -- not what it is on a particular activity (which may not actually have a status bar). – dazed Dec 15 '15 at 13:04
  • 1
    in XML the dimen resource "@android:dimen/status_bar_height" can be used. 24dp. But you can not direct reference it in your app project. So you must used code. – Tshunglee Dec 12 '18 at 06:45
66

Hardcoding the size or using reflection to get the value of status_bar_height is considered bad practice. Chris Banes talked about this in at the Droidcon New York. The recommended way of getting the status bar size is via the OnApplyWindowInsetsListener:

myView.setOnApplyWindowInsetsListener { view, insets -> {
  val statusBarSize = insets.systemWindowInsetTop
  return insets
}

This was added in API 20 and is also backported via ViewAppCompat.

Niklas
  • 23,674
  • 33
  • 131
  • 170
  • This is the most accurate answer today – keith Feb 05 '18 at 21:46
  • for me this only fires once, If I have fragments via bottom nav. If I replace the fragment again, this listener doesnt get called, is there a compat getter aswell? – urSus Mar 11 '18 at 02:51
  • 143
    And yet this API is horrible, because the number of WTF/Gotchas behind the scenes is huge. You’d think that you can do it with any view, but no, you need to override certain things and ensure YOU pass the insets to your children (??) because SOME ViewGroups will (material design) and ALL OTHERS won’t (linear layout? ConstraintLayout? hello?). Instead of the system having a Window.getStatusBarSize()… we have to SUBSCRIBE TO A FREAKING LISTENER… go home Android, you’re drunk. Just hardcode the size until Google wakes up, we’re in 2018. I hope Chris Banes sees this one day… – Martin Marconcini Jun 19 '18 at 20:49
  • In my case it is not getting fired. I put it Activity#onCreated. Did I do something wrong? Additionally why do not we use mView.getRootWindowInsets()? – Adil Aliyev Oct 26 '18 at 07:00
  • 1
    You need to call view.onApplyWindowInsets, because otherwise the view's own method won't be called. Moreover, your code is syntactically wrong (misplaced brace, return statement from closure). – digory doo Mar 30 '21 at 05:46
  • 1
    `insets.systemWindowInsetTop` is deprecated now. So the most actual way now how to get statusbar insets today: `val statusbarInsets = insets.getInsets(WindowInsetsCompat.Type.statusBars())` and then `statusbarInsets.top`. Read more about how to handle overlaps using insets when implementing edge-to-edge https://developer.android.com/training/gestures/edge-to-edge#handle-overlaps – sergpetrov Aug 08 '22 at 14:40
51

On MDPI devices, the status bar is 25px. We can use this as the base and multiply it by the density (rounded up) to get the status bar height on any device:

int statusBarHeight = Math.ceil(25 * context.getResources().getDisplayMetrics().density);

For reference: ldpi=.75, mdpi=1, hdpi=1.5, xhdpi=2

Grantland Chew
  • 2,620
  • 26
  • 26
  • 6
    This is correct for devices that *have* a status bar. Note that since the above was written, it became true that not all devices will have one. Specifically, devices running ICS may have a combined status/nav bar at the bottom and nothing at all at the top. So for that case, for most programming purposes, you would want to assign a height of zero to the status bar, but the above formulation would give you a non-zero size. – Carl Dec 12 '12 at 05:11
  • 1
    Also the 25px value is not correct for all mdpi devices. It can vary based on API level. For example, the 10.1 WXGA tablet emulator device reports 25px at API 16 & 19, but 24px at API 24. – jk7 Jul 26 '17 at 20:33
  • Constant usage (like 25) is not work correctly all time, you may try to use https://stackoverflow.com/a/16523854/3341089 solution. – oguzhan Jun 15 '22 at 19:12
39

I've merged some solutions together:

public static int getStatusBarHeight(final Context context) {
    final Resources resources = context.getResources();
    final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0)
        return resources.getDimensionPixelSize(resourceId);
    else
        return (int) Math.ceil((VERSION.SDK_INT >= VERSION_CODES.M ? 24 : 25) * resources.getDisplayMetrics().density);
    }

another alternative:

    final View view = findViewById(android.R.id.content);
    runJustBeforeBeingDrawn(view, new Runnable() {
        @Override
        public void run() {
            int statusBarHeight = getResources().getDisplayMetrics().heightPixels - view.getMeasuredHeight();
        }
    });

EDIT: Alternative to runJustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • getResources().getDisplayMetrics().heightPixels -getActivity().findViewById(android.R.id.content).getMeasuredHeight() not work in android lolipop – abbasalim Sep 02 '15 at 10:08
  • @ArMo372 Updated answer. It's just that the view needs to pass the measurement first. You don't need to use runJustBeforeBeingDrawn if you've passed it already. You will use it only on too-early cases. – android developer Aug 15 '16 at 19:17
33

According to Material Guidance; height of status bar is 24 dp.

If you want get status bar height in pixels you can use below method:

private static int statusBarHeight(android.content.res.Resources res) {
    return (int) (24 * res.getDisplayMetrics().density);
}

which can be called from activity with:

statusBarHeight(getResources());
Rashid
  • 1,515
  • 16
  • 16
25

The default height used to be 25dp. With Android Marshmallow (API 23) the height was reduced to 24dp.

Update: Please be aware that since the age of notches and punch-whole-cameras began, using a static height for the status bar no longer works. Please use window insets instead!

crysxd
  • 3,177
  • 20
  • 32
21

this also work with the refrence link

public int getStatusBarHeight() {
  int result = 0;
  int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
  if (resourceId > 0) {
      result = getResources().getDimensionPixelSize(resourceId);
  }
  return result;
}
Parag Chauhan
  • 35,760
  • 13
  • 86
  • 95
17

Official height is 24dp, as is stated officially by Google on Android Design webpage.

Joaquin Iurchuk
  • 5,499
  • 2
  • 48
  • 64
15

Kotlin version that combines two best solutions

fun getStatusBarHeight(): Int {
    val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
    return if (resourceId > 0) resources.getDimensionPixelSize(resourceId)
    else Rect().apply { window.decorView.getWindowVisibleDisplayFrame(this) }.top
}
  1. Takes status_bar_height value if present
  2. If status_bar_height is not present, calculates the status bar height from Window decor
tomrozb
  • 25,773
  • 31
  • 101
  • 122
  • Is this the correct way to get in status bar height? can you attach the document please. – Tippu Fisal Sheriff Jan 11 '23 at 09:38
  • Ad 1.: Use of this function is discouraged because resource reflection makes it harder to perform build optimizations and compile-time verification of code. – t0m Jan 22 '23 at 18:51
14

I have the same problem of having to get the status bar height in an onCreate. This works for me.

private static final int LOW_DPI_STATUS_BAR_HEIGHT = 19;

private static final int MEDIUM_DPI_STATUS_BAR_HEIGHT = 25;

private static final int HIGH_DPI_STATUS_BAR_HEIGHT = 38;

Inside the onCreate:

DisplayMetrics displayMetrics = new DisplayMetrics();
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);

int statusBarHeight;

switch (displayMetrics.densityDpi) {
    case DisplayMetrics.DENSITY_HIGH:
        statusBarHeight = HIGH_DPI_STATUS_BAR_HEIGHT;
        break;
    case DisplayMetrics.DENSITY_MEDIUM:
        statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
        break;
    case DisplayMetrics.DENSITY_LOW:
        statusBarHeight = LOW_DPI_STATUS_BAR_HEIGHT;
        break;
    default:
        statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
}

See:

http://developer.android.com/reference/android/util/DisplayMetrics.html http://developer.android.com/guide/practices/ui_guidelines/icon_design.html

benhylau
  • 430
  • 5
  • 9
  • 3
    I like your idea of using density-driven values. If you're going to use the code in multiple places (or use other density-related values) I prefer offloading the work to the system, and storing the values in a dimen resource, which makes the switch unnecessary. You do need to create a dimension-specific folder and resource file for each density. final Resources res = context.getResources(); int statusbarHeight = 0; try { statusbarHeight = res.getDimensionPixelSize(R.dimen.android_statusbar_height); } catch (NotFoundException e) {} – ProjectJourneyman Dec 13 '11 at 19:16
  • 5
    Hardcoding these values is dangerous, what if they change in a later platform version? – David Snabel-Caunt Feb 22 '12 at 15:34
  • I think that instead of using hardcoded pixels sizes (one for each density), it's better to use "25dp" . – android developer Mar 10 '15 at 14:04
13

Yes when i try it with View it provides the result of 25px. Here is the whole code :

public class SpinActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout lySpin = new LinearLayout(this);
        lySpin.setOrientation(LinearLayout.VERTICAL);       
        lySpin.post(new Runnable()
        {
            public void run()
            {
                Rect rect = new Rect();
                Window window = getWindow();
                window.getDecorView().getWindowVisibleDisplayFrame(rect);
                int statusBarHeight = rect.top;
                int contentViewTop = 
                    window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
                int titleBarHeight = contentViewTop - statusBarHeight;
                System.out.println("TitleBarHeight: " + titleBarHeight 
                    + ", StatusBarHeight: " + statusBarHeight);
            }
        }
    }
}
avh4
  • 2,635
  • 1
  • 22
  • 25
Braj
  • 131
  • 1
  • 2
  • The above code is working for me when i create a new linear layout as you have done above, but when i do findviewbyid for the lySpin from the xml. then it returns null. not understanding y it is behaving so. – Shaista Naaz Jun 23 '11 at 17:06
  • Because the layout doesn't know its size yet in onCreate because it hasn't finished being drawn. What I usually do is post a Runnable on the UI thread from onCreate which gives the UI time to draw itself. – Jason Robinson Jan 18 '12 at 00:00
9

240x320 - 20px

320x480 - 25px

480x800+ - 38px

Community
  • 1
  • 1
Denis
  • 433
  • 6
  • 14
8

Try this:

    Rect rect = new Rect();
    Window win = this.getWindow();
    win.getDecorView().getWindowVisibleDisplayFrame(rect);
    int statusBarHeight = rect.top;
    int contentViewTop = win.findViewById(Window.ID_ANDROID_CONTENT).getTop();
    int titleBarHeight = contentViewTop - statusBarHeight;
    Log.d("ID-ANDROID-CONTENT", "titleBarHeight = " + titleBarHeight );

it didn't work for me in the onCreate method for the activity, but did when I put it in an onClickListener and gave me a measurement of 25

Martyn
  • 16,432
  • 24
  • 71
  • 104
  • I suspect that at the point he tested in onCreate(), the status bar had not yet been created. By contrast, when he manually clicked to activate his onClickListener() code, the bar had already had plenty of think-type time to display, and he was able to retrieve its size. – Carl May 26 '12 at 11:40
7

the height of the status bar is 24dp in android 6.0

 <!-- Height of the status bar -->
 <dimen name="status_bar_height">24dp</dimen>
 <!-- Height of the bottom navigation / system bar. -->
 <dimen name="navigation_bar_height">48dp</dimen>

you can find the answer in the source code: frameworks\base\core\res\res\values\dimens.xml

xiaoyuan hu
  • 175
  • 2
  • 2
  • 3
    is there a way to get this resource in our XMLs? `@android:dimen/status_bar_height` does not work for me – avalancha Apr 17 '20 at 12:02
6

To solve this, I used a combination approach. This is necessary as on tablets the system bar already subtracts it's pixels when display.getHeight() is called. So I first check if a system bar is present, and then Ben Claytons approach, which works fine on phones.

public int getStatusBarHeight() {
    int statusBarHeight = 0;

    if (!hasOnScreenSystemBar()) {
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
    }

    return statusBarHeight;
}

private boolean hasOnScreenSystemBar() {
    Display display = getWindowManager().getDefaultDisplay();
    int rawDisplayHeight = 0;
    try {
        Method getRawHeight = Display.class.getMethod("getRawHeight");
        rawDisplayHeight = (Integer) getRawHeight.invoke(display);
    } catch (Exception ex) {
    }

    int UIRequestedHeight = display.getHeight();

    return rawDisplayHeight - UIRequestedHeight > 0;
}
Rutger
  • 323
  • 3
  • 8
4

Thanks to @Niklas +1 this is the correct way to do it.

public class MyActivity extends Activity implements android.support.v4.View.OnApplyWindowInsetsListener {

    Rect windowInsets;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity);

        View rootview = findViewById(android.R.id.content);

        android.support.v4.View.ViewCompat.setOnApplyWindowInsetsListener(rootview, this);
    }

    android.support.v4.View.WindowInsetsCompat android.support.v4.View.OnApplyWindowInsetsListener.OnApplyWindowInsets(View v, android.support.v4.View.WindowInsetsCompat insets)
    {
        windowInsets = new Rect();
        windowInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
        //StatusBarHeight = insets.getSystemWindowInsetTop();

        //Refresh/Adjust view accordingly

        return insets;
    }
}

Please excuse me if the code isn't 100% correct, converted it from Xamarin C# but this is the just of it. Works with Notches, etc.

Pierre
  • 8,397
  • 4
  • 64
  • 80
3

Toggled Fullscreen Solution:

This solution may look like a workaround, but it actually accounts for whether your app is fullscreen (aka hiding the status bar) or not:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point(); display.getSize(size);
int barheight = size.y - findViewById(R.id.rootView).getHeight();

This way, if your app is currently fullscreen, barheight will equal 0.

Personally I had to use this to correct absolute TouchEvent coordinates to account for the status bar as so:

@Override
public boolean onTouch(View view,MotionEvent event) {
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point(); display.getSize(size);
    int YCoord = (int)event.getRawY() - size.y + rootView.getHeight());
}

And that will get the absolute y-coordinate whether the app be fullscreen or not.

Enjoy

Aaron Gillion
  • 2,227
  • 3
  • 19
  • 31
3

The reason why the top answer does not work for some people is because you cannot get the dimensions of a view until it is ready to render. Use an OnGlobalLayoutListener to get said dimensions when you actually can:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ViewGroup decorView = (ViewGroup) this.getWindow().getDecorView();
    decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= 16) {
                decorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                // Nice one, Google
                decorView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
            Rect rect = new Rect();
            decorView.getWindowVisibleDisplayFrame(rect);
            rect.top; // This is the height of the status bar
        }
    }
}

This is the most reliable method.

user1112789
  • 437
  • 5
  • 12
3

On Android 4.1 and higher, you can set your application's content to appear behind the status bar, so that the content doesn't resize as the status bar hides and shows. To do this, use SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN. You may also need to use SYSTEM_UI_FLAG_LAYOUT_STABLE to help your app maintain a stable layout.

When you use this approach, it becomes your responsibility to ensure that critical parts of your app's UI (for example, the built-in controls in a Maps application) don't end up getting covered by system bars. This could make your app unusable. In most cases you can handle this by adding the android:fitsSystemWindows attribute to your XML layout file, set to true. This adjusts the padding of the parent ViewGroup to leave space for the system windows. This is sufficient for most applications.

In some cases, however, you may need to modify the default padding to get the desired layout for your app. To directly manipulate how your content lays out relative to the system bars (which occupy a space known as the window's "content insets"), override fitSystemWindows(Rect insets). The fitSystemWindows() method is called by the view hierarchy when the content insets for a window have changed, to allow the window to adjust its content accordingly. By overriding this method you can handle the insets (and hence your app's layout) however you want.

form: https://developer.android.com/training/system-ui/status.html#behind

xiaoyuan hu
  • 175
  • 2
  • 2
3

Since multi-window mode is available now, your app may not have statusbar on top.

Following solution handle all the cases automatically for you.

android:fitsSystemWindows="true"

or programatically

findViewById(R.id.your_root_view).setFitsSystemWindows(true);

you may also get root view by

findViewById(android.R.id.content).getRootView();
or
getWindow().getDecorView().findViewById(android.R.id.content)

For more details on getting root-view refer - https://stackoverflow.com/a/4488149/9640177

Mayank Kumar Chaudhari
  • 16,027
  • 10
  • 55
  • 122
2

If you know exactly the size VS height

like

for example in a device with 320 X 480 screen size the status bar height is 25px, for a device with 480 x 800 the status bar height must be 38px

then you can just get the width of your view / the screen size you can just use an if else statement to get the height of status bar

Steven Shih
  • 645
  • 1
  • 10
  • 22
  • In my experience, the height appears to be based upon density rather than screen size. Of course, density itself is typically related to screen size, so there is an indirect relationship. My old Moto Droid, for example, has a 480x854 (rather than 480x800) display, and the status bar is also 38 pixels high. – Carl May 26 '12 at 22:00
  • They invented dp for this (density independant pixels) – Roel Oct 29 '14 at 12:29
1

This issue recently became relevant for me because of the notch in my Pixel 3XL. I really liked android developer's solution, but I wanted to be able to get the status bar height at will, since it was specifically necessary for a full screen animation that I needed to play. The function below enabled a reliable query:

private val DEFAULT_INSET = 96
fun getInsets(view: View?): Int {
     var inset = DEFAULT_INSET
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//Safe because only P supports notches
          inset = view?.rootWindowInsets?.stableInsetTop ?: DEFAULT_INSET
     }
     return inset
}

fun blurView(rootView: View?, a: SpacesActivity?) {
    val screenBitmap = getBitmapFromView(rootView!!)
    val heightDifference = getInsets(rootView)
    val croppedMap = Bitmap.createBitmap(
                    screenBitmap, 0, heightDifference,
                    screenBitmap.width,
                    screenBitmap.height - heightDifference)
    val blurredScreen = blurBitmap(croppedMap)
    if (blurredScreen != null) {
         val myDrawable = BitmapDrawable(a!!.resources, blurredScreen)
         a.errorHudFrameLayout?.background = myDrawable
         a.appBarLayout?.visibility = View.INVISIBLE
   }
}

And then in the activity class:

fun blurView() {
    this.runOnUiThread {
        Helper.blurView(this)
    }
}

You will of course want to make pass a weak reference of the activity to the static Helper class method parameter, but for the sake of brevity I refrained in this example. The blurBitmapand errorHudFrameLayout are omitted for the same reason, since they don't directly pertain to obtaining the height of the status bar.

James Jordan Taylor
  • 1,560
  • 3
  • 24
  • 38