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

Android折叠屏设备开合状态检测不稳定问题求助

折叠屏FLAT状态检测不稳定的修复方案

问题根源分析

你的代码存在几个关键问题导致检测不稳定:

  • 依赖FEATURE_SENSOR_HINGE_ANGLE判断折叠屏不准确,部分折叠设备没有铰链传感器但支持折叠特性
  • 未正确管理WindowInfoTracker的生命周期,可能导致重复回调或窗口未初始化时触发回调
  • 未处理displayFeatures为空的场景:当设备完全展开(FLAT状态)时,部分系统不会返回FoldingFeature实例

具体修复步骤

1. 替换折叠屏检测逻辑

放弃仅依赖铰链传感器的判断,改用更通用的折叠屏特性检测:

private void checkIfDeviceIsFold() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        windowInfoTracker = new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(this));
        // 同时检测折叠屏特性和铰链传感器,覆盖更多设备
        PackageManager pm = getApplication().getPackageManager();
        deviceIsFoldable = pm.hasSystemFeature(PackageManager.FEATURE_FOLDABLE) 
                || pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE);
        Log.d(Constants.TAG, "Device is foldable: " + deviceIsFoldable);
    } else {
        deviceIsFoldable = false;
    }
}

2. 正确管理监听生命周期

在onStop中移除监听,避免内存泄漏和无效回调:

@Override
protected void onStop() {
    super.onStop();
    if (windowInfoTracker != null) {
        windowInfoTracker.removeWindowLayoutInfoListener(layoutStateChangeCallback);
    }
}

3. 优化回调逻辑,处理displayFeatures为空的情况

当displayFeatures为空时,结合屏幕尺寸判断是否处于FLAT状态(完全展开):

class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
    @Override
    public void accept(WindowLayoutInfo newLayoutInfo) {
        FoldableHelper.FoldableLayoutInfo resultInfo = FoldableHelper.updateLayout(newLayoutInfo, StudyDisplay.this);
        Log.d(Constants.TAG, "FoldableHelper : newLayoutInfo : " + resultInfo.state);
        Log.d(Constants.TAG, "Study Fold state : newLayoutInfo : " + newLayoutInfo.toString());

        // 默认设为未打开状态
        deviceIsFoldableAndItsOpen = false;
        List<DisplayFeature> displayFeatures = newLayoutInfo.getDisplayFeatures();

        if (!displayFeatures.isEmpty()) {
            for (DisplayFeature feature : displayFeatures) {
                Log.d(Constants.TAG, "Study Fold feature : " + feature);
                if (feature instanceof FoldingFeature) {
                    FoldingFeature foldingFeature = (FoldingFeature) feature;
                    FoldingFeature.State state = foldingFeature.getState();
                    Log.d(Constants.TAG, "Study Fold state : " + state);
                    // 只要不是折叠闭合状态,就认为是打开(包括半开)
                    deviceIsFoldableAndItsOpen = state != FoldingFeature.State.FOLDED;
                }
            }
        } else if (deviceIsFoldable) {
            // 折叠设备但无displayFeatures,说明处于完全展开的FLAT状态
            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
            // 可根据设备实际展开后的宽高比调整判断条件,比如大部分折叠屏展开后是接近1:1或16:9
            boolean isWideEnough = metrics.widthPixels > 1000 && metrics.heightPixels > 1000;
            if (isWideEnough) {
                deviceIsFoldableAndItsOpen = true;
                Log.d(Constants.TAG, "Study Fold state : FLAT (no display feature detected)");
            }
        }

        // 统一触发UI更新
        updateLayoutForScreenSize();
    }
}

4. 额外优化:添加初始状态检测

在onResume中主动触发一次状态检测,避免首次进入时等待回调:

@Override
protected void onResume() {
    super.onResume();
    if (deviceIsFoldable && windowInfoTracker != null) {
        // 主动请求一次窗口布局信息
        windowInfoTracker.computeWindowLayoutInfo(this)
                .addOnSuccessListener(layoutStateChangeCallback::accept);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 19:59:50