1. 程式人生 > >android8.0劉海屏適配集合

android8.0劉海屏適配集合

國內手機廠商參差不齊,google官方9.0才出劉海屏適配,國內的廠商各有各的方法,苦了我們這些程式設計師,因此特地把它彙總起來,使用時直接複製就可。

先附上各自的官網

以下程式碼,呼叫notchsupport方法,就會返回劉海屏的px值,沒劉海屏則返回0

//呼叫該方法,可以獲取劉海屏的px值,沒劉海屏則返回0
public float notchsupport(Context context){
        float notchLengthFloat=0.0f;

        //判斷手機廠商,目前只做了華為、小米、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=length;
                //下面註釋的是單獨測試時的彈出訊息
                //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上都需要手動去設定開啟全面屏