Android 检测手机是否是异形屏,刘海屏,水滴屏,挖孔屏

news/2024/11/16 8:39:23/

全面屏适配请阅读本人另外一篇博客:

https://blog.csdn.net/zhao8856234/article/details/117744924?spm=1001.2014.3001.5501

直接上工具类,复制使用即可:

public class NotchUtil {private static final String SP_NAME = "MY_NOTCH_SP";//保存异形屏Nameprivate static final String KEY_IS_NOTCH_SCREEN = "KEY_IS_NOTCH_SCREEN";//是否是异形屏KEY/*** 保存当前手机是否是异形屏** @param isNotchScreen 是否是异形屏(刘海屏,水滴屏,挖孔屏等)*/public static void saveScreen(Context context, boolean isNotchScreen) {SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);SharedPreferences.Editor edit = sp.edit();if (!sp.contains(KEY_IS_NOTCH_SCREEN)) {//不存在的时候保存edit.putBoolean(KEY_IS_NOTCH_SCREEN, isNotchScreen);} else if (sp.contains(KEY_IS_NOTCH_SCREEN) && !sp.getBoolean(KEY_IS_NOTCH_SCREEN, false)) {//当这个值存在并且是false的时候也保存edit.putBoolean(KEY_IS_NOTCH_SCREEN, isNotchScreen);}//当这个值存在并且为true的时候不去覆盖数据.edit.commit();}/*** 获取保存在本地的屏幕类型,是否是异形屏(刘海屏,水滴屏,挖孔屏等)*/public static boolean getScreenType(Context context) {return context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE).getBoolean(KEY_IS_NOTCH_SCREEN, false);}/*** 判断是否是8.0系统之后的异形屏(刘海屏,水滴屏,挖孔屏等)* 必须在Activity的onAttachedToWindow()方法中才会生效,其他地方windowInsets为 null* onCreate->onStart->onResume->onAttachedToWindow*/public static boolean IsNotchScreen(Context context, WindowInsets windowInsets) {if (Build.VERSION.SDK_INT >= 26) {if (isAndroidPNotchScreen(windowInsets) || hasNotchInScreenAtVivo(context) || hasNotchInScreenAtOppo(context)|| hasNotchInScreenAtHuawei(context) || hasNotchInScreenAtMI()) { //TODO 各种品牌return true;}}return false;}/*** Android P 异形屏判断** @param windowInsets 必须使用控件的setOnApplyWindowInsetsListener()接口回调方法中的才或者在Activity的*                     onAttachedToWindow()方法中调用getWindow().getDecorView().getRootWindowInsets();*                     其他地方获取会直接为空*/@SuppressLint("NewApi")public static boolean isAndroidPNotchScreen(WindowInsets windowInsets) {boolean isNotchScreen = false;if (PlatformUtils.isAndroidP() && null != windowInsets) {DisplayCutout cutout = windowInsets.getDisplayCutout();if (cutout != null) {List<Rect> rects = cutout.getBoundingRects();if (rects != null && rects.size() > 0) {isNotchScreen = true;}}}return isNotchScreen;}/*** 判断是否华为异形屏*/public static boolean hasNotchInScreenAtHuawei(Context context) {boolean ret = false;try {ClassLoader cl = context.getClassLoader();Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");ret = (boolean) get.invoke(HwNotchSizeUtil);} catch (ClassNotFoundException e) {PlatformLog.ee("hasNotchInScreenAtHuawei()-> ClassNotFoundException");} catch (NoSuchMethodException e) {PlatformLog.ee("hasNotchInScreenAtHuawei()-> NoSuchMethodException");} catch (Exception e) {PlatformLog.ee("hasNotchInScreenAtHuawei()-> Exception");} finally {PlatformLog.e("hasNotchInScreenAtHuawei()-> ClassNotFoundException");return ret;}}/*** 获取华为O版本异形屏宽高*/public static int[] getNotchSizeForHuawei(Context context) {int[] ret = new int[]{0, 0};try {ClassLoader cl = context.getClassLoader();Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");Method get = HwNotchSizeUtil.getMethod("getNotchSize");ret = (int[]) get.invoke(HwNotchSizeUtil);} catch (ClassNotFoundException e) {PlatformLog.ee("HUAWEI-getNotchSize()-> ClassNotFoundException");} catch (NoSuchMethodException e) {PlatformLog.ee("HUAWEI-getNotchSize()-> NoSuchMethodException");} catch (Exception e) {PlatformLog.ee("HUAWEI-getNotchSize()-> Exception");} finally {return ret;}}/*** 判断oppo 机型是否异形屏*/public static boolean hasNotchInScreenAtOppo(Context context) {return context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");}public static String getNotchOppoProperty() {String value = "";try {Class<?> cls = Class.forName("android.os.SystemProperties");Method hideMethod = cls.getMethod("get", String.class);Object object = cls.newInstance();value = (String) hideMethod.invoke(object, "ro.oppo.screen.heteromorphism");} catch (ClassNotFoundException e) {PlatformLog.ee("getNotchOppoProperty()->get error() ", e.getMessage());} catch (NoSuchMethodException e) {PlatformLog.ee("getNotchOppoProperty()->get error() ", e.getMessage());} catch (InstantiationException e) {PlatformLog.ee("getNotchOppoProperty()->get error() ", e.getMessage());} catch (IllegalAccessException e) {PlatformLog.ee("getNotchOppoProperty()->get error() ", e.getMessage());} catch (IllegalArgumentException e) {PlatformLog.ee("getNotchOppoProperty()->get error() ", e.getMessage());} catch (InvocationTargetException e) {PlatformLog.ee("getNotchOppoProperty()->get error() ", e.getMessage());}return value;}/*** 判断vivo机型是否异形屏*/public static final int NOTCH_IN_SCREEN_VOIO = 0x00000020;//是否有凹槽public static final int ROUNDED_IN_SCREEN_VOIO = 0x00000008;//是否有圆角public static boolean hasNotchInScreenAtVivo(Context context) {boolean ret = false;try {ClassLoader cl = context.getClassLoader();Class FtFeature = cl.loadClass("android.util.FtFeature");Method get = FtFeature.getMethod("isFeatureSupport", int.class);ret = (boolean) get.invoke(FtFeature, NOTCH_IN_SCREEN_VOIO);} catch (ClassNotFoundException e) {PlatformLog.ee("hasNotchInScreenAtVivo()-> ClassNotFoundException");} catch (NoSuchMethodException e) {PlatformLog.ee("hasNotchInScreenAtVivo()-> NoSuchMethodException");} catch (Exception e) {PlatformLog.ee("hasNotchInScreenAtVivo()-> Exception");} finally {return ret;}}/*** 判断小米机型是否异形屏*/private static Method getBooleanMethod = null;public static boolean hasNotchInScreenAtMI() {try {if (getBooleanMethod == null) {getBooleanMethod = Class.forName("android.os.SystemProperties").getMethod("getBoolean", String.class, boolean.class);}//Log.i(TAG,"getBoolean:"+getBooleanMethod.invoke(null, key, def));return (Boolean) getBooleanMethod.invoke(null, "ro.miui.notch", false);} catch (Exception e) {return false;}}}

调用方法:

1. Activity调用:

/*** 生命周期 onCreate->onStart->onResume->onAttachedToWindow* 判断是否是异形屏,必须在此方法*/@Overridepublic void onAttachedToWindow() {super.onAttachedToWindow();if (Build.VERSION.SDK_INT >= 23) {boolean isNotchScreen = NotchUtil.IsNotchScreen(this, getWindow().getDecorView().getRootWindowInsets());NotchUtil.saveScreen(this, isNotchScreen);}}

2. 控件调用:

 public static void setNotchScreenParentLayout(final Context context, final View parentLayout) {//异形屏 刘海屏从安卓8.0系统开始推出if (null != context && null != parentLayout && Build.VERSION.SDK_INT >= 26) {//设置异形屏的安全区域,避免遮挡内容parentLayout.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {@Overridepublic WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {boolean isNotchScreen = NotchUtil.IsNotchScreen(context, windowInsets);if (isNotchScreen && null != windowInsets) {parentLayout.setPadding(0, 0, 0, 0);if (Build.VERSION.SDK_INT >= 28 && null != windowInsets.getDisplayCutout()) {DisplayCutout cutout = windowInsets.getDisplayCutout();if (cutout != null) {List<Rect> rects = cutout.getBoundingRects();if (rects != null && rects.size() > 0) {PlatformLog.e("异形屏->安卓9.0之后系统,间距左" + cutout.getSafeInsetLeft() +",上:" + cutout.getSafeInsetTop() + ",右:" + cutout.getSafeInsetRight() + ",下:" + cutout.getSafeInsetBottom());parentLayout.setPadding(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(),cutout.getSafeInsetRight(), cutout.getSafeInsetBottom());}}}}return windowInsets;}});}}

 


http://www.ppmy.cn/news/192227.html

相关文章

Android各种屏,刘海屏,打孔屏满屏显示

试了很多种方法&#xff0c;只有这种满屏效果最好。 if(Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {WindowManager.LayoutParams lp getWindow().getAttributes();lp.layoutInDisplayCutoutMode WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_E…

iOS——判断刘海屏

在写项目时&#xff0c;发现在非刘海屏型号的iPhone上测试的UI界面&#xff0c;有时候在刘海屏iPhone会被遮挡。这时候&#xff0c;我们需要判断当前设备是否是刘海屏&#xff0c;以来对UI代码做相应的适配&#xff0c;以下是学习的几种方案。 判断手机型号 iPhone的发展历史…

Android 浅谈适配全面屏、刘海屏、水滴屏

对刘海屏、水滴屏做适配前&#xff0c;先在此给出一个基本概念&#xff1a;何谓刘海屏&#xff1f;何谓水滴屏&#xff1f; 上述两种屏幕都可以统称为刘海屏&#xff0c;不过对于右侧较小的刘海&#xff0c;业界一般称为水滴屏或美人尖。 目前国内流行的手机厂商主要有&#x…

android兼容小米xiaomi刘海屏解决方案

引用自小米官方文档&#xff0c;这里缩减了一些内容&#xff0c;捡取重要内容。 转载请标明出处&#xff1a; https://blog.csdn.net/DJY1992/article/details/80688376 本文出自:【奥特曼超人的博客】 推荐&#xff1a; android 兼容所有刘海屏的方案大全android 兼容huaw…

Android刘海屏、水滴屏全面屏适配详解,androidui基础教程

适配方式 适配方式有两种&#xff1a; 将targetSdkVersion版本设置到API 24及以上&#xff1b; 这个操作将会为<application> 标签隐式添加一个属性&#xff0c;android:resizeableActivity“true”, 该属性的作用后面将详细说明。 在 标签中增加属性&#xff1a;and…

Android刘海屏、水滴屏全面屏适配详解大厂直通车!

为什么想跳槽&#xff1f; 简单说一下当时的状况&#xff0c;我在这家公司做了两年多&#xff0c;这两年多完成了一个大项目&#xff0c;作为开发的核心主力&#xff0c;开发压力很大&#xff0c;特别是项目上线前的几个月是非常辛苦&#xff0c;几乎每晚都要加班到12点以后&a…

Android适配全面屏/刘海屏

目前国内厂商已经推出的刘海屏Android手机有华为P20 pro&#xff0c; vivo X21&#xff0c;OPPO R15。 1.华为刘海屏的官方适配文档 https://devcenter-test.huawei.com/consumer/cn/devservice/doc/50114 2.oppo刘海屏官方文档&#xff1a; https://open.oppomobile.com/…

浅谈Maven依赖冲突与依赖管理

目录 什么是依赖冲突 为什么会产生冲突 依赖冲突的解决和避免 Maven的仲裁机制