18034727885
2026-06-21 b85c31f93903234aa9533d81f6bc963ec6f29fd2
修复问题
1个文件已添加
1个文件已修改
88 ■■■■■ 已修改文件
app/src/main/java/com/xw/yunwei/ui/work/site/SiteNavActivity.kt 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/src/main/java/com/xw/common/SecureScreenShot.kt 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/xw/yunwei/ui/work/site/SiteNavActivity.kt
@@ -310,11 +310,14 @@
                    }
                }
            }
            filterDialog?.setOnDismissListener { binding.filterOverlay.visibility = View.GONE }
        }
        filterDialog?.show()
        binding.filterOverlay.visibility = View.VISIBLE
        // 关键:让软键盘把 BottomSheet 顶上去
        filterDialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
        filterDialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
        filterDialog?.window?.setLayout(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
common/src/main/java/com/xw/common/SecureScreenShot.kt
New file
@@ -0,0 +1,85 @@
package com.xw.common
import android.view.Window
import android.view.WindowManager
import java.lang.ref.WeakReference
/**
 * 统一管理 APP 防截屏(FLAG_SECURE)开关。
 *
 * 默认行为:非 DEBUG 包禁止截屏,DEBUG 包允许截屏,保持与历史逻辑一致。
 *
 * 内部用弱引用集合保存所有受管理的 [Window](避免持有 Activity/Dialog 导致内存泄漏)。
 * 当 [allowScreenShot] 在 true/false 之间发生变化时,会自动刷新所有存活 window 的
 * FLAG_SECURE 标记,从而实时启用 / 禁用截屏。
 */
object SecureScreenShot {
    /** 受管理的 window 弱引用集合 */
    private val windowRefs = mutableListOf<WeakReference<Window>>()
    /**
     * 运行时是否允许截屏。默认 false(即开启防截屏)。
     * 赋值发生变化时,会自动刷新所有已登记 window 的截屏标记。
     */
    @Volatile
    var allowScreenShot: Boolean = false
        set(value) {
            if (field == value) return
            field = value
            refreshAll()
        }
    /**
     * 登记并立即为指定 [window] 应用当前的截屏配置。
     * 同一个 window 不会重复登记,失效的弱引用会被顺带清理。
     */
    @Synchronized
    fun apply(window: Window?) {
        window ?: return
        var exists = false
        val iterator = windowRefs.iterator()
        while (iterator.hasNext()) {
            val w = iterator.next().get()
            if (w == null) {
                iterator.remove()
            } else if (w === window) {
                exists = true
            }
        }
        if (!exists) {
            windowRefs.add(WeakReference(window))
        }
        applyFlag(window)
    }
    /**
     * 刷新所有存活 window 的截屏标记,并清理已失效的弱引用。
     */
    @Synchronized
    private fun refreshAll() {
        val iterator = windowRefs.iterator()
        while (iterator.hasNext()) {
            val w = iterator.next().get()
            if (w == null) {
                iterator.remove()
            } else {
                applyFlag(w)
            }
        }
    }
    /**
     * 根据当前配置为指定 [window] 应用或清除防截屏标记。
     *
     * - DEBUG 包或 [allowScreenShot] 为 true 时:清除 FLAG_SECURE,允许截屏
     * - 否则:添加 FLAG_SECURE,禁止截屏
     */
    private fun applyFlag(window: Window) {
        if (BuildConfig.DEBUG || allowScreenShot) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
        } else {
            window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)//禁止截屏
        }
    }
}