使用Kotlin实现Android设备可用显示屏检测与副屏控制方法
Kotlin 访问折叠屏内置副屏实现方案(适配摩托罗拉Razr系列、三星Z Flip系列)
检测副屏是否存在
直接调用Android原生WindowManager接口枚举所有可用显示屏即可,不需要依赖厂商私有SDK,过滤逻辑如下:
val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager var builtInSecondaryDisplay: Display? = null // 遍历所有已挂载的显示屏 windowManager.displays.forEach { display -> // 过滤规则:支持Presentation展示、非默认主屏幕、状态为可用 val isValidSecondaryScreen = (display.flags and Display.FLAG_PRESENTATION) != 0 && display.displayId != Display.DEFAULT_DISPLAY && (display.state == Display.STATE_ON || display.state == Display.STATE_OFF) if (isValidSecondaryScreen) { builtInSecondaryDisplay = display } }
注意:摩托罗拉Razr 2019的副屏displayId在多数系统版本为2,不建议硬编码ID,通过flag过滤兼容性更好。
强制唤起副屏点亮
Android原生提供了Presentation类专门用于副屏内容展示,只要拿到有效的副屏Display实例,不需要系统正确识别折叠状态,即可直接在副屏渲染内容、点亮屏幕,基础实现代码:
// 自定义副屏展示容器 class RazrSecondaryScreen(context: Context, targetDisplay: Display) : Presentation(context, targetDisplay) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 加载副屏要显示的布局,可自定义时间、快捷操作等内容 setContentView(R.layout.layout_secondary_screen) // 配置窗口属性:点亮屏幕、保持常亮 window?.addFlags( WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ) } } // 检测到副屏存在时直接唤起 builtInSecondaryDisplay?.let { val secondaryScreen = RazrSecondaryScreen(this, it) secondaryScreen.show() }
常见适配坑点
- 摩托罗拉MyUX系统默认限制第三方应用在外屏启动内容,需要提前引导用户在系统设置的「外屏管理」页面,给当前应用开启外屏展示权限。
- 部分旧版本系统对
FLAG_TURN_SCREEN_ON兼容性差,可以补充申请WAKE_LOCK权限,通过PowerManager强制唤醒副屏。 - 如果需要在应用退到后台时副屏仍然显示,需要把Presentation的window type设置为系统弹窗类型(Android 8.0以上用
TYPE_APPLICATION_OVERLAY,同时引导用户开启悬浮窗权限)。
Razr 2019 折叠传感器故障场景的补充方案
如果设备折叠识别完全失效,可根据自身权限情况选择方案:
- 无root场景:在应用内添加手动触发开关,用户折叠手机后手动点击按钮触发上述Presentation展示逻辑,不需要依赖系统折叠状态广播。
- 有root场景:可直接执行shell指令手动写入系统折叠状态值,触发系统原生副屏点亮逻辑,不需要自行实现副屏UI:
# 1为折叠状态(点亮副屏),0为展开状态(点亮主屏) settings put secure folded_state 1
内容的提问来源于stack exchange,提问作者Monolith
相关产品推荐
相关产品推荐

