美文网首页
Android刘海屏高度获取(小米,华为,荣耀,vivo,OPP

Android刘海屏高度获取(小米,华为,荣耀,vivo,OPP

作者: 没有小叮当的大雄 | 来源:发表于2021-03-22 14:46 被阅读0次

    1.第一步 首先判断Android手机是否是有刘海

    判断小米手机是否有刘海屏

    /**
     * 小米刘海屏判断
     * @return 0 if it is not notch ; return 1 means notch
     * @throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static boolean hasNotchAtXiaoMi() {
            return getInt("ro.miui.notch") == 1;
    }
    public static int getInt(String key) {
            int result = 0;
            if (android.os.Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) {
                try {
                    ClassLoader classLoader = Application.getInstance().getClassLoader();
                    @SuppressWarnings("rawtypes")
                    Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");
                    //参数类型
                    @SuppressWarnings("rawtypes")
                    Class[] paramTypes = new Class[2];
                    paramTypes[0] = String.class;
                    paramTypes[1] = int.class;
                    Method getInt = SystemProperties.getMethod("getInt", paramTypes);
                    //参数
                    Object[] params = new Object[2];
                    params[0] = new String(key);
                    params[1] = new Integer(0);
                    result = (Integer) getInt.invoke(SystemProperties, params);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return result;
    }
    

    判断华为和荣耀手机是否有刘海屏

    /**
     * 华为刘海屏判断
     * @return
     */
    public static boolean hasNotchAtHuawei() {
            boolean ret = false;
            try {
                ClassLoader classLoader = Application.getInstance().getClassLoader();
                Class HwNotchSizeUtil = classLoader.loadClass("com.huawei.android.util.HwNotchSizeUtil");
                Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
                ret = (boolean) get.invoke(HwNotchSizeUtil);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ret;
    }
    

    判断OPPO手机是否有刘海屏

    /**
     * OPPO刘海屏判断
     * @return
     */
    public static boolean hasNotchAtOPPO() {
            return Application.getInstance().getPackageManager()
                    .hasSystemFeature("com.oppo.feature.screen.heteromorphism");
    }
    

    判断VIVO手机是否有刘海屏

    /**
     * VIVO刘海屏判断
     * @return
     */
    public static boolean hasNotchAtVivo() {
            boolean ret = false;
            try {
                ClassLoader classLoader = Application.getInstance().getClassLoader();
                Class FtFeature = classLoader.loadClass("android.util.FtFeature");
                Method method = FtFeature.getMethod("isFeatureSupport", int.class);
                ret = (boolean) method.invoke(FtFeature, VIVO_NOTCH);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ret;
    }
    

    判断三星手机是否有刘海屏

    /**
    * 判断三星手机是否有刘海屏
    * @return
    */
    private static boolean hasNotchSamsung() {
            if (android.os.Build.MANUFACTURER.equalsIgnoreCase("samsung")) {
                try {
                    final Resources res = Application.getInstance().getResources();
                    final int resId = res.getIdentifier("config_mainBuiltInDisplayCutout", "string", "android");
                    final String spec = resId > 0 ? res.getString(resId) : null;
                    return spec != null && !TextUtils.isEmpty(spec);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return false;
    }
    

    其他Android手机是否有刘海屏 通过Google Android SDK的方法进行判断

    /**
     * @param activity
    * @return
    */
    private static boolean isOtherBrandHasNotch(Activity activity) {
            if (activity != null && activity.getWindow() != null) {
                View decorView = activity.getWindow().getDecorView();
                if ((Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M)) {
                    WindowInsets windowInsets = decorView.getRootWindowInsets();
                    if (windowInsets != null) {
                        if ((Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P)) {
                            DisplayCutout displayCutout = windowInsets.getDisplayCutout();
                            if (displayCutout != null) {
                                List<Rect> rects = displayCutout.getBoundingRects();
                                if (rects != null && rects.size() > 0) {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
       return false;
    }
    

    综合上边所有的方法

    /**
     * 是否是刘海或是钻孔屏幕 全局只取一次
     * @return
     */
     public static boolean hasNotch(Activity activity) {
            if (!hasExecuteNotch) {
                if (hasNotchAtXiaoMi() || hasNotchAtHuawei() || hasNotchAtOPPO()
                        || hasNotchAtVivo() || hasNotchSamsung() || isOtherBrandHasNotch(activity)) {
                    isNotch = true;
                } else {
                    isNotch = false;
                }
                hasExecuteNotch = true;
            }
            return isNotch;
    }
    

    2.如果是刘海屏获取刘海的高度

    /**
     * 获取刘海高度
     */
    public static int getNotchHeight(Activity activity) {
            String manufacturer = android.os.Build.MANUFACTURER.toLowerCase();
            if (hasNotch(activity)) {
                //有刘海才获取高度 否则默认刘海高度是0
                if (manufacturer.equalsIgnoreCase("xiaomi")) {
                    notchHeight = getSysStatusBarHeight();//小米刘海会比状态栏小 直接获取状态栏高度
                } else if (manufacturer.equalsIgnoreCase("huawei") || manufacturer.equalsIgnoreCase("honour")) {
                    notchHeight = getNotchSizeAtHuaWei();
                } else if (manufacturer.equalsIgnoreCase("vivo")) {
                    //VIVO是32dp
                    notchHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                            32, Application.getInstance().getResources().getDisplayMetrics());
                } else if (manufacturer.equalsIgnoreCase("oppo")) {
                    notchHeight = 80;//oppo当时是固定数值
                } else if (android.os.Build.MANUFACTURER.equalsIgnoreCase("smartisan")) {
                    notchHeight = 82;//当时锤子PDF文档上是固定数值
                }  else {
                    //其他品牌手机
                    if (activity != null && activity.getWindow() != null) {
                        View decorView = activity.getWindow().getDecorView();
                        if ((Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M)) {
                            WindowInsets windowInsets = decorView.getRootWindowInsets();
                            if (windowInsets != null) {
                                if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)) {
                                    DisplayCutout displayCutout = windowInsets.getDisplayCutout();
                                    if (displayCutout != null) {
                                        List<Rect> rects = displayCutout.getBoundingRects();
                                        if (rects != null && rects.size() > 1) {
                                            if (rects.get(0) != null) {
                                                notchHeight = rects.get(0).bottom;
                                                return notchHeight;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return notchHeight;
            }
            return 0;
        }
    

    获取华为&荣耀手机刘海屏高度

    /**
         * 华为获取刘海高度
         * 获取刘海尺寸:width、height
         * int[0]值为刘海宽度 int[1]值为刘海高度
    */
    public static int getNotchSizeAtHuaWei() {
            int height = 0;
            try {
                ClassLoader cl = Application.getInstance().getClassLoader();
                Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
                Method get = HwNotchSizeUtil.getMethod("getNotchSize");
                int[] ret = (int[]) get.invoke(HwNotchSizeUtil);
                height = ret[1];
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return height;
    }
    

    3.状态栏和刘海高度中获取更大的值 作为顶部适配高度 每次APP启动只获取一次

    public static int getStatusBarHeight(Activity activity) {
            if (statusBarHeight == 0) {
                int height = getSysStatusBarHeight();
                int notchHeight = ScreenUtil.getNotchHeight(activity);
                statusBarHeight = Math.max(height, notchHeight);
            }
            return statusBarHeight;
    }
    

    获取手机状态栏高度

    /**
     * 获得手机状态栏高度
     * @return
     */
    public static int getSysStatusBarHeight() {
            int result = 0;
            Resources resources = Application.getInstance().getResources();
            int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
                result = resources.getDimensionPixelSize(resourceId);
            }
            if (result == 0) {
                result = resources.getDimensionPixelSize(R.dimen.default_48PX);
            }
            return result;
        }
    

    以上代码已经上线,如有适配更新请各位指正。!_!

    相关文章

      网友评论

          本文标题:Android刘海屏高度获取(小米,华为,荣耀,vivo,OPP

          本文链接:https://www.haomeiwen.com/subject/cbkzcltx.html