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()
}
}
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With