'Getter for defaultDisplay: Display!' is deprecated. Deprecated in Java

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.



Solution 1:[1]

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

Solution 2:[2]

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

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

Solution 3:[3]

This method was deprecated in API level 30.

Use Context.getDisplay() instead.

Deprecated method: getDefaultDisplay

New Method: getDisplay

Solution 4:[4]

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

Solution 5:[5]

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

Solution 6:[6]

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

Solution 7:[7]

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

        }

    }
}

Solution 8:[8]

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

Solution 9:[9]

Instead of doing that, do this and save the hassle of writing more code.

val dialog = super.onCreateDialog(savedInstanceState)
dialog.setOnShowListener {
    val bottomSheetDialog = it as BottomSheetDialog
    val parentLayout =
        bottomSheetDialog.findViewById<View>(R.id.design_bottom_sheet)
    parentLayout?.let { bottomSheet ->
        val behaviour = BottomSheetBehavior.from(bottomSheet)
        val layoutParams = bottomSheet.layoutParams
        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT
        bottomSheet.layoutParams = layoutParams
        behaviour.state = BottomSheetBehavior.STATE_EXPANDED
    }
}
return dialog

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tyler
Solution 2
Solution 3 tyler
Solution 4
Solution 5
Solution 6 Roxin Vivian Topp
Solution 7
Solution 8
Solution 9 John De la cruz