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

Android 10+系统设置应用悬浮层布局失效问题求助

Android 10+系统设置应用悬浮层不显示问题解决

问题概述

启动系统设置应用时,应用锁样式的悬浮层无法正常触发显示,其他第三方应用均能正常触发悬浮层解锁逻辑,且已确认应用悬浮层权限已成功授予。

核心原因分析

  1. 前台应用检测延迟:Android 10+中,UsageStatsManager.queryUsageStats返回的是统计聚合数据,存在一定延迟,无法实时捕捉系统设置这类高优先级应用切换到前台的事件,导致悬浮层触发逻辑未及时执行。
  2. 悬浮层窗口参数限制:当前配置的WindowManager.LayoutParams包含FLAG_NOT_FOCUSABLE,系统设置应用的窗口层级较高,无焦点的悬浮层会被系统窗口遮挡或忽略。
  3. 系统应用特殊校验:Android 10+对系统核心应用(如设置)的悬浮窗显示有额外校验规则,普通悬浮层参数无法满足显示要求。

解决方案

1. 优化前台应用检测逻辑

替换queryUsageStats为queryEvents,实时获取应用前后台切换事件,确保精准捕捉系统设置的前台状态:

private fun getForegroundObservableaboveQ(): Flowable<String>? {
    return Flowable.interval(500, TimeUnit.MILLISECONDS)
        .filter { PermissionChecker.checkUsageAccessPermission(context) }
        .map {
            val mUsageStatsManager = context.getSystemService(Service.USAGE_STATS_SERVICE) as UsageStatsManager
            val time = System.currentTimeMillis()
            val usageEvents = UsageEvents()
            mUsageStatsManager.queryEvents(time - 10000, time, usageEvents)
            
            var foregroundPackage = ""
            val event = UsageEvents.Event()
            while (usageEvents.hasNextEvent()) {
                usageEvents.getNextEvent(event)
                // 仅关注应用切换到前台的事件
                if (event.eventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
                    foregroundPackage = event.packageName ?: ""
                }
            }
            foregroundPackage
        }
        .filter { it.isNotEmpty() }
        .distinctUntilChanged()
}

2. 调整悬浮层窗口参数

移除FLAG_NOT_FOCUSABLE,添加全屏相关flag,确保悬浮层能覆盖系统设置窗口:

object OverlayViewLayoutParams {
    fun get(): WindowManager.LayoutParams {
        val layoutFlag: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
        } else {
            WindowManager.LayoutParams.TYPE_PHONE
        }

        return WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            layoutFlag,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                    WindowManager.LayoutParams.FLAG_FULLSCREEN or
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN,
            PixelFormat.TRANSLUCENT
        )
    }
}

3. 针对系统设置应用的特殊处理

在onAppForeground中添加系统设置包名判断,强制触发悬浮层显示,避免逻辑分支被跳过:

private fun onAppForeground(foregroundAppPackage: String) {
    hideOverlay()

    //Lock overlay work
    if (lockedAppPackageSet.contains(foregroundAppPackage)) {
        // 针对系统设置应用强制使用悬浮层
        val isSystemSettings = foregroundAppPackage == "com.android.settings"
        if ((appLockerPreferences.getFingerPrintEnabled() || !PermissionChecker.checkOverlayPermission(applicationContext)) && !isSystemSettings) {
            val intent = OverlayValidationActivity.newIntent(applicationContext, foregroundAppPackage)
            intent.flags = if (lastForegroundAppPackage == applicationContext.packageName) {
                Intent.FLAG_ACTIVITY_NEW_TASK
            } else {
                Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            }
            startActivity(intent)
        } else {
            showOverlay(foregroundAppPackage)
        }
    }
    lastForegroundAppPackage = foregroundAppPackage
}

验证步骤

  1. 重新确认应用已获取悬浮层和使用统计权限
  2. 启动系统设置应用,检查悬浮层是否正常弹出
  3. 测试其他第三方应用,确保原有应用锁功能不受影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 06:33:23