package com.example.basecore.util; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.Rect; import android.util.DisplayMetrics; import android.util.Size; import android.view.Display; import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowMetrics; import androidx.annotation.NonNull; import androidx.annotation.Nullable; public class ScreenUtils { public static final int DEF_VALUE = 0;// 默认值 // 获取App显示区 宽高 public static int getAppDisplayWidth(Context context) { return getAppDisplayRect(context, DEF_VALUE).width(); } public static int getAppDisplayWidth(Context context, int defValue) { return getAppDisplayRect(context, defValue).width(); } public static int getAppDisplayHeight(Context context) { return getAppDisplayRect(context, DEF_VALUE).height(); } public static int getAppDisplayHeight(Context context, int defValue) { return getAppDisplayRect(context, defValue).height(); } // 获取设备屏幕 宽高 public static int getDeviceScreenWidth(Context context) { return getDeviceScreenRect(context, DEF_VALUE).width(); } public static int getDeviceScreenWidth(Context context, int defValue) { return getDeviceScreenRect(context, defValue).width(); } public static int getDeviceScreenHeight(Context context) { return getDeviceScreenRect(context, DEF_VALUE).height(); } public static int getDeviceScreenHeight(Context context, int defValue) { return getDeviceScreenRect(context, defValue).height(); } // 获取设备屏幕 宽高 public static int getDeviceScreenWidthCache(Context context) { return getDeviceScreenRectCache(context, DEF_VALUE).width(); } public static int getDeviceScreenWidthCache(Context context, int defValue) { return getDeviceScreenRectCache(context, defValue).width(); } public static int getDeviceScreenHeightCache(Context context) { return getDeviceScreenRectCache(context, DEF_VALUE).height(); } public static int getDeviceScreenHeightCache(Context context, int defValue) { return getDeviceScreenRectCache(context, defValue).height(); } /** * 获取App显示区 高宽比 */ public static float getAppDisplayHeightWidthRatio(Context context) { Rect rect = getAppDisplayRect(context, DEF_VALUE); if (rect.width() != 0) { return (float) rect.height() / (float) rect.width(); } return 0F; } /** * 获取设备屏幕 高宽比 */ public static float getDeviceHeightWidthRatio(Context context) { Rect rect = getDeviceScreenRect(context, DEF_VALUE); if (rect.width() != 0) { return (float) rect.height() / (float) rect.width(); } return 0F; } @NonNull public static Size getAppDisplaySize(Context context, int defValue) { Size size = null; try { size = getAppDisplaySize(context); } catch (Exception e) { } if (size == null) size = new Size(defValue, defValue); return size; } /** * 获得App可用的显示区域大小 * 不包含 导航条 和 刘海屏 区域。 */ @Nullable public static Size getAppDisplaySize(Context context) { WindowManager wm = getWindowManager(context); if (wm == null) return null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { final WindowMetrics metrics = wm.getCurrentWindowMetrics(); // Gets all excluding insets final WindowInsets windowInsets = metrics.getWindowInsets(); Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout()); int insetsWidth = insets.right + insets.left; int insetsHeight = insets.top + insets.bottom; // Legacy size that Display#getSize reports final Rect bounds = metrics.getBounds(); Size size = new Size(bounds.width() - insetsWidth, bounds.height() - insetsHeight); log("new-app-size: " + size.getWidth() + " - " + size.getHeight()); return size; } else { Display display = wm.getDefaultDisplay(); if (display != null) { DisplayMetrics dm = new DisplayMetrics(); // Android 11 弃用 Display.getSize()、Display.getMetrics() display.getMetrics(dm); log("app-size: " + dm.widthPixels + " " + dm.heightPixels); return new Size(dm.widthPixels, dm.heightPixels); } } return null; } @NonNull public static Rect getAppDisplayRect(Context context, int defValue) { Rect rect = null; try { rect = getAppDisplayRect(context); } catch (Exception e) { } if (rect == null) rect = new Rect(defValue, defValue, defValue, defValue); return rect; } /** * 获得App可用的显示区域 * 表示显示器的大小减去任何系统装饰,不包含 导航条 和 刘海屏 区域。 */ @Nullable public static Rect getAppDisplayRect(Context context) { // androidx.window.layout.WindowMetricsCalculatorCompat WindowManager wm = getWindowManager(context); if (wm == null) return null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { final WindowMetrics metrics = wm.getCurrentWindowMetrics(); // Gets all excluding insets final WindowInsets windowInsets = metrics.getWindowInsets(); Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout()); // Legacy size that Display#getSize reports final Rect bounds = metrics.getBounds(); Rect rect = new Rect( bounds.left + insets.left, bounds.top + insets.top, bounds.right - insets.right, bounds.bottom - insets.bottom ); log("new-app-rect: " + rect.width() + " - " + rect.height()); return rect; } else { Display display = wm.getDefaultDisplay(); if (display != null) { DisplayMetrics dm = new DisplayMetrics(); // Android 11 弃用 Display.getSize()、Display.getMetrics() display.getMetrics(dm); log("app-rect: " + dm.widthPixels + " " + dm.heightPixels); return new Rect(0, 0, dm.widthPixels, dm.heightPixels); } } return null; } @NonNull public static Rect getDeviceScreenRect(Context context, int defValue) { Rect rect = null; try { rect = getDeviceScreenRect(context); } catch (Exception e) { } if (rect == null) rect = new Rect(defValue, defValue, defValue, defValue); return rect; } /** * 获取设备屏幕大小缓存,在application的onConfigurationChanged中重置 */ public static Rect mDeviceScreenRect; public static Rect getDeviceScreenRectCache(Context context, int defValue) { if (mDeviceScreenRect == null) { mDeviceScreenRect = getDeviceScreenRect(context, defValue); } return mDeviceScreenRect; } /** * 获得设备屏幕大小,包含所有系统栏区域 * 当系统模拟较小的显示器时,它可能小于物理尺寸。 *
* Mi 11 : (0, 0 - 1440, 3200) * 1+ 9 : (0, 0 - 1080, 2400) */ @Nullable public static Rect getDeviceScreenRect(Context context) { // androidx.window.layout.WindowMetricsCalculatorCompat WindowManager wm = getWindowManager(context); if (wm == null) return null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { Rect rect = wm.getCurrentWindowMetrics().getBounds(); log("new-device: " + rect.width() + " - " + rect.height()); return rect; } else { Display display = wm.getDefaultDisplay(); if (display != null) { DisplayMetrics dm = new DisplayMetrics(); // Android 12 弃用 Display.getRealSize()、Display.getRealMetrics() display.getRealMetrics(dm); log("device: " + dm.widthPixels + " " + dm.heightPixels); return new Rect(0, 0, dm.widthPixels, dm.heightPixels); } } return null; } /** * 获得屏幕分辨率 */ public static int getDensityDpi(Context context) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { return context.getResources().getConfiguration().densityDpi; } else { WindowManager wm = getWindowManager(context); if (wm == null) return 0; Display display = wm.getDefaultDisplay(); if (display == null) return 0; DisplayMetrics outMetrics = new DisplayMetrics(); display.getMetrics(outMetrics); return outMetrics.densityDpi; } } @Nullable private static WindowManager getWindowManager(Context context) { if (context == null) return null; if (context instanceof Activity) { return ((Activity) context).getWindowManager(); } else { return (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); } } public static void updateApplicationDisplay(Context context) { // Size size = ScreenUtils.getAppDisplaySize(context, -1); // int densityDpi = getDensityDpi(context); // if (size.getWidth() > 0 && size.getHeight() > 0) { // log("update-application: " + size.getWidth() + " - " + size.getHeight() + " - " + densityDpi); // WeiboApplication.setDisplay(size.getWidth(), size.getHeight(), densityDpi); // } } private static void log(String msg) { // LogUtil.i("Display12", msg); } public static int getSystemStatusBarHeight(Context context) { return getSystemStatusBarHeight(context, 0); } public static int getSystemStatusBarHeight(Context context, int defValue) { if (context == null) return defValue; Resources resources = context.getResources(); int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { return resources.getDimensionPixelSize(resourceId); } return defValue; } }