I need the width of the screen. But recently found Android defaultDisplay deprecacted with message:
Getter for defaultDisplay: Display!' is deprecated. Deprecated in Java
Code:
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
return displayMetrics.widthPixels
Please suggest an alternative.
defaultDisplay was marked as deprecated in API level 30 (Android R) and above.
This means if you have a minimum SDK configuration below API level 30, you should have both implementations with the old deprecated code and the new recommended code.
After fixing the problem correctly you can use #Suppress("DEPRECATION") to suppress warnings
Example: Kotlin solution
val outMetrics = DisplayMetrics()
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
val display = activity.display
display?.getRealMetrics(outMetrics)
} else {
#Suppress("DEPRECATION")
val display = activity.windowManager.defaultDisplay
#Suppress("DEPRECATION")
display.getMetrics(outMetrics)
}
WindowManager.getDefaultDisplay() was deprecated in API level 30 in favour of Context.getDisplay() method which requires minimum API level 30.
At the moment, androidx.core.content.ContextCompat doesn't seem to offer any backwards compatible getDisplay() method.
If you only need to retrieve the default display, instead of using different methods for different API levels as other answers suggest, you can you DisplayManager.getDisplay(Display.DEFAULT_DISPLAY) method (supported since API 17) to achieve the same result.
Deprecated code:
val defaultDisplay = getSystemService<WindowManager>()?.defaultDisplay
New code:
val defaultDisplay = getSystemService<DisplayManager>()?.getDisplay(Display.DEFAULT_DISPLAY)
Ref: androidx.core source code
If what you need is to get the size of the Window, the new Jetpack WindowManager library provides a common API surface for new Window Manager features (e.g. foldable devices and Chrome OS) throughout old and new platform versions.
dependencies {
implementation "androidx.window:window:1.0.0-beta02"
}
Jetpack WindowManager offers two ways to retrieve WindowMetrics information, as an asynchronous stream or synchronously.
Asynchronous WindowMetrics flow:
Use WindowInfoRepository#currentWindowMetrics to get notified by the library when there’s a window size change, independent of whether this change fires a configuration change.
import androidx.window.layout.WindowInfoRepository
import androidx.window.layout.WindowInfoRepository.Companion.windowInfoRepository
import androidx.window.layout.WindowMetrics
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.flowWithLifecycle
lifecycleScope.launch(Dispatchers.Main) {
windowInfoRepository().currentWindowMetrics.flowWithLifecycle(lifecycle)
.collect { windowMetrics: WindowMetrics ->
val currentBounds = windowMetrics.bounds // E.g. [0 0 1350 1800]
val width = currentBounds.width()
val height = currentBounds.height()
}
}
Note: lifecycleScope and flowWithLifecycle() are part of Jetpack Lifecycle library.
Synchronous WindowMetrics:
Use WindowMetricsCalculator when writing code in a view where the asynchronous API can be too hard to deal with (such as onMeasure or during testing).
import androidx.window.layout.WindowMetricsCalculator
import androidx.window.layout.WindowMetrics
val windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(activity)
val currentBounds = windowMetrics.bounds // E.g. [0 0 1350 1800]
val width = currentBounds.width()
val height = currentBounds.height()
Ref: Unbundling the WindowManager | Android Developers Medium
This method was deprecated in API level 30.
Use Context.getDisplay() instead.
Deprecated method: getDefaultDisplay
New Method: getDisplay
Try something like this:
private Display getDisplay(#NonNull WindowManager windowManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// This one (context) may or may not have a display associated with it, due to it being
// an application context
return getDisplayPostR();
} else {
return getDisplayPreR(windowManager);
}
}
#RequiresApi(api = Build.VERSION_CODES.R)
private Display getDisplayPostR() {
// We can't get the WindowManager by using the context we have, because that context is a
// application context, which isn't associated with any display. Instead, grab the default
// display, and create a DisplayContext, from which we can use the WindowManager or
// just get that Display from there.
//
// Note: the default display doesn't have to be the one where the app is on, however the
// getDisplays which returns a Display[] has a length of 1 on Pixel 3.
//
// This gets rid of the exception interrupting the onUserLogin() method
Display defaultDisplay = DisplayManagerCompat.getInstance(context).getDisplay(Display.DEFAULT_DISPLAY);
Context displayContext = context.createDisplayContext(defaultDisplay);
return displayContext.getDisplay();
}
#SuppressWarnings("deprecation")
private Display getDisplayPreR(#NonNull WindowManager windowManager) {
return windowManager.getDefaultDisplay();
}
or to get the actual size:
private Point getScreenResolution() {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (wm == null) {
return null;
}
Display display = getDisplay(wm);
return getSize(display, wm);
}
private Point getSize(Display forWhichDisplay, WindowManager windowManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return getSizePostR(windowManager);
} else {
return getSizePreR(forWhichDisplay);
}
}
#RequiresApi(api = Build.VERSION_CODES.R)
private Point getSizePostR(#NonNull WindowManager windowManager) {
WindowMetrics currentWindowMetrics = windowManager.getCurrentWindowMetrics();
Rect bounds = currentWindowMetrics.getBounds();
// Get the insets, such as titlebar and other decor views
WindowInsets windowInsets = currentWindowMetrics.getWindowInsets();
Insets insets = windowInsets.getInsets(WindowInsets.Type.navigationBars());
// If cutouts exist, get the max of what we already calculated and the system's safe insets
if (windowInsets.getDisplayCutout() != null) {
insets = Insets.max(
insets,
Insets.of(
windowInsets.getDisplayCutout().getSafeInsetLeft(),
windowInsets.getDisplayCutout().getSafeInsetTop(),
windowInsets.getDisplayCutout().getSafeInsetRight(),
windowInsets.getDisplayCutout().getSafeInsetBottom()
)
);
}
// Calculate the inset widths/heights
int insetsWidth = insets.right + insets.left;
int insetsHeight = insets.top + insets.bottom;
// Get the display width
int displayWidth = bounds.width() - insetsWidth;
int displayHeight = bounds.height() - insetsHeight;
return new Point(displayWidth, displayHeight);
}
// This was deprecated in API 30
#SuppressWarnings("deprecation")
private Point getSizePreR(Display display) {
Point size = new Point();
if (isRealDisplaySizeAvailable()) {
display.getRealSize(size);
} else {
display.getSize(size);
}
return size;
}
private static boolean isRealDisplaySizeAvailable() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
}
I use DisplayCompatManager to get width and height on android R-Above and use DisplayMatrics to get it on other android version.
So, this is my code ( + #Suppress("DEPRECATION") )
private fun screenValue() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val defaultDisplay =
DisplayManagerCompat.getInstance(this).getDisplay(Display.DEFAULT_DISPLAY)
val displayContext = createDisplayContext(defaultDisplay!!)
width = displayContext.resources.displayMetrics.widthPixels
height = displayContext.resources.displayMetrics.heightPixels
Log.e(tag, "width (ANDOIRD R/ABOVE): $width")
Log.e(tag, "height (ANDOIRD R/ABOVE) : $height")
} else {
val displayMetrics = DisplayMetrics()
#Suppress("DEPRECATION")
windowManager.defaultDisplay.getMetrics(displayMetrics)
height = displayMetrics.heightPixels
width = displayMetrics.widthPixels
Log.e(tag, "width (BOTTOM ANDROID R): $width")
Log.e(tag, "height (BOTTOM ANDROID R) : $height")
}
}
If you want see my gist in github
In Api Level 31 method Display.getRealMetrics() was deprecated as well. The recommended way is to use WindowManager#getCurrentWindowMetrics(). I prefer the following approach to get screen size:
object ScreenSizeCompat {
private val api: Api =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) ApiLevel30()
else Api()
/**
* Returns screen size in pixels.
*/
fun getScreenSize(context: Context): Size = api.getScreenSize(context)
#Suppress("DEPRECATION")
private open class Api {
open fun getScreenSize(context: Context): Size {
val display = context.getSystemService(WindowManager::class.java).defaultDisplay
val metrics = if (display != null) {
DisplayMetrics().also { display.getRealMetrics(it) }
} else {
Resources.getSystem().displayMetrics
}
return Size(metrics.widthPixels, metrics.heightPixels)
}
}
#RequiresApi(Build.VERSION_CODES.R)
private class ApiLevel30 : Api() {
override fun getScreenSize(context: Context): Size {
val metrics: WindowMetrics = context.getSystemService(WindowManager::class.java).currentWindowMetrics
return Size(metrics.bounds.width(), metrics.bounds.height())
}
}
}
And to get, for example, screen height use it in Activity:
ScreenSizeCompat.getScreenSize(this).height
Anyone looking to do it in java here you go:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
Display display = this.getDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getRealMetrics(displayMetrics);
float density = getResources().getDisplayMetrics().density;
float dpHeight = displayMetrics.heightPixels / density;
float dpWidth = displayMetrics.widthPixels / density;
Log.d(TAG, "OmesChecka R: "+"second width:"+dpWidth+"second h:"+dpHeight);
}else {
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
float density = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth = outMetrics.widthPixels / density;
Log.d(TAG, "OmesChecka: "+"second width:"+dpWidth+"second h:"+dpHeight);
}
Since I had to go to several places to get the complete answer, here it is in one post:
getDefaultDisplay method is depreciated as of Android API 30 (Android 11), but still works.
Even so, because it's depreciated you should use the new method for Android 11, and still implement the old method for Android 10 or earlier.
Here's the code, with comments: (To run this you need viewBinding enabled in your build.gradle (since I'm not using findViewByID), an activity_main.xml with your top level layout named "main_activity", a button view named "calculate_button", and three text views named "android_version", "screen_height" and "screen_width".)
package com.example.test
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.WindowManager
import com.example.test.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.calculateButton.setOnClickListener { calcScreenSize() }
}
private fun calcScreenSize() { //All in one function to calculate and display screen size in pixels
val metrics = DisplayMetrics()
var width: Int = 0
var height: Int = 0
val version = android.os.Build.VERSION.SDK_INT //Check android version. Returns API # ie 29 (Android 10), 30 (Android 11)
if (version >= android.os.Build.VERSION_CODES.R) { //If API is version 30 (Android 11) or greater, use the new method for getting width/height
binding.androidVersion.setText("Android API Version: $version")
binding.mainActivity.display?.getRealMetrics(metrics) //New method
width = metrics.widthPixels
height = metrics.heightPixels
binding.screenHeight.setText("Height: $height") //Display Width and Height in Text Views
binding.screenWidth.setText("Width: $width")
} else {
binding.androidVersion.setText("Android API Version: $version") //If API is less than version 30 (ie 29 (Android 10)), use the old method for getting width/height
#Suppress("DEPRECATION") //Suppress the "Deprecation" warning
windowManager.defaultDisplay.getMetrics(metrics) //Old method
width = metrics.widthPixels
height = metrics.heightPixels
binding.screenHeight.setText("Height: $height") //Display Width and Height in Text Views
binding.screenWidth.setText("Width: $width")
}
}
}
Here is a java solution attempting the least amount of code, imports, and further depreciated methods as possible. I leave potential device insets in my game to keep the view as large as possible. However, the commented code will shorten width and height for insets.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowMetrics windowMetrics = ((Activity) context).getWindowManager().getCurrentWindowMetrics();
//Insets insets = windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(WindowInsets.Type.systemBars());
screenWidth = windowMetrics.getBounds().width();// - insets.left - insets.right;
screenHeight = windowMetrics.getBounds().height();// - insets.top - insets.bottom;
} else {
Display display = ((Activity) context).getWindowManager().getDefaultDisplay();//getDefaultDisplay depreciated getMetrics() depreciated
Point size = new Point();
display.getSize(size);
screenWidth = size.x;
screenHeight = size.y;
try {
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(display, realSize);
screenWidth = realSize.x;
screenHeight = realSize.y;
} catch (Exception ignored) {
}
}
I have a view subclass that starts from activity subclass like that:
this.setContentView(instanceOfMyView);
In that my view subclass I want to make some work with screen size, but all people here says that it should be started like:
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;
screenHeight = dm.heightPixels;
But getWindowManager() is the method that can be called from activity subclass only (Am I right?)
So, is it bad idea and I need to get screen size in activity and use it as parameters in view constructor or there is a way to get screen size in view subclass? Maybe, just need to somehow get a link to instance of activity in view class?
Thanks in advance.
Yes there is a way, if you can pass the Context Object to your non activity class,
int width= context.getResources().getDisplayMetrics().widthPixels;
int height= context.getResources().getDisplayMetrics().heightPixels;
You don't need the Activity Object itself.
DisplayMetrics metrics = getBaseContext().getResources().getDisplayMetrics();
final int w = metrics.widthPixels;
final int h = metrics.heightPixels;
The other answers here won't give you the screen resolution.
Here's how you should do it:
#SuppressLint("ObsoleteSdkInt")
#JvmStatic
fun getScreenResolution(context: Context, naturalResolution: Boolean = false): Point {
val screenResolution = Point()
val display = getDisplay(context)!!
#Suppress("DEPRECATION")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
display.getRealSize(screenResolution)
} else display.getSize(screenResolution)
if (naturalResolution) {
val screenNaturalOrientation = getScreenNaturalOrientation(context)
if ((screenNaturalOrientation == Configuration.ORIENTATION_PORTRAIT && screenResolution.x > screenResolution.y)
|| (screenNaturalOrientation == Configuration.ORIENTATION_LANDSCAPE && screenResolution.y > screenResolution.x))
screenResolution.set(screenResolution.y, screenResolution.x)
}
return screenResolution
}
/**
* returns the natural orientation of the device: Configuration.ORIENTATION_LANDSCAPE or Configuration.ORIENTATION_PORTRAIT .<br></br>
* The result should be consistent no matter the orientation of the device
*/
fun getScreenNaturalOrientation(context: Context): Int {
//based on : http://stackoverflow.com/a/9888357/878126
val config = context.resources.configuration
val rotation = getDisplay(context)!!.rotation
return if ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
config.orientation == Configuration.ORIENTATION_LANDSCAPE
|| (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
config.orientation == Configuration.ORIENTATION_PORTRAIT) Configuration.ORIENTATION_LANDSCAPE else Configuration.ORIENTATION_PORTRAIT
}
To get the display, use:
fun getDisplay(context: Context): Display? {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
try {
val result = context.display
if (result != null)
return result
} catch (e: Throwable) {
}
if (context is Activity) {
return try {
#Suppress("DEPRECATION")
context.windowManager.defaultDisplay
} catch (e: Throwable) {
null
}
}
return null
}
docs:
https://developer.android.com/reference/android/view/Display.html#getRealSize(android.graphics.Point)
This can be used in any class:
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
Integer with = metrics.widthPixels;
Integer height = metrics.heightPixels;
Hope this help
Even simpler than accepted answer. You don't need context.
object ScreenUtils {
fun getScreenWidth() = Resources.getSystem().displayMetrics.widthPixels
fun getScreenHeight() = Resources.getSystem().displayMetrics.heightPixels
}
How can I get the screen width and height and use this value in:
#Override protected void onMeasure(int widthSpecId, int heightSpecId) {
Log.e(TAG, "onMeasure" + widthSpecId);
setMeasuredDimension(SCREEN_WIDTH, SCREEN_HEIGHT -
game.findViewById(R.id.flag).getHeight());
}
Using this code, you can get the runtime display's width & height:
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
In a view you need to do something like this:
((Activity) getContext()).getWindowManager()
.getDefaultDisplay()
.getMetrics(displayMetrics);
In some scenarios, where devices have a navigation bar, you have to check at runtime:
public boolean showNavigationBar(Resources resources)
{
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
return id > 0 && resources.getBoolean(id);
}
If the device has a navigation bar, then count its height:
private int getNavigationBarHeight() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int usableHeight = metrics.heightPixels;
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int realHeight = metrics.heightPixels;
if (realHeight > usableHeight)
return realHeight - usableHeight;
else
return 0;
}
return 0;
}
So the final height of the device is:
int height = displayMetrics.heightPixels + getNavigationBarHeight();
There is a very simple answer and without pass context
public static int getScreenWidth() {
return Resources.getSystem().getDisplayMetrics().widthPixels;
}
public static int getScreenHeight() {
return Resources.getSystem().getDisplayMetrics().heightPixels;
}
Note: if you want the height include navigation bar, use method below
WindowManager windowManager =
(WindowManager) BaseApplication.getApplication().getSystemService(Context.WINDOW_SERVICE);
final Display display = windowManager.getDefaultDisplay();
Point outPoint = new Point();
if (Build.VERSION.SDK_INT >= 19) {
// include navigation bar
display.getRealSize(outPoint);
} else {
// exclude navigation bar
display.getSize(outPoint);
}
if (outPoint.y > outPoint.x) {
mRealSizeHeight = outPoint.y;
mRealSizeWidth = outPoint.x;
} else {
mRealSizeHeight = outPoint.x;
mRealSizeWidth = outPoint.y;
}
Just to update the answer by parag and SpK to align with current SDK backward compatibility from deprecated methods:
int Measuredwidth = 0;
int Measuredheight = 0;
Point size = new Point();
WindowManager w = getWindowManager();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
w.getDefaultDisplay().getSize(size);
Measuredwidth = size.x;
Measuredheight = size.y;
}else{
Display d = w.getDefaultDisplay();
Measuredwidth = d.getWidth();
Measuredheight = d.getHeight();
}
It’s very easy to get in Android:
int width = Resources.getSystem().getDisplayMetrics().widthPixels;
int height = Resources.getSystem().getDisplayMetrics().heightPixels;
Why not
DisplayMetrics displaymetrics = getResources().getDisplayMetrics();
Then use
displayMetrics.widthPixels
and
displayMetrics.heightPixels
• Kotlin Version via Extension Property
If you want to know the size of the screen in pixels as well as dp, using these extension properties really helps:
DimensionUtils.kt
import android.content.Context
import android.content.res.Resources
import android.graphics.Rect
import android.graphics.RectF
import android.os.Build
import android.util.DisplayMetrics
import android.view.WindowManager
import kotlin.math.roundToInt
/**
* #author aminography
*/
private val displayMetrics: DisplayMetrics by lazy { Resources.getSystem().displayMetrics }
/**
* Returns boundary of the screen in pixels (px).
*/
val screenRectPx: Rect
get() = displayMetrics.run { Rect(0, 0, widthPixels, heightPixels) }
/**
* Returns boundary of the screen in density independent pixels (dp).
*/
val screenRectDp: RectF
get() = screenRectPx.run { RectF(0f, 0f, right.px2dp, bottom.px2dp) }
/**
* Returns boundary of the physical screen including system decor elements (if any) like navigation
* bar in pixels (px).
*/
val Context.physicalScreenRectPx: Rect
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
(applicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager)
.run { DisplayMetrics().also { defaultDisplay.getRealMetrics(it) } }
.run { Rect(0, 0, widthPixels, heightPixels) }
} else screenRectPx
/**
* Returns boundary of the physical screen including system decor elements (if any) like navigation
* bar in density independent pixels (dp).
*/
val Context.physicalScreenRectDp: RectF
get() = physicalScreenRectPx.run { RectF(0f, 0f, right.px2dp, bottom.px2dp) }
/**
* Converts any given number from pixels (px) into density independent pixels (dp).
*/
val Number.px2dp: Float
get() = this.toFloat() / displayMetrics.density
/**
* Converts any given number from density independent pixels (dp) into pixels (px).
*/
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")
println()
val physicalWidthPx = physicalScreenRectPx.width()
val physicalHeightPx = physicalScreenRectPx.height()
println("[PX] physical screen width: $physicalWidthPx , height: $physicalHeightPx")
val physicalWidthDp = physicalScreenRectDp.width()
val physicalHeightDp = physicalScreenRectDp.height()
println("[DP] physical screen width: $physicalWidthDp , height: $physicalHeightDp")
}
}
Result:
When the device is in portrait orientation:
[PX] screen width: 1440 , height: 2392
[DP] screen width: 360.0 , height: 598.0
[PX] physical screen width: 1440 , height: 2560
[DP] physical screen width: 360.0 , height: 640.0
When the device is in landscape orientation:
[PX] screen width: 2392 , height: 1440
[DP] screen width: 598.0 , height: 360.0
[PX] physical screen width: 2560 , height: 1440
[DP] physical screen width: 640.0 , height: 360.0
You can get width and height from context
java:
int width= context.getResources().getDisplayMetrics().widthPixels;
int height= context.getResources().getDisplayMetrics().heightPixels;
kotlin
val width: Int = context.resources.displayMetrics.widthPixels
val height: Int = context.resources.displayMetrics.heightPixels
Try below code :-
1.
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
2.
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // deprecated
int height = display.getHeight(); // deprecated
or
int width = getWindowManager().getDefaultDisplay().getWidth();
int height = getWindowManager().getDefaultDisplay().getHeight();
3.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
metrics.heightPixels;
metrics.widthPixels;
Some methods, applicable for retrieving screen size, are deprecated in API Level 31, including Display.getRealMetrics() and Display.getRealSize(). Starting from API Level 30 we can use WindowManager#getCurrentWindowMetrics(). The clean way to get screen size is to create some Compat class, e.g.:
object ScreenMetricsCompat {
private val api: Api =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) ApiLevel30()
else Api()
/**
* Returns screen size in pixels.
*/
fun getScreenSize(context: Context): Size = api.getScreenSize(context)
#Suppress("DEPRECATION")
private open class Api {
open fun getScreenSize(context: Context): Size {
val display = context.getSystemService(WindowManager::class.java).defaultDisplay
val metrics = if (display != null) {
DisplayMetrics().also { display.getRealMetrics(it) }
} else {
Resources.getSystem().displayMetrics
}
return Size(metrics.widthPixels, metrics.heightPixels)
}
}
#RequiresApi(Build.VERSION_CODES.R)
private class ApiLevel30 : Api() {
override fun getScreenSize(context: Context): Size {
val metrics: WindowMetrics = context.getSystemService(WindowManager::class.java).currentWindowMetrics
return Size(metrics.bounds.width(), metrics.bounds.height())
}
}
}
Calling ScreenMetricsCompat.getScreenSize(this).height in Activity we can get a screen height.
I suggest you create extension functions.
/**
* Return the width and height of the screen
*/
val Context.screenWidth: Int
get() = resources.displayMetrics.widthPixels
val Context.screenHeight: Int
get() = resources.displayMetrics.heightPixels
/**
* Pixel and Dp Conversion
*/
val Float.toPx get() = this * Resources.getSystem().displayMetrics.density
val Float.toDp get() = this / Resources.getSystem().displayMetrics.density
val Int.toPx get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp get() = (this / Resources.getSystem().displayMetrics.density).toInt()
DisplayMetrics lDisplayMetrics = getResources().getDisplayMetrics();
int widthPixels = lDisplayMetrics.widthPixels;
int heightPixels = lDisplayMetrics.heightPixels;
For kotlin user's
fun Activity.displayMetrics(): DisplayMetrics {
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
return displayMetrics
}
And in Activity you could use it like
resources.displayMetrics.let { displayMetrics ->
val height = displayMetrics.heightPixels
val width = displayMetrics.widthPixels
}
Or in fragment
activity?.displayMetrics()?.run {
val height = heightPixels
val width = widthPixels
}
As getMetrics and getRealMetrics are deprecated, Google recommends to determine the screen width and height as follows:
WindowMetrics windowMetrics = getActivity().getWindowManager().getMaximumWindowMetrics();
Rect bounds = windowMetrics.getBounds();
int widthPixels = bounds.width();
int heightPixels = bounds.height();
However, I've figured out another methode that gives me the same results:
Configuration configuration = mContext.getResources().getConfiguration();
Display.Mode mode = display.getMode();
int widthPixels = mode.getPhysicalWidth();
int heightPixels = mode.getPhysicalHeight();
None of the answers here work correctly for Chrome OS multiple displays, or soon-to-come Foldables.
When looking for the current configuration, always use the configuration from your current activity in getResources().getConfiguration(). Do not use the configuration from your background activity or the one from the system resource. The background activity does not have a size, and the system's configuration may contain multiple windows with conflicting sizes and orientations, so no usable data can be extracted.
So the answer is
val config = context.getResources().getConfiguration()
val (screenWidthPx, screenHeightPx) = config.screenWidthDp.dp to config.screenHeightDp.dp
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int width = dimension.widthPixels;
int height = dimension.heightPixels;
Get the value of screen width and height.
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
As an android official document said for the default display use Context#getDisplay() because this method was deprecated in API level 30.
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
This code given below is in kotlin and is written accodring to the latest version of Android help you determine width and height:
fun getWidth(context: Context): Int {
var width:Int = 0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val displayMetrics = DisplayMetrics()
val display: Display? = context.getDisplay()
display!!.getRealMetrics(displayMetrics)
return displayMetrics.widthPixels
}else{
val displayMetrics = DisplayMetrics()
this.windowManager.defaultDisplay.getMetrics(displayMetrics)
width = displayMetrics.widthPixels
return width
}
}
fun getHeight(context: Context): Int {
var height: Int = 0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val displayMetrics = DisplayMetrics()
val display = context.display
display!!.getRealMetrics(displayMetrics)
return displayMetrics.heightPixels
}else {
val displayMetrics = DisplayMetrics()
this.windowManager.defaultDisplay.getMetrics(displayMetrics)
height = displayMetrics.heightPixels
return height
}
}
fun Activity.getRealScreenSize(): Pair<Int, Int> { //<width, height>
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val size = Point()
display?.getRealSize(size)
Pair(size.x, size.y)
} else {
val size = Point()
windowManager.defaultDisplay.getRealSize(size)
Pair(size.x, size.y)
}}
This is an extension function and you can use in your activity in this way:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val pair = getRealScreenSize()
pair.first //to get width
pair.second //to get height
}
I use the following code to get the screen dimensions
getWindow().getDecorView().getWidth()
getWindow().getDecorView().getHeight()
Full way to do it, that returns the true resolution (including when the user has changed the resolution) is to use "getRealSize".
I've noticed that all other available functions, including the ones the docs say to use instead of this - have some cases that the result is smaller.
Here's the code to do it:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Point size = new Point();
wm.getDefaultDisplay().getRealSize(size);
final int width = size.x, height = size.y;
And since this can change on different orientation, here's a solution (in Kotlin), to get it right no matter the orientation:
/**
* returns the natural orientation of the device: Configuration.ORIENTATION_LANDSCAPE or Configuration.ORIENTATION_PORTRAIT .<br></br>
* The result should be consistent no matter the orientation of the device
*/
#JvmStatic
fun getScreenNaturalOrientation(context: Context): Int {
//based on : http://stackoverflow.com/a/9888357/878126
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val config = context.resources.configuration
val rotation = windowManager.defaultDisplay.rotation
return if ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) && config.orientation == Configuration.ORIENTATION_LANDSCAPE || (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) && config.orientation == Configuration.ORIENTATION_PORTRAIT)
Configuration.ORIENTATION_LANDSCAPE
else
Configuration.ORIENTATION_PORTRAIT
}
/**
* returns the natural screen size (in pixels). The result should be consistent no matter the orientation of the device
*/
#JvmStatic
fun getScreenNaturalSize(context: Context): Point {
val screenNaturalOrientation = getScreenNaturalOrientation(context)
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val point = Point()
wm.defaultDisplay.getRealSize(point)
val currentOrientation = context.resources.configuration.orientation
if (currentOrientation == screenNaturalOrientation)
return point
else return Point(point.y, point.x)
}
Display display = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int mWidthScreen = display.getWidth();
int mHeightScreen = display.getHeight();
public class DisplayInfo {
int screen_height=0, screen_width=0;
WindowManager wm;
DisplayMetrics displaymetrics;
DisplayInfo(Context context) {
getdisplayheightWidth(context);
}
void getdisplayheightWidth(Context context) {
wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
displaymetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(displaymetrics);
screen_height = displaymetrics.heightPixels;
screen_width = displaymetrics.widthPixels;
}
public int getScreen_height() {
return screen_height;
}
public int getScreen_width() {
return screen_width;
}
}
Seems like all these answers fail for my Galaxy M51 with Android 11. After doing some research around I found this code :
WindowMetrics windowmetrics = MainActivity.getWindowManager().getCurrentWindowMetrics();
Rect rect = windowmetrics.getBounds();
int width = rect.right;
int height =rect.bottom;
shows my true device resolution of 1080x2400, the rest only return 810x1800.
Methods shown here are deprecated/outdated but this is still working.Require API 13
check it out
Display disp= getWindowManager().getDefaultDisplay();
Point dimensions = new Point();
disp.getSize(size);
int width = size.x;
int height = size.y;
As an android official document said for the default display use Context#getDisplay() because this method was deprecated in API level 30.
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
This bowl of code help to determine width and height.
public static int getWidth(Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
Display display = context.getDisplay();
if (display != null) {
display.getRealMetrics(displayMetrics);
return displayMetrics.widthPixels;
}
return -1;
}
For the Height:
public static int getHeight(Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
Display display = context.getDisplay();
if (display != null) {
display.getRealMetrics(displayMetrics);
return displayMetrics.heightPixels;
}
return -1;
}
Try this code for Kotlin
val display = windowManager.defaultDisplay
val size = Point()
display.getSize(size)
var DEVICE_WIDTH = size.x
var DEVICE_HEIGHT = size.y
Just use the function below that returns width and height of the screen size as an array of integers
private int[] getScreenSIze(){
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int h = displaymetrics.heightPixels;
int w = displaymetrics.widthPixels;
int[] size={w,h};
return size;
}
On your onCreate function or button click add the following code to output the screen sizes as shown below
int[] screenSize= getScreenSIze();
int width=screenSize[0];
int height=screenSize[1];
screenSizes.setText("Phone Screen sizes \n\n width = "+width+" \n Height = "+height);
I updated answer for Kotlin language!
For Kotlin: You should call Window Manager and get metrics. After that easy way.
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
var width = displayMetrics.widthPixels
var height = displayMetrics.heightPixels
How can we use it effectively in independent activity way with Kotlin language?
Here, I created a method in general Kotlin class. You can use it in all activities.
private val T_GET_SCREEN_WIDTH:String = "screen_width"
private val T_GET_SCREEN_HEIGHT:String = "screen_height"
private fun getDeviceSizes(activity:Activity, whichSize:String):Int{
val displayMetrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
return when (whichSize){
T_GET_SCREEN_WIDTH -> displayMetrics.widthPixels
T_GET_SCREEN_HEIGHT -> displayMetrics.heightPixels
else -> 0 // Error
}
}
I found weigan's answer best one in this page, here is how you can use that in Xamarin.Android:
public int GetScreenWidth()
{
return Resources.System.DisplayMetrics.WidthPixels;
}
public int GetScreenHeight()
{
return Resources.System.DisplayMetrics.HeightPixels;
}
Screen resolution is total no of pixel in screen. Following program will extract the screen resolution of the device. It will print screen width and height. Those values are in pixel.
public static Point getScreenResolution(Context context) {
// get window managers
WindowManager manager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point point = new Point();
display.getSize(point);
// get width and height
int width = point.x;
int height = point.y;
return point;
}