By Niko Gamulin


2009-06-19 08:25:57 8 Comments

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?

30 comments

@Tyler 2019-03-19 22:07:42

Note that the height returned by these APIs will be LESS THAN the device's physical height because the button bar height is subtracted.

For example: On a Moto X4 it returns the correct widthPixels (1080) but it returns a height of 1776 even though the device's screen is 1920 pixels tall.

@Artem Botnev 2019-02-27 08:35:08

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}")
}

@Josef Pfleger 2009-06-19 08:41:04

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);

@Abhishek Susarla 2011-05-04 05:52:35

No way u can do it in the XML?

@MR Mido 2011-08-01 17:47:55

@ 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.

@ajacian81 2011-09-14 01:44:27

well explained MR Mido. A lot of people who are new to Android don't understand the purpose of the XML files.

@Josef Pfleger 2012-02-04 16:13:45

Thanks @jcfrei ! - I refactored the answer appropriately.

@pzulw 2012-02-10 18:03:36

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.

@Someone Somewhere 2012-02-22 00:50:10

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.

@Carol 2012-04-01 05:29:20

getWidth() or getSize()? What would I use if I need my app to run on API <13 as well as API >13?

@Arnaud 2012-05-12 11:41:31

try { display.getSize(size); width = size.x; height = size.y; } catch (NoSuchMethodError e) { width = display.getWidth(); height = display.getHeight(); }

@ArtOfWarfare 2012-11-13 19:14:33

@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.)

@Arnaud 2012-11-14 11:39:33

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?

@Patrik 2012-11-28 15:41:05

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.

@A-Live 2012-12-19 17:48:38

@CipherCom at least because it might become deprecated as well.

@Patrik 2012-12-30 10:16:51

@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.

@A-Live 2012-12-30 14:21:50

@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.

@Parth Mehrotra 2013-02-28 23:42:38

@Josef How do the software buttons affect these methods?

@WildBill 2013-03-04 07:01:23

what is 'ctx' in the above code? Is that a reference to something not defined in the code snippet?

@tom_mai78101 2013-03-08 07:37:57

@WildBill ctx is a Context variable.

@android developer 2013-05-12 23:24:57

what if you want to get the screen size excluding the navigation bar and/or notification bar

@Eric Platon 2014-04-09 02:54:32

If this answer gets you wrong screen sizes, see this related question for an extra necessary step.

@milosmns 2014-09-01 11:51:19

@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

@android developer 2014-09-01 16:10:36

@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

@Muzikant 2014-12-16 10:19:13

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(); }

@user3245882 2016-03-14 21:18:04

Use getDefaultDisplay().getRealMetrics(metrics) in order to include screen buttons

@Paul Woitaschek 2017-07-11 15:04:59

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.

@Khemraj 2018-10-01 11:43:00

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
}

@Mike T 2018-07-19 07:44:37

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

@Anonymous 2017-09-04 11:21:01

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;

@Joao Gavazzi 2017-10-14 20:13:45

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 ...
}

@Jéwôm' 2017-10-09 14:09:44

You can do get the height size using :

getResources().getDisplayMetrics().heightPixels;

and the width size using

getResources().getDisplayMetrics().widthPixels; 

@Maharshi Saparia 2017-07-29 07:07:10

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;
    }

@Rutger 2013-11-02 19:55:00

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).

@Balaji.K 2011-01-31 02:01:11

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;

@Tony Chan 2011-11-28 02:17:53

Note that the metrics (width, height) change depending on the rotation of the device.

@Guy 2011-12-29 11:12:10

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.

@Hagai L 2012-03-28 11:00:27

@Guy it depends on your implementation. You can hide the status bar: requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLS‌​CREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

@Nik 2012-07-11 05:32:47

Also exists this way: getContext().getResources().getDisplayMetrics().widthPixels

@Abandoned Cart 2014-02-20 04:45:27

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.

@Armfoot 2014-09-02 10:00:16

@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...

@Jonny2Plates 2014-10-16 14:07:26

This should be the accepted answer as it is Platform independent.

@Abandoned Cart 2014-11-10 18:47:06

@Armfoot to sway rounding without a lot of excess code.

@worked 2016-05-15 12:25:50

getActivity().getResources().getDisplayMetrics().widthPixels‌​; from within a fragment.

@portfoliobuilder 2016-08-30 17:37:50

Does this actually return back the device screen size or the device screen resolution?

@sonida 2013-11-07 16:31:43

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;
}

@Sotti 2015-12-16 11:16:49

mContext.getResources().getDisplayMetrics().widthPixels; ???

@Abhishek 2016-01-05 05:31:41

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;
}

@Marcin Gil 2009-06-19 08:38:30

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

@gcb 2010-11-20 02:22:12

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.

@Dori 2011-03-01 13:02:44

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...

@Swapnil Sonar 2013-08-27 13:12:30

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.

@Michel 2015-11-14 15:35:21

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.

@Heinrich 2016-02-21 13:20:32

This approach is outdated as of Android Marshmallow. Status bar height can change from device or Android version. Better use OnApplyWindowInsetsListener.

@digiphd 2012-07-24 03:14:27

(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 2015-06-22 22:46:04

Yeah, this was back in 2012.

@sudocoder 2015-06-23 04:24:09

sorry, allow me to clarify what I meant. It is highly unlikely that anyone would support API <14 as of 6/22/2015

@Zelleriation 2014-11-26 10:47:10

Simplest way:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 

@Armfoot 2014-09-02 10:48:08

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.

@Jakob 2014-06-11 17:19:01

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];

@Cristiana Chavez 2013-12-18 10:30:33

DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;

@Shoaib Ahmed Khan 2012-06-27 12:18:12

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);
    }
}

@NagarjunaReddy 2012-06-18 04:42:48

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);
}

@duggu 2012-12-17 11:22:09

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.

@Elenasys 2012-10-17 14:44:20

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;
}

@Adil Malik 2013-10-14 15:09:02

You need to add @SuppressLint("NewApi") just above the function signature in order to be able to compile.

@Sam 2015-05-26 05:50:53

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.

@Francesco Vadicamo 2013-09-09 09:02:51

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);
}

@RenniePet 2013-08-16 21:44:02

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);

@Dragan Marjanović 2013-03-29 08:15:43

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) {
}

@Andy Cochrane 2013-05-31 20:24:39

This is the only post here that takes into account the window decorations (statusbar/menu bar). worked great for me.

@Erik B 2013-06-21 23:15:13

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.

@Dragan Marjanović 2013-06-22 16:41:28

@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).

@TalkLittle 2013-08-12 02:00:51

Note that this code is licensed under GPL v3 which has implications for using in production apps.

@Michel 2015-11-14 15:41:26

GPL and depending on reflection to call methods which might not be present in future Android versions. Mhhh

@android developer 2018-02-17 23:09:43

Why reflection, if the function is actually available for API 17 : developer.android.com/reference/android/view/… ? 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: 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.

@forlayo 2019-03-04 10:53:26

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.

@christinac 2013-06-26 18:35:05

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.

@Rishabh Srivastava 2013-09-20 11:44:03

nopes...it returns 0.

@Steve Waring 2013-05-22 12:16:47

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 2013-05-22 12:21:34

Obviously, you can also pass back the height in the bundle too.

@David Corsalini 2013-05-12 20:16:20

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?

@Steven L 2013-10-10 01:38:18

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!

Related Questions

Sponsored Content

33 Answered Questions

[SOLVED] Converting pixels to dp

16 Answered Questions

[SOLVED] Get the size of the screen, current web page and browser window

8 Answered Questions

[SOLVED] How to get the absolute coordinates of a view

5 Answered Questions

[SOLVED] Navigation Drawer (Google+ vs. YouTube)

9 Answered Questions

[SOLVED] how to get android screen size programmatically, once and for all?

  • 2013-07-05 04:57:22
  • Don Hatch
  • 59885 View
  • 130 Score
  • 9 Answer
  • Tags:   android

26 Answered Questions

[SOLVED] Using jQuery to center a DIV on the screen

18 Answered Questions

[SOLVED] Fling gesture detection on grid layout

1 Answered Questions

1 Answered Questions

Android – Am I Doing this Right?

2 Answered Questions

Sponsored Content