国内手机厂商参差不齐,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刘海适配