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

Android平台游戏如何检测打开通知栏等失焦场景

Android 7.0(API 24)之后,下拉展开通知栏/快捷设置面板时,前台Activity不会触发onPause回调——此时Activity仍处于Resumed生命周期状态,只是被系统级窗口覆盖,这就是你之前用onPause做失焦检测失效的根本原因。《狂野飙车9》这类商用游戏的暂停逻辑也没有依赖onPause实现,具体检测方案可以根据你的项目支持的最低版本选择:

实现方案

1. 原生安卓项目通用实现

按系统版本适配,覆盖全场景无隐藏API调用:

  • Android 11(API 30)及以上:通过WindowInsets监听状态栏状态,判断逻辑最准确
    // 给游戏界面的根View绑定insets监听
    gameRootView.setOnApplyWindowInsetsListener { view, insets ->
        val statusBarVisibleHeight = insets.getInsets(WindowInsets.Type.statusBars()).top
        // 阈值按设备密度转换为px,普通常驻状态栏高度一般为24~48dp,超过80dp即可判定为下拉展开通知面板
        val isNotificationShadeOpened = statusBarVisibleHeight > TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, 80f, view.resources.displayMetrics
        ).toInt()
        if (isNotificationShadeOpened) {
            triggerGamePause() // 执行你的游戏暂停逻辑
        }
        insets
    }
    
  • Android 7.0(API 24)~ Android 10(API 29):结合系统UI可见性变化+窗口可见区域判断
    gameRootView.setOnSystemUiVisibilityChangeListener { visibility ->
        val isInFullScreenMode = visibility and View.SYSTEM_UI_FLAG_FULLSCREEN != 0
        if (!isInFullScreenMode) {
            val visibleRect = Rect()
            gameRootView.getWindowVisibleDisplayFrame(visibleRect)
            // 排除软键盘弹出场景:软键盘只会改变窗口底部边距,通知栏下拉会让顶部边距大幅增加
            val topOffset = visibleRect.top
            val threshold = TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 80f, gameRootView.resources.displayMetrics
            ).toInt()
            if (topOffset > threshold) {
                triggerGamePause()
            }
        }
    }
    
  • Android 7.0以下版本:下拉通知栏会正常触发onPause,原有逻辑可以直接覆盖这个版本区间。

2. 误判场景规避

以上逻辑需要额外排除几个特殊场景,避免错误触发暂停:

  • 软键盘弹出:软键盘弹出仅会改变窗口底部inset/边距,顶部边距不会达到阈值,只要同时校验上下边距即可区分
  • 系统小弹窗(权限申请、音量调节、电源菜单):这类弹窗不会让状态栏可见高度达到80dp的阈值,不会触发误判
  • 分屏/自由小窗模式:提前通过Activity.isInMultiWindowMode判断应用是否处于多窗口模式,多窗口下的尺寸变化单独处理即可

3. 游戏引擎快速实现

如果使用商业游戏引擎开发,不需要自行编写原生适配逻辑,引擎已经封装了对应回调:

  • Unity:直接监听MonoBehaviour.OnApplicationFocus(bool hasFocus),下拉通知栏时会回调hasFocus = false,直接绑定暂停逻辑即可
  • Unreal Engine:监听FCoreDelegates::ApplicationWillDeactivateDelegate委托,通知栏展开时该委托会正常触发,直接绑定暂停逻辑即可

不要使用反射调用系统隐藏APIStatusBarManager.isNotificationShadeExpanded()实现检测:不同厂商ROM对该隐藏API的实现差异极大,同时反射调用隐藏API会提高应用上架被拒的风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:09:09