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
相关产品推荐
相关产品推荐

