android8.0 小米、vivo、oppo、华为刘海屏适配

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/iamZ2z/article/details/84063943

国内手机厂商参差不齐,google官方9.0才出刘海屏适配,国内的厂商各有各的方法,苦了我们这些程序员,因此特地把它汇总起来,使用时直接复制就可。

先附上各自的官网

VIVO:https://dev.vivo.com.cn/documentCenter/doc/103

OPPO:https://open.oppomobile.com/service/message/detail?id=61876

小米:https://dev.mi.com/console/doc/detail?pId=1293

华为:https://developer.huawei.com/consumer/cn/devservice/doc/50114?from=timeline

 

四厂商都是使用反射的方法来获取系统参数的,按照官方要求调用方法即可。直接汇总附上代码。

以下直接附上代码,调用notchsupport方法,就会返回刘海屏的px值,没刘海屏则返回0

//调用该方法,可以获取刘海屏的px值,没刘海屏则返回0
public float notchsupport(Context context){
        float notchLengthFloat=0.0f;

        //判断手机厂商,目前8.0只有华为、小米、oppo、vivo适配了刘海屏
        String phoneManufacturer=android.os.Build.BRAND.toLowerCase();
        if("huawei".equals(phoneManufacturer)){
            //huawei,长度为length,单位px
            boolean haveInScreenEMUI = hasNotchInScreenEMUI(context);
            if (haveInScreenEMUI) {
                int[] screenSize = {0};
                int length = 0;
                screenSize = getNotchSizeEMUI(context);
                notchLengthFloat=screenSize[1];
                //下面注释的是单独测试时的弹出消息
                //Toast.makeText(context, "haveInScreen:" + haveInScreenEMUI + ",screenSize:" + length, Toast.LENGTH_LONG).show();
            }
        }else if("xiaomi".equals(phoneManufacturer)){
            //xiaomi,单位px
            boolean haveInScreenMIUI = getNotchMIUI("ro.miui.notch", 0) == 1;
            if (haveInScreenMIUI) {
                int resourceId = context.getResources().getIdentifier("notch_height", "dimen", "android");
                int result = 0;
                if (resourceId > 0) {
                    result = context.getResources().getDimensionPixelSize(resourceId);
                }
                notchLengthFloat=result;
                //下面注释的是单独测试时的弹出消息
                //Toast.makeText(context, "haveInScreen:" + haveInScreenMIUI + ",screenSize" + result, Toast.LENGTH_LONG).show();
            }
        }else if("vivo".equals(phoneManufacturer)){
            //vivo,单位dp,高度27dp
            boolean haveInScreenVIVO = hasNotchAtVivo(context);
            if (haveInScreenVIVO) {
                //下面注释的是单独测试时的弹出消息
                //Toast.makeText(context, "haveInScreenVIVO:" + haveInScreenVIVO, Toast.LENGTH_LONG).show();
                notchLengthFloat=dp2px(context,27);
            }
        }else if("oppo".equals(phoneManufacturer)){
            //oppo
            boolean haveInScreenOPPO = context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
            if (haveInScreenOPPO) {
                //下面注释的是单独测试时的弹出消息
                //Toast.makeText(context, "haveInScreenOPPO:" + haveInScreenOPPO, Toast.LENGTH_LONG).show();
                notchLengthFloat=80;
            }
        }

        return notchLengthFloat;
    }


    //huawei
    public boolean hasNotchInScreenEMUI(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) {
            Log.e("test", "hasNotchInScreen ClassNotFoundException");
        } catch (NoSuchMethodException e) {
            Log.e("test", "hasNotchInScreen NoSuchMethodException");
        } catch (Exception e) {
            Log.e("test", "hasNotchInScreen Exception");
        } finally {
            return ret;
        }
    }

    public int[] getNotchSizeEMUI(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) {
            Log.e("test", "getNotchSize ClassNotFoundException");
        } catch (NoSuchMethodException e) {
            Log.e("test", "getNotchSize NoSuchMethodException");
        } catch (Exception e) {
            Log.e("test", "getNotchSize Exception");
        } finally {
            return ret;
        }
    }

    public int getNotchMIUI(final String key, final int def) {
        Method getIntMethod = null;
        try {
            if (getIntMethod == null) {
                getIntMethod = Class.forName("android.os.SystemProperties")
                        .getMethod("getInt", String.class, int.class);
            }
            return ((Integer) getIntMethod.invoke(null, key, def)).intValue();
        } catch (Exception e) {
            Log.e("MainActivity", "Platform error: " + e.toString());
            return def;
        }
    }

    public boolean hasNotchAtVivo(Context context) {
        boolean ret = false;
        try {
            ClassLoader classLoader = context.getClassLoader();
            Class FtFeature = classLoader.loadClass("android.util.FtFeature");
            Method method = FtFeature.getMethod("isFeatureSupport", int.class);
            ret = (boolean) method.invoke(FtFeature, 0x00000020);
        } catch (ClassNotFoundException e) {
            Log.e("Notch", "hasNotchAtVivo ClassNotFoundException");
        } catch (NoSuchMethodException e) {
            Log.e("Notch", "hasNotchAtVivo NoSuchMethodException");
        } catch (Exception e) {
            Log.e("Notch", "hasNotchAtVivo Exception");
        } finally {
            return ret;
        }
    }

    private int dp2px(Context context,float dpValue){
        float scale=context.getResources().getDisplayMetrics().density;
        return (int)(dpValue*scale+0.5f);
    }

以上为java1.8的做法,java1.6时的反射方法需要改成

if((Boolean) get.invoke(HwNotchSizeUtil))
    ret=true;
else
    ret=false;

Manifest需要修改的内容

<!--vivo.oppo-->
        <meta-data
            android:name="android.max_aspect"
            android:value="2.2" />
        <!--xiaomi-->
        <meta-data
            android:name="notch.config"
            android:value="portrait|landscape" />
        <!--huawei-->
        <meta-data
            android:name="android.notch_support"
            android:value="true" />

在手机调试时,记得在设置打开应用的全屏模式,小米、VIVO上都需要手动去设置打开全面屏

另外,适配后的app在vivo提审时需要

 

下面附上之后的android9.0刘海适配

https://blog.csdn.net/iamZ2z/article/details/85259525

展开阅读全文

没有更多推荐了,返回首页