You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在模拟器中获取摄像头挖孔的DisplayCutout高度?

解决全屏应用中Pixel模拟器摄像头挖孔遮挡及DisplayCutout为null的问题

一、先解决DisplayCutout为null的问题

你遇到的DisplayCutout为null,核心原因是模拟器未启用挖孔模拟或应用未正确进入全屏模式,按以下步骤排查:

1. 启用模拟器的挖孔模拟

Pixel模拟器默认不会显示挖孔,需手动开启:

  • 打开模拟器系统设置,进入System > Developer options(若未显示开发者选项,先到About phone连续点击Build number激活)
  • 找到Simulate a display with a cutout选项,选择对应类型(比如Pixel 4系列选"Notch",Pixel 6+选"Double cutout")

2. 确保应用进入全屏模式

只有应用处于全屏状态,系统才会返回包含DisplayCutout的WindowInsets。在onCreate中优先添加全屏设置:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 设置全屏,让布局延伸到系统窗口区域
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        getWindow().setDecorFitsSystemWindows(false);
    } else {
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        );
    }

    // 之后再设置Insets监听
    getWindow().getDecorView().setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
        @Override
        public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                DisplayCutout cutout = insets.getDisplayCutout();
                if (cutout != null) {
                    Log.d("mytag", "left= " + cutout.getSafeInsetLeft() + ", top= " + cutout.getSafeInsetTop());
                } else {
                    Log.d("mytag", "Cutout is null");
                }
            } else {
                Log.d("mytag", "Old API");
            }
            return insets.consumeSystemWindowInsets();
        }
    });
}

注意:必须先设置全屏,再添加Insets监听,否则DisplayCutout仍会返回null。

二、解决控件被挖孔遮挡的问题

你尝试的LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER不生效,是因为全屏设置不正确或模式设置时机不对,按以下方式修复:

1. 正确设置layoutInDisplayCutoutMode

在全屏设置之后,添加代码配置布局模式:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    WindowManager.LayoutParams params = getWindow().getAttributes();
    // 让系统自动避开挖孔区域,布局不会延伸到挖孔处
    params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
    getWindow().setAttributes(params);
}

或在styles.xml的Activity主题中配置(更稳定):

<style name="FullscreenTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <item name="android:windowLayoutInDisplayCutoutMode">never</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowNoTitle">true</item>
</style>

然后在AndroidManifest.xml中给目标Activity应用该主题:

<activity
    android:name=".MainActivity"
    android:theme="@style/FullscreenTheme">
    ...
</activity>

2. 手动调整布局避开挖孔

若需要布局延伸到挖孔区域,仅让特定控件避开,可通过DisplayCutout获取安全区域边距,手动设置控件padding:

@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        DisplayCutout cutout = insets.getDisplayCutout();
        if (cutout != null) {
            int safeTop = cutout.getSafeInsetTop();
            // 给顶部控件设置top padding,避开挖孔
            View topView = findViewById(R.id.top_text);
            topView.setPadding(topView.getPaddingLeft(), safeTop, topView.getPaddingRight(), topView.getPaddingBottom());
        }
    }
    return insets.consumeSystemWindowInsets();
}

关键注意事项

  • 模拟器必须启用挖孔模拟,否则DisplayCutout始终为null
  • 必须先设置setDecorFitsSystemWindows(false)或对应全屏flags,才能触发系统返回包含DisplayCutout的Insets
  • layoutInDisplayCutoutMode的设置必须在全屏设置之后才会生效

内容的提问来源于stack exchange,提问作者Sasha Minsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:17:24