Android P适配

Android P行为变更

官网介绍: Android P 行为变更

0x1 刘海屏适配

如果没有刘海屏手机,可以在Andrid P 手机或者模拟器开发者模式>simulate display with a cutout。 刘海屏的适配分为下面三种情况:

  • 1.有状态栏的页面,系统自动适配,不会受到刘海屏的影响。
  • 2.全屏未适配刘海屏的页面,系统会对刘海屏区域进行切割,让整体 UI 页面做下移处理,避开刘海屏的显示。
  • 3.全屏已适配刘海屏的页面,可以兼容刘海屏,做到真正的全屏显示。

这是一个没有适配的例子,闪屏页面整体向下了,并没有全屏。

# 适配方案
WindowManager.LayoutParams lp  
                =getWindow().getAttributes();
lp.layoutInDisplayCutoutMode =  
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
getWindow().setAttributes(lp);  
# 获取凹形屏相关参数
view.postDelayed(new Runnable() {  
    @Override
    public void run() {
        DisplayCutout displayCutout = view.getRootWindowInsets().getDisplayCutout();
        Log.i("cxmyDev", "SafeInsetBottom:" + displayCutout.getSafeInsetBottom());
        Log.i("cxmyDev", "SafeInsetLeft:" + displayCutout.getSafeInsetLeft());
        Log.i("cxmyDev", "SafeInsetRight:" + displayCutout.getSafeInsetRight());
        Log.i("cxmyDev", "SafeInsetTop:" + displayCutout.getSafeInsetTop());
    }
}, 100);
oppo非官方方案实现刘海屏

oppo凹形屏适配文档

// 仅Oppo机型有效
context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism")  

0x2 对于非 SDK 接口的限制(@hide保护接口)

官方介绍:对于非 SDK 接口的限制

为帮助确保应用稳定性和兼容性,此平台对某些非 SDK 函数和字段的使用进行了限制;无论您是直接访问这些函数和字段,还是通过反射或 JNI 访问,这些限制均适用。 在 Developer Preview 1 中,您的应用可以继续访问这些受限的接口;该平台通过 toast 和日志条目提醒您注意这些接口。 如果您的应用显示这样的 toast,则必须寻求受限接口之外的其他实现策略。

Android Preview 1提示

弹出提示相关代码 android/app/Activity.java#7073

boolean isAppDebuggable = (mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;  
// This property is set for all non-user builds except final release
boolean isApiWarningEnabled = SystemProperties.getInt("ro.art.hiddenapi.warning", 0) == 1;  
if (isAppDebuggable || isApiWarningEnabled) {  
    if (!mMainThread.mHiddenApiWarningShown && VMRuntime.getRuntime().hasUsedHiddenApi()) {
        // Only show the warning once per process.
        mMainThread.mHiddenApiWarningShown = true;
        String appName = getApplicationInfo().loadLabel(getPackageManager())
                .toString();
        String warning = "Detected problems with API compatibility\n"
                         + "(visit g.co/dev/appcompat for more info)";
        if (isAppDebuggable) {
            new AlertDialog.Builder(this)
                .setTitle(appName)
                .setMessage(warning)
                .setPositiveButton(android.R.string.ok, null)
                .setCancelable(false)
                .show();
        } else {
            Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show();
        }
    }
}
解决方案

参考文档