1960

I created some custom elements, and I want to programmatically place them to the upper right corner (n pixels from the top edge and m pixels from the right edge). Therefore I need to get the screen width and screen height and then set position:

int px = screenWidth - m;
int py = screenHeight - n;

How do I get screenWidth and screenHeight in the main Activity?

Samet ÖZTOPRAK
  • 3,112
  • 3
  • 32
  • 33
Niko Gamulin
  • 66,025
  • 95
  • 221
  • 286
  • Use dp instead of px. because it will distort your layout with other devices.. – Zar E Ahmer Apr 24 '14 at 06:13
  • Don't forget to multiply by getResources().getDisplayMetrics().density to account for display scaling – jmaculate Jun 16 '14 at 12:53
  • This proves the most up-voted answer is not always the best (& lots of people repeat answers for rep). Instead of getSize and deprecated getWidth/getHeight combo (ignoring errors), try Balaji.K's `getMetrics`. Nik's comment in his answer even explains `getDisplayMetrics` to consider the system/status bar size. Also you may use __density__ as jmaculate and LoungeKatt explained to have the __EXACT__ value:`DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels;` Tested in Android v2.2 (API 8) and v4.0 with good results and **no errors/warnings**. – Armfoot Sep 02 '14 at 10:32
  • DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels; – Azahar May 01 '15 at 05:30
  • another way to get the DisplayMetrics : `Resources.getSystem().getDisplayMetrics()`. You won't need a `Context` to get them. – Täg Feb 08 '19 at 08:56

46 Answers46

3566

For API Level 30, WindowMetrics.getBounds is to be used. An example of its usage can be found in the linked docs:

 final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
 // Gets all excluding insets
 final WindowInsets windowInsets = metrics.getWindowInsets();
 Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
         | WindowInsets.Type.displayCutout());

 int insetsWidth = insets.right + insets.left;
 int insetsHeight = insets.top + insets.bottom;

 // Legacy size that Display#getSize reports
 final Rect bounds = metrics.getBounds();
 final Size legacySize = new Size(bounds.width() - insetsWidth,
         bounds.height() - insetsHeight);

Old answer:

If you want the display dimensions in pixels you can use getSize:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

If you're not in an Activity you can get the default Display via WINDOW_SERVICE:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

If you are in a fragment and want to acomplish this just use Activity.WindowManager (in Xamarin.Android) or getActivity().getWindowManager() (in java).

Before getSize was introduced (in API level 13), you could use the getWidth and getHeight methods that are now deprecated:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();  // deprecated
int height = display.getHeight();  // deprecated

For the use case, you're describing, however, a margin/padding in the layout seems more appropriate.

Another way is: DisplayMetrics

A structure describing general information about a display, such as its size, density, and font scaling. To access the DisplayMetrics members, initialize an object like this:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

We can use widthPixels to get information for:

"The absolute width of the display in pixels."

Example:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);
General Grievance
  • 4,555
  • 31
  • 31
  • 45
Josef Pfleger
  • 74,165
  • 16
  • 97
  • 99
  • No way u can do it in the XML? – Abhishek Susarla May 04 '11 at 05:52
  • 1
    @ Abhishek Susarla : XML usage is general used in a static way you should expect anything to be done dynamically, hope this helps you figure out ur problem. – MR Mido Aug 01 '11 at 17:47
  • 1
    well explained MR Mido. A lot of people who are new to Android don't understand the purpose of the XML files. – ajacian81 Sep 14 '11 at 01:44
  • 1
    If you use display.getWidth() be sure to set your minSdkVersion to at least 4 in AndroidManifest.xml or you will get incorrect results on some devices. – pzulw Feb 10 '12 at 18:03
  • Interesting discovery: in the emulator (Android 8) I've specified "Abstracted LCD density" as 150, but when I look at DisplayMetrics.densityDpi it shows 160. – Someone Somewhere Feb 22 '12 at 00:50
  • 15
    getWidth() or getSize()? What would I use if I need my app to run on API <13 as well as API >13? – Carol Apr 01 '12 at 05:29
  • 54
    try { display.getSize(size); width = size.x; height = size.y; } catch (NoSuchMethodError e) { width = display.getWidth(); height = display.getHeight(); } – Arnaud May 12 '12 at 11:41
  • @Arnaud Wouldn't it be a better idea to flip flop the try and catch until getWidth() and getHeight() are actually removed from the SDK? It seems to me your code will end up slowing down devices running API < 13 while giving no speed boost for devices running API >= 13? (BTW Carol, your comment is missing the case API == 13.) – ArtOfWarfare Nov 13 '12 at 19:14
  • Good point! I'd bet the majority of devices running API>=13 would less suffer of this than devices running API<13 in terms of performance. Also this would still work until the getWidth is really removed and not just deprecated. Any Android guy to confirm this? – Arnaud Nov 14 '12 at 11:39
  • 256
    I don't see why you want to use `try/catch` for such a check? Why not simply use `if (android.os.Build.VERSION.SDK_INT >= 13)` without any thrown exception at all? I think of `try/catch` in a normal app-flow as bad practice. – Patrik Nov 28 '12 at 15:41
  • @CipherCom at least because it might become deprecated as well. – A-Live Dec 19 '12 at 17:48
  • 4
    @A-Live then the app would break as well (but not crashing). We developers must pre-check a new os version nevertheless and this maybe just conceal a problem. Also with this argument one could/should surround every few code lines with try/catch, which in my opinion is bad practice as mentioned already. – Patrik Dec 30 '12 at 10:16
  • 1
    @CipherCom as a developer, you must understand the difference of the general and device dependent code, the latter is always better to use with try/catch at Android world in my opinion. And by try/catch I don't mean spamming exceptions at log but preparing a fallback functionality like using default values. – A-Live Dec 30 '12 at 14:21
  • 1
    @Josef How do the software buttons affect these methods? – Parth Mehrotra Feb 28 '13 at 23:42
  • what is 'ctx' in the above code? Is that a reference to something not defined in the code snippet? – WildBill Mar 04 '13 at 07:01
  • 1
    @WildBill `ctx` is a `Context` variable. – tom_mai78101 Mar 08 '13 at 07:37
  • 14
    what if you want to get the screen size excluding the navigation bar and/or notification bar – android developer May 12 '13 at 23:24
  • If this answer gets you wrong screen sizes, see this [related question](http://stackoverflow.com/questions/5078808/android-showing-wrong-screen-resolution) for an extra necessary step. – Eric Platon Apr 09 '14 at 02:54
  • @androiddeveloper Navigation, notification and action bars are always the same height, dependent on the system. Check out Android docs to see how many y-pixels – milosmns Sep 01 '14 at 11:51
  • @milosmns They aren't always being visible. it depends on the device - some tablets have the navigation bar with the notifications inside it (I think on Honeycomb, maybe even later), and also, some devices don't have a navigation bar at all, since they have real buttons – android developer Sep 01 '14 at 16:10
  • To handle API Level correctly (Pre/Post API 13) use this code: Point windowSize = new Point(); Display defaultDisplay = getActivity().getWindowManager().getDefaultDisplay(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { defaultDisplay.getSize(windowSize); } else { windowSize.x = defaultDisplay.getWidth(); windowSize.y = defaultDisplay.getHeight(); } – Muzikant Dec 16 '14 at 10:19
  • Use getDefaultDisplay().getRealMetrics(metrics) in order to include screen buttons – santaclos Mar 14 '16 at 21:18
  • You should use the `WindowManager` form `activity.getWindwoManager()`. Else when entering multi window, you will receive the size of your app in full width mode. – Paul Woitaschek Jul 11 '17 at 15:04
391

One way is:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

It is deprecated, and you should try the following code instead. The first two lines of code gives you the DisplayMetrics objecs. This objects contains the fields like heightPixels, widthPixels.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
      
int height = metrics.heightPixels;
int width = metrics.widthPixels;

Api level 30 update

final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
 // Gets all excluding insets
 final WindowInsets windowInsets = metrics.getWindowInsets();
 Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
         | WindowInsets.Type.displayCutout());

 int insetsWidth = insets.right + insets.left;
 int insetsHeight = insets.top + insets.bottom;

 // Legacy size that Display#getSize reports
 final Rect bounds = metrics.getBounds();
 final Size legacySize = new Size(bounds.width() - insetsWidth,
         bounds.height() - insetsHeight);
t0m
  • 3,004
  • 31
  • 53
Balaji.K
  • 8,745
  • 5
  • 30
  • 39
  • 19
    Note that the metrics (width, height) change depending on the rotation of the device. – Tony Chan Nov 28 '11 at 02:17
  • 9
    Metrics will return the size of the display, but HoneyComb and up, your activity will have less space than what's returned due to the system bar. – Guy Dec 29 '11 at 11:12
  • 4
    @Guy it depends on your implementation. You can hide the status bar: requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); – Hagai L Mar 28 '12 at 11:00
  • 83
    Also exists this way: getContext().getResources().getDisplayMetrics().widthPixels – Nik Jul 11 '12 at 05:32
  • 2
    final float scale = getResources().getDisplayMetrics().density; int width = (int) (metrics.widthPixels * scale + 0.5f); - You have to account for device density when doing it that way. – Abandoned Cart Feb 20 '14 at 04:45
  • 1
    @LoungeKatt why do you add 0.5f? Multiplying by scale gives me the right value, adding that 0.5f gets me (e.g.) 800.5... – Armfoot Sep 02 '14 at 10:00
  • 1
    This should be the accepted answer as it is Platform independent. – auracool Oct 16 '14 at 14:07
  • 1
    @Armfoot to sway rounding without a lot of excess code. – Abandoned Cart Nov 10 '14 at 18:47
  • 1
    getActivity().getResources().getDisplayMetrics().widthPixels; from within a fragment. – worked May 15 '16 at 12:25
123

It may not answer your question, but it could be useful to know (I was looking for it myself when I came to this question) that if you need a View's dimension but your code is being executed when its layout has not been laid out yet (for example in onCreate() ) you can setup a ViewTreeObserver.OnGlobalLayoutListener with View.getViewTreeObserver().addOnGlobalLayoutListener() and put the relevant code that needs the view's dimension there. The listener's callback will be called when the layout will have been laid out.

Francesco Feltrinelli
  • 1,589
  • 1
  • 10
  • 14
  • 1
    or just write view.post – Lukas Hanacek Sep 19 '13 at 09:27
  • 1
    view.post is not guaranteed to work though. It is just a workaround. – marsbear Feb 25 '14 at 14:31
  • 1
    @marsbear where does it say `View.post()` isn't guaranteed to work? I'm curious because I also rely on this method for getting a View's size after layout and was unaware it unreliable. – Tony Chan Mar 22 '14 at 00:20
  • 1
    @Turbo I say that :p We used that workaround before and it turned out to be unreliable. That workaround is based on the assumption, that the initially layouting is done within the same UIThread turn as the initialization. Hence you could schedule your code to run before the next UI turn via post() and be fine. It turned out that the layouting might take even longer under certain circumstances and the view was still not layouted when the posted code ran. What I do now is add the ViewTreeObserver in onCreate and remove it after the first onLayout. Init your stuff during that first onLayout. – marsbear Mar 28 '14 at 15:30
  • 1
    @marsbear does it matter which `View` you get the `ViewTreeObserver` from? Or do they all share the same one? – Tony Chan Apr 09 '14 at 20:58
  • 1
    @Turbo They should all share the same but the instance you get from getViewTreeObserver might not be valid forever hence you have to check if it is still alive (isAlive()). What I currently do is: getWindow().getDecorView().addOnLayoutChangeListener(). During the first call of the listener I remove it again and call a method in my BaseActivity: afterFirstLayout(). That's where we do calculations that need an initial complete layout cycle – marsbear Apr 10 '14 at 10:34
  • 1
    @marsbear and this method you use always executes at the right time even with the situation you describe about certain views not finishing their layout when View.post() finally executes? – Tony Chan Apr 10 '14 at 23:02
  • 1
    @Turbo so far: yes. But with all the different custom Androids out there it might fail one day :) The most secure way is to do your work in onLayout within your own View class but that is not always feasible if you want to 'just' put a view off the screen in onCreate for animation purposes. – marsbear Apr 11 '14 at 10:29
112

(2012 answer, may be out of date) If you want to support pre Honeycomb, you will need to put in backward compatibility prior to API 13. Something like:

int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    Point size = new Point();
    w.getDefaultDisplay().getSize(size);
    measuredWidth = size.x;
    measuredHeight = size.y;
} else {
    Display d = w.getDefaultDisplay();
    measuredWidth = d.getWidth();
    measuredHeight = d.getHeight();
}

Of course the deprecated methods will eventually be taken out of the the most recent SDKs, but while we still rely on most of our users having Android 2.1, 2.2 and 2.3, this is what we are left with.

digiphd
  • 2,319
  • 3
  • 23
  • 22
75

I have tried all possible "solutions" unsuccessfully and I noticed that Elliott Hughes' "Dalvik Explorer" app always shows correct dimension on any Android device/OS version. I ended up looking at his open source project that can be found here: https://code.google.com/p/enh/

Here's all the relevant code:

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

EDIT: slightly improved version (avoid firing exceptions on non-supported OS version):

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}
dakshbhatt21
  • 3,558
  • 3
  • 31
  • 40
Dragan Marjanović
  • 2,386
  • 1
  • 19
  • 17
  • 12
    This is the only post here that takes into account the window decorations (statusbar/menu bar). worked great for me. – Andy Cochrane May 31 '13 at 20:24
  • 6
    Awesome, however you should never have expected business logic fire exceptions. Exception firing(even when caught) is horrible for performance. Plus you are doing more work than needed if the SDK_INT is > 13. Instead, you should just add some ifs on the Build.VERSION.SDK_INT. – Erik B Jun 21 '13 at 23:15
  • 4
    @Erik B, I agree. I added improved version. Still I left the part "since SDK 1" just in case something goes wrong in try/catch (I've seen many bad things in Android especially when you think it's impossible something to go wrong so I like to keep it safe :)). Anyway there shouldn't be too mouch overhead since this calculation should be done only once (e.g. values could be kept in some static attributes). – Dragan Marjanović Jun 22 '13 at 16:41
  • 9
    Note that this code is licensed under GPL v3 which has implications for using in production apps. – TalkLittle Aug 12 '13 at 02:00
  • 1
    GPL and depending on reflection to call methods which might not be present in future Android versions. Mhhh – Michel Nov 14 '15 at 15:41
  • 1
    Why reflection, if the function is actually available for API 17 : https://developer.android.com/reference/android/view/Display.html#getRealSize(android.graphics.Point) ? Anyway, this doesn't take into account the current orientation, so it will switch according to it. Here's a solution that will work the same no matter is the orientation: https://stackoverflow.com/a/47684256/878126 . However, the question of the thread is about the normal sizes, so it doesn't need the real resolution. Just the part that can be used. – android developer Feb 17 '18 at 23:09
  • If using getRealMetricts() you're going to get the full size with windows decorations and these things; just in case someone is wondering how to do this without reflection. – forlayo Mar 04 '19 at 10:53
  • You're actually using reflection to calculate screen size? – IgorGanapolsky Oct 03 '22 at 18:02
54

Simplest way:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 
Zelleriation
  • 2,834
  • 1
  • 23
  • 23
48

For accessing the height of the status bar for Android devices, we prefer a programmatic way to get it:

Sample code

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

The variable result gives the height in the pixel.

For quick access

Enter image description here

For more information about height of Title bar, Navigation bar and Content View, kindly look on Android Device Screen Sizes.

Community
  • 1
  • 1
Swapnil Sonar
  • 2,232
  • 2
  • 29
  • 42
  • Just what i needed! `getResources().getDisplayMetrics().heightPixels + result` gives actual fullscreen height. Dragan Marjanović's answer also works but I prefer this much shorter and simpler solution. – Michel Nov 14 '15 at 15:35
  • This approach is outdated as of Android Marshmallow. Status bar height can change from device or Android version. Better use [`OnApplyWindowInsetsListener`](http://developer.android.com/reference/android/view/View.OnApplyWindowInsetsListener.html). – Jan Heinrich Reimer Feb 21 '16 at 13:20
33

First get view (eg. by findViewById()) and then you can use getWidth() on the view itself.

Anik Islam Abhi
  • 25,137
  • 8
  • 58
  • 80
Marcin Gil
  • 68,043
  • 8
  • 59
  • 60
  • 3
    This is actually how the documentation tells you to do it... but it's kinda pointless if you are NOT using a view. you may be using something else, e.g. mglsurfaceview. – gcb Nov 20 '10 at 02:22
  • 2
    this is better as the parent view may not be the size of the display. But make sure that this is done at a point where the view you are querying the size of has already been layed out, which will not usually be inside onCreate(). You can use a custom callback from onWindowFocusChanged(boolean hasFocus) which will be called after all the views have been measured and so on, ensuring you will not receive incorrect dimensions for the view you are interested it... – Dori Mar 01 '11 at 13:02
29

I have two functions, one for sending the context and the other getting height and width in pixels:

public static int getWidth(Context mContext){
    int width=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        width = size.x;
    }
    else{
        width = display.getWidth();  // Deprecated
    }
    return width;
}

and

public static int getHeight(Context mContext){
    int height=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        height = size.y;
    }
    else{
        height = display.getHeight();  // Deprecated
    }
    return height;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • You need to add `@SuppressLint("NewApi")` just above the function signature in order to be able to compile. – Adil Malik Oct 14 '13 at 15:09
  • I think it's better to get the height and width in one go rather than in separate calls to the APIs because otherwise they could be out of sync. This could happen if the screen orientation is changing while your code is running. – Sam May 26 '15 at 05:50
19

This is the code I use for the task:

// `activity` is an instance of Activity class.
Display display = activity.getWindowManager().getDefaultDisplay();
Point screen = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    display.getSize(screen);
} else {            
    screen.x = display.getWidth();
    screen.y = display.getHeight();
}

Seems clean enough and yet, takes care of the deprecation.

Pijusn
  • 11,025
  • 7
  • 57
  • 76
19

Isn't this a much better solution? DisplayMetrics comes with everything you need and works from API 1.

public void getScreenInfo(){
    DisplayMetrics metrics = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);

    heightPixels = metrics.heightPixels;
    widthPixels = metrics.widthPixels;
    density = metrics.density;
    densityDpi = metrics.densityDpi;
}

You can also get the actual display (including screen decors, such as Status Bar or software navigation bar) using getRealMetrics, but this works on 17+ only.

Am I missing something?

David Corsalini
  • 7,958
  • 8
  • 41
  • 66
  • 1
    It's not subtracting space for on-screen controls (such as on Tablets or Nexus devices). Also, I get a different value (750 vs 800) on my 10" Tablet, depending on whether the Activity is active when the calculation is done. But for my purposes, this is more than fine. Thank you! – Steven L Oct 10 '13 at 01:38
19

For dynamically scaling using XML there is an attribute called "android:layout_weight"

The below example, modified from synic's response on this thread, shows a button that takes up 75% of the screen (weight = .25) and a text view taking up the remaining 25% of the screen (weight = .75).

<LinearLayout android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="somebutton">

    <TextView android:layout_width="fill_parent"
        android:layout_height="Wrap_content"
        android:layout_weight=".75">
</LinearLayout>
Community
  • 1
  • 1
Crbreingan
  • 641
  • 2
  • 8
  • 18
17

Find width and height of the screen:

width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

Using this, we can get the latest and above SDK 13.

// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
    Point size = new Point();
    display.getSize(size);
    width = size.x;
    Log.i("width", "if =>" +width);
}
else {
    width = display.getWidth();
    Log.i("width", "else =>" +width);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
NagarjunaReddy
  • 8,621
  • 10
  • 63
  • 98
17
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Cristiana Chavez
  • 11,349
  • 5
  • 55
  • 54
17

Just adding to Francesco's answer. The other observer that is more apt, if you want to find out the location in window or location in screen is ViewTreeObserver.OnPreDrawListener()

This also can be used to find other attributes of a view that is mostly unknown at onCreate() time e.g. the scrolled position, the scaled position.

pellucide
  • 3,407
  • 2
  • 22
  • 25
16

Using the following code in Activity.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;
Vinothkumar Arputharaj
  • 4,567
  • 4
  • 29
  • 36
14
public class AndroidScreenActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        String str_ScreenSize = "The Android Screen is: "
                                   + dm.widthPixels
                                   + " x "
                                   + dm.heightPixels;

        TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
        mScreenSize.setText(str_ScreenSize);
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shoaib Ahmed
  • 747
  • 12
  • 28
14

Need to say, that if you are not in Activity, but in View (or have variable of View type in your scope), there is not need to use WINDOW_SERVICE. Then you can use at least two ways.

First:

DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();

Second:

DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);

All this methods we call here is not deprecated.

Sergei Pikalev
  • 516
  • 4
  • 5
14

This is not an answer for the OP, as he wanted the display dimensions in real pixels. I wanted the dimensions in "device-independent-pixels", and putting together answers from here https://stackoverflow.com/a/17880012/253938 and here https://stackoverflow.com/a/6656774/253938 I came up with this:

    DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
    int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
    int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);
Community
  • 1
  • 1
RenniePet
  • 11,420
  • 7
  • 80
  • 106
14

For getting the screen dimensions use display metrices

DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null) 
      WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      Display defaultDisplay = windowManager.getDefaultDisplay();
      defaultDisplay.getRealMetrics(displayMetrics);
    }

Get the height and width in pixels

int width  =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;
Mohamed Nageh
  • 1,963
  • 1
  • 19
  • 27
Sharath kumar
  • 4,064
  • 1
  • 14
  • 20
13

I found this did the trick.

Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);
Justin
  • 3,255
  • 3
  • 22
  • 20
  • 5
    Cool but the is one scary thing about this method in the sourcecode: [this comment](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.5_r1/android/view/View.java#4079) – Norbert Jul 19 '12 at 08:48
11

You can do get the height size using :

getResources().getDisplayMetrics().heightPixels;

and the width size using

getResources().getDisplayMetrics().widthPixels; 
Jéwôm'
  • 3,753
  • 5
  • 40
  • 73
10

There is a non-deprecated way to do this using DisplayMetrics (API 1), that avoids the try/catch messiness:

 // initialize the DisplayMetrics object
 DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();

 // populate the DisplayMetrics object with the display characteristics
 getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);

 // get the width and height
 screenWidth = deviceDisplayMetrics.widthPixels;
 screenHeight = deviceDisplayMetrics.heightPixels;
paulrehkugler
  • 3,241
  • 24
  • 45
10

I would wrap the getSize code like this:

@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
    Point size = new Point();
    Display d = a.getWindowManager().getDefaultDisplay();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        d.getSize(size);
    } else {
        size.x = d.getWidth();
        size.y = d.getHeight();
    }
    return size;
}
Simon
  • 13,173
  • 14
  • 66
  • 90
9

For who is searching for usable screen dimension without Status Bar and Action Bar (also thanks to Swapnil's answer):

DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    screen_h -= getResources().getDimensionPixelSize(resId);
}

TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
    screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}
Francesco Vadicamo
  • 5,522
  • 35
  • 29
8

Kotlin

fun getScreenHeight(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.heightPixels
}

fun getScreenWidth(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.widthPixels
}
Community
  • 1
  • 1
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
7

First load the XML file and then write this code:

setContentView(R.layout.main);      
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());

Show width and height according your screen resolution.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
duggu
  • 37,851
  • 12
  • 116
  • 113
7

Follow the methods below:

public static int getWidthScreen(Context context) {
    return getDisplayMetrics(context).widthPixels;
}

public static int getHeightScreen(Context context) {
    return getDisplayMetrics(context).heightPixels;
}

private static DisplayMetrics getDisplayMetrics(Context context) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sonida
  • 4,411
  • 1
  • 38
  • 40
6

There are times when you need to know the precise dimensions of the available space for a layout when in an activity's onCreate. After some thought I worked out this way of doing it.

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivityForResult(new Intent(this, Measure.class), 1);
        // Return without setting the layout, that will be done in onActivityResult.
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -1);
        // Width is now set to the precise available width, and a layout can now be created.            ...
    }
}

public final class Measure extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
       // Create a LinearLayout with a MeasureFrameLayout in it.
        // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
        LinearLayout linearLayout = new LinearLayout(this);
        LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
        measureFrameLayout.setLayoutParams(matchParent);
        linearLayout.addView(measureFrameLayout);
        this.addContentView(linearLayout, matchParent);
        // measureFrameLayout will now request this second activity to finish, sending back the width.
    }

    class MeasureFrameLayout extends FrameLayout {
        boolean finished = false;
        public MeasureFrameLayout(Context context) {
            super(context);
        }

        @SuppressLint("DrawAllocation")
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (finished) {
                return;
            }
            finished = true;
            // Send the width back as the result.
            Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
            Measure.this.setResult(Activity.RESULT_OK, data);
            // Tell this activity to finish, so the result is passed back.
            Measure.this.finish();
        }
    }
}

If for some reason you don't want to add another activity to the Android manifest, you can do it this way:

public class MainActivity extends Activity {
    static Activity measuringActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            extras = new Bundle();
        }
        int width = extras.getInt("Width", -2);
        if (width == -2) {
            // First time in, just start another copy of this activity.
            extras.putInt("Width", -1);
            startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1);
            // Return without setting the layout, that will be done in onActivityResult.
            return;
        }
        if (width == -1) {
            // Second time in, here is where the measurement takes place.
            // Create a LinearLayout with a MeasureFrameLayout in it.
            // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
            LinearLayout linearLayout = new LinearLayout(measuringActivity = this);
            LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
            measureFrameLayout.setLayoutParams(matchParent);
            linearLayout.addView(measureFrameLayout);
            this.addContentView(linearLayout, matchParent);
            // measureFrameLayout will now request this second activity to finish, sending back the width.
        }
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -3);
        // Width is now set to the precise available width, and a layout can now be created. 
        ...
    }

class MeasureFrameLayout extends FrameLayout {
    boolean finished = false;
    public MeasureFrameLayout(Context context) {
        super(context);
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (finished) {
            return;
        }
        finished = true;
        // Send the width back as the result.
        Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
        MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data);
        // Tell the (second) activity to finish.
        MainActivity.measuringActivity.finish();
    }
}    
Steve Waring
  • 2,882
  • 2
  • 32
  • 37
6

Much simpler in Kotlin.

val displayMetrics = Resources.getSystem().displayMetrics
displayMetrics.heightPixels
displayMetrics.widthPixels
Syed Arsalan Kazmi
  • 949
  • 1
  • 11
  • 17
  • This one is very short and precise!! Kudos !! – Nayan Mar 31 '23 at 13:08
  • Watch out - [as others pointed out] this one is only using the static system values, check the source/comments for `Resources.getSystem` if you wanna make sure this one suits your purpose. – Saik Caskey May 26 '23 at 06:16
5

If you don't want the overhead of WindowManagers, Points, or Displays, you can grab the height and width attributes of the topmost View item in your XML, provided its height and width are set to match_parent. (This is true so long as your layout takes up the entire screen.)

For example, if your XML starts with something like this:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/entireLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

Then findViewById(R.id.entireLayout).getWidth() will return the screen's width and findViewById(R.id.entireLayout).getHeight() will return the screen's height.

christinac
  • 395
  • 4
  • 4
3

I have a splash screen activity with a LinearLayout as a root view that has match_parent for its width & height. This is the code in the onCreate() method of that activity. I use these measures in all other activities of the app.

int displayWidth = getRawDisplayWidthPreHoneycomb();
int rawDisplayHeight = getRawDisplayHeightPreHoneycomb();
int usableDisplayHeight = rawDisplayHeight - getStatusBarHeight();
pf.setScreenParameters(displayWidth, usableDisplayHeight);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    LinearLayout myView = (LinearLayout) findViewById(R.id.splash_view);
    myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            if (left == 0 && top == 0 && right == 0 && bottom == 0) {
                return;
            }
            int displayWidth = Math.min(right, bottom);
            int usableDisplayHeight = Math.max(right, bottom);
            pf.setScreenParameters(displayWidth, usableDisplayHeight);
        }
    });
}

Here are the implementations for the methods you see get called above:

private int getRawDisplayWidthPreHoneycomb() {
    WindowManager windowManager = getWindowManager();
    Display display = windowManager.getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    display.getMetrics(displayMetrics);

    int widthPixels = displayMetrics.widthPixels;
    int heightPixels = displayMetrics.heightPixels;

    return Math.min(widthPixels, heightPixels);
}

private int getRawDisplayHeightPreHoneycomb() {
    WindowManager w = getWindowManager();
    Display d = w.getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    d.getMetrics(metrics);

    int widthPixels = metrics.widthPixels;
    int heightPixels = metrics.heightPixels;

    return Math.max(widthPixels, heightPixels);
}

public int getStatusBarHeight() {
    int statusBarHeight = 0;

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

    return statusBarHeight;
}

This results in the height and width of the usable display, excluding any type of bars (status bar, navigation bar), for all API versions and different types of devices (phones and tablets).

Daniel
  • 2,355
  • 9
  • 23
  • 30
Rutger
  • 323
  • 3
  • 8
3

Above code has been deprecated in API level 30. Now you can get using following code

 val width = windowManager.currentWindowMetrics.bounds.width()
 val height = windowManager.currentWindowMetrics.bounds.height()

This method reports the window size including all system bar areas, while Display#getSize(Point) reports the area excluding navigation bars and display cutout areas. The value reported by Display#getSize(Point) can be obtained by using:

 val metrics = windowManager.currentWindowMetrics
 // Gets all excluding insets
 val windowInsets = metrics.windowInsets
 var insets: Insets = windowInsets.getInsets(WindowInsets.Type.navigationBars())
 val cutout = windowInsets.displayCutout
 if (cutout != null) {
    val cutoutSafeInsets = Insets.of(cutout.safeInsetLeft, cutout.safeInsetTop, cutout.safeInsetRight, cutout.safeInsetBottom)
    insets = Insets.max(insets, cutoutSafeInsets)
 }

 val insetsWidth = insets.right + insets.left
 val insetsHeight = insets.top + insets.bottom

 // Legacy size that Display#getSize reports
 val legacySize =  Size(metrics.bounds.width() - insetsWidth, metrics.bounds.height() - insetsHeight)

Source : WindowManager#getCurrentWindowMetrics()

Krishna Meena
  • 5,693
  • 5
  • 32
  • 44
2

Above answer won't work if the Display class will not work then you can get the width and height by below method.

private static final int WIDTH_INDEX = 0;
private static final int HEIGHT_INDEX = 1;

    public static int[] getScreenSize(Context context) {
        int[] widthHeight = new int[2];
        widthHeight[WIDTH_INDEX] = 0;
        widthHeight[HEIGHT_INDEX] = 0;

        try {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();

            Point size = new Point();
            display.getSize(size);
            widthHeight[WIDTH_INDEX] = size.x;
            widthHeight[HEIGHT_INDEX] = size.y;

            if (!isScreenSizeRetrieved(widthHeight))
            {
                DisplayMetrics metrics = new DisplayMetrics();
                display.getMetrics(metrics);
                widthHeight[0] = metrics.widthPixels;
                widthHeight[1] = metrics.heightPixels;
            }

            // Last defense. Use deprecated API that was introduced in lower than API 13
            if (!isScreenSizeRetrieved(widthHeight)) {
                widthHeight[0] = display.getWidth(); // deprecated
                widthHeight[1] = display.getHeight(); // deprecated
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return widthHeight;
    }

    private static boolean isScreenSizeRetrieved(int[] widthHeight) {
        return widthHeight[WIDTH_INDEX] != 0 && widthHeight[HEIGHT_INDEX] != 0;
    }
1

Simple function compatible with lower versions as well.

/**
 * @return screen size int[width, height]
 *
 * */
public int[] getScreenSize(){
    Point size = new Point();
    WindowManager w = getWindowManager();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
        w.getDefaultDisplay().getSize(size);
        return new int[]{size.x, size.y};
    }else{
        Display d = w.getDefaultDisplay();
        //noinspection deprecation
        return new int[]{d.getWidth(), d.getHeight()};
    }
}

To use:

int width = getScreenSize()[0];
int height = getScreenSize()[1];
Jakob Harteg
  • 9,587
  • 15
  • 56
  • 78
1

This function returns the approximate screen size in inches.

public double getScreenSize()
{
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int width=dm.widthPixels;
        int height=dm.heightPixels;
        int dens=dm.densityDpi;
        double wi=(double)width/(double)dens;
        double hi=(double)height/(double)dens;
        double x = Math.pow(wi,2);
        double y = Math.pow(hi,2);
        double screenInches = Math.sqrt(x+y);
        return screenInches;
}
Abhishek
  • 2,295
  • 24
  • 28
1

Here is a simple adaptation from some answers above in a Kotlin implementation. It requires as mentioned above windowsSoftInput="adjustResize" in the manifest:

class KeyboardWatcher(private val layoutRooView: View) {

    companion object {
        private const val MIN_KEYBOARD_HEIGHT = 200f
    }

    private val displayMetrics: DisplayMetrics = layoutRooView.resources.displayMetrics
    private var stateVisible = false

    var observer: ((Boolean) -> Unit)? = null

    init {
        layoutRooView.viewTreeObserver.addOnGlobalLayoutListener {
            val heightDiff = layoutRooView.rootView.height - layoutRooView.height
            if (!stateVisible && heightDiff > dpToPx(MIN_KEYBOARD_HEIGHT)) {
                stateVisible = true
                observer?.invoke(stateVisible)
            } else if(stateVisible) {
                stateVisible = false
                observer?.invoke(stateVisible)
            }
        }
    }

    private fun dpToPx(valueInDp: Float): Float {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, displayMetrics)
    }
}

And to use:

val activityRootView = findViewById<ViewGroup>(R.id.activityRoot)
KeyboardWatcher(activityRootView).observer = { visible ->
    if (visible) do something here ...
}
Joao Gavazzi
  • 1,818
  • 18
  • 8
1

Created Kotlin extension function to get screen width and height -

fun Context?.screenWidthInPx(): Int {
    if (this == null) return 0
    val dm = DisplayMetrics()
    val wm = this.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    wm.defaultDisplay.getMetrics(dm)
    return dm.widthPixels
}
//comment
fun Context?.screenHeightInPx(): Int {
    if (this == null) return 0
    val dm = DisplayMetrics()
    val wm = this.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    wm.defaultDisplay.getMetrics(dm)
    return dm.heightPixels
}
TinTin
  • 201
  • 1
  • 8
  • 19
Roman
  • 2,464
  • 2
  • 17
  • 21
1

Now on the Api 30 level , it should be done like this

final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
 // Gets all excluding insets
 final WindowInsets windowInsets = metrics.getWindowInsets();
 Insets insets = windowInsets.getInsetsIgnoreVisibility(WindowInsets.Type.navigationBars()
         | WindowInsets.Type.displayCutout());

 int insetsWidth = insets.right + insets.left;
 int insetsHeight = insets.top + insets.bottom;

 // Legacy size that Display#getSize reports
 final Rect bounds = metrics.getBounds();
 final Size legacySize = new Size(bounds.width() - insetsWidth,
         bounds.height() - insetsHeight);
ismail alaoui
  • 5,748
  • 2
  • 21
  • 38
1

Here is Kotlin extension functions for below/above API 30 code:

fun Activity.getScreenWidth(): Int {
    return if (Build.VERSION.SDK_INT < 30) {
        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        displayMetrics.widthPixels
    } else {
        val metrics = windowManager.currentWindowMetrics
        val insets = metrics.windowInsets
            .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
        metrics.bounds.width() - insets.left - insets.right
    }
}

fun Activity.getScreenHeight(): Int {
    return if (Build.VERSION.SDK_INT < 30) {
        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        displayMetrics.heightPixels
    } else {
        val metrics = windowManager.currentWindowMetrics
        val insets = metrics.windowInsets
            .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
        metrics.bounds.height() - insets.top - insets.bottom
    }
}

Corresponding Java helper methods:

public int getScreenWidth(Activity activity) {
    if (Build.VERSION.SDK_INT < 30) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.widthPixels;
    } else {
        WindowMetrics metrics = activity.getWindowManager().getCurrentWindowMetrics();
        Insets insets = metrics.getWindowInsets()
                .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars());
        return metrics.getBounds().width() - insets.left - insets.right;
    }
}


public int getScreenHeight(Activity activity) {
    if (Build.VERSION.SDK_INT < 30) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.heightPixels;
    } else {
        WindowMetrics metrics = activity.getWindowManager().getCurrentWindowMetrics();
        Insets insets = metrics.getWindowInsets()
                .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars());
        return metrics.getBounds().height() - insets.bottom - insets.top;
    }
}
Zain
  • 37,492
  • 7
  • 60
  • 84
0
DisplayMetrics dm = getResources().getDisplayMetrics();
float fwidth = dm.density * dm.widthPixels;
float fheight = dm.density * dm.heightPixels;

If getSize gets you an error due to your minSDKVersion and you don't want to use deprecated methods (getWidth & getHeight), the getMetrics solution was originally posted on 2011 by Balaji.K... And Nik added a comment explaining getDisplayMetrics also considers the status bar size.

Some other comments refer to multiply by the scale (density) in order to get the precise float value of the dimensions. Tested in Android v2.2 (API 8) and v4.0 with good results and no errors/warnings.

Armfoot
  • 4,663
  • 5
  • 45
  • 60
0

I used above proposals and created a kotlin version for our question. Hope this provides some additional help for those using kotlin:

private val screenDimensions: Int by lazy {
    val display = (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
    Point()
        .also { size ->
            when {
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 -> display.getRealSize(size)
                else -> display.getSize(size)
            }
        }
}

screenDimensions.x // width
screenDimensions.y // height
Mike T
  • 1,194
  • 14
  • 25
0

I think it's simplest

private fun checkDisplayResolution() {
    val displayMetrics = DisplayMetrics().also {
        windowManager.defaultDisplay.getMetrics(it)
    }

    Log.i(TAG, "display width: ${displayMetrics.widthPixels}")
    Log.i(TAG, "display height: ${displayMetrics.heightPixels}")
    Log.i(TAG, "display width dpi: ${displayMetrics.xdpi}")
    Log.i(TAG, "display height dpi: ${displayMetrics.ydpi}")
    Log.i(TAG, "display density: ${displayMetrics.density}")
    Log.i(TAG, "display scaled density: ${displayMetrics.scaledDensity}")
}
Artem Botnev
  • 2,267
  • 1
  • 14
  • 19
0

Kotlin Version via Extension Property

There are multiple ways of achieving the screen dimensions in android, but I think the best solution could be independent of a Context instance, so you can use it everywhere in your code. Here I've provided a solution via kotlin extension property, which makes it easy to know the screen size in pixels as well as dp:


DimensionUtils.kt

import android.content.res.Resources
import android.graphics.Rect
import android.graphics.RectF
import android.util.DisplayMetrics
import kotlin.math.roundToInt

/**
 * @author aminography
 */

private val displayMetrics: DisplayMetrics by lazy { Resources.getSystem().displayMetrics }

val screenRectPx: Rect
    get() = displayMetrics.run { Rect(0, 0, widthPixels, heightPixels) }

val screenRectDp: RectF
    get() = displayMetrics.run { RectF(0f, 0f, widthPixels.px2dp, heightPixels.px2dp) }

val Number.px2dp: Float
    get() = this.toFloat() / displayMetrics.density

val Number.dp2px: Int
    get() = (this.toFloat() * displayMetrics.density).roundToInt()


Usage:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val widthPx = screenRectPx.width()
        val heightPx = screenRectPx.height()
        println("[PX] screen width: $widthPx , height: $heightPx")

        val widthDp = screenRectDp.width()
        val heightDp = screenRectDp.height()
        println("[DP] screen width: $widthDp , height: $heightDp")
    }
}

Result:

When the device is in portrait orientation:

[PX] screen width: 1440 , height: 2392
[DP] screen width: 360.0 , height: 598.0

When the device is in landscape orientation:

[PX] screen width: 2392 , height: 1440
[DP] screen width: 598.0 , height: 360.0


If you are not a fan of kotlin, use the java version:

import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.DisplayMetrics;

/**
 * @author aminography
 */
public class DimensionUtils {

    private static DisplayMetrics displayMetrics;

    private static DisplayMetrics getDisplayMetrics() {
        if (displayMetrics == null) {
            displayMetrics = Resources.getSystem().getDisplayMetrics();
        }
        return displayMetrics;
    }

    public static Rect screenRectPx() {
        return new Rect(0, 0, getDisplayMetrics().widthPixels, getDisplayMetrics().heightPixels);
    }

    public static RectF screenRectDp() {
        return new RectF(0f, 0f, px2dp(getDisplayMetrics().widthPixels), px2dp(getDisplayMetrics().heightPixels));
    }

    public static float px2dp(int value) {
        return value / getDisplayMetrics().density;
    }

    public static int dp2px(float value) {
        return (int) (value * getDisplayMetrics().density);
    }
}
aminography
  • 21,986
  • 13
  • 70
  • 74
0

KOTLIN

fun getScreenHeight(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.heightPixels
}

fun getScreenWidth(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.widthPixels
}

JAVA

DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
Rahul
  • 3,293
  • 2
  • 31
  • 43
0

create a class and a method like below:

public MyPoint getScreenDimensionsAsPixel(Context context){
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();

        Point point = new Point();
        display.getSize(point);

        return new MyPoint(point.x, point.y);
    }

    public class MyPoint{
        private int width;
        private int height;

        public MyPoint(int width, int height) {
            this.width = width;
            this.height = height;
        }

        public int getWidth() {
            return width;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        public int getHeight() {
            return height;
        }

        public void setHeight(int height) {
            this.height = height;
        }
    }

and then use them in your codes:

MyPoint myPoint = getScreenDimensionsAsPixel(MainActivity.this);
                Toast.makeText(MainActivity.this, "width: " + String.valueOf(myPoint.getWidth()) + "|" +
                        "height: " + String.valueOf(myPoint.getHeight()), Toast.LENGTH_LONG).show();