有没有办法将LayoutParams.FLAG_SECURE应用到Compose Screen Level来防止截图?

问题描述 投票:0回答:2

我有一个活动撰写应用程序,并且希望防止在单个屏幕中截屏。但是,将

LayoutParams.FLAG_SECURE
应用于活动窗口将阻止此活动中所有屏幕的屏幕截图。

我知道我可以获取窗口并更改它,但必须在调用

setContent
之前完成。

有现成的解决方案吗?当我搜索时,什么也没找到。

我知道我可以将我想要阻止屏幕截图的屏幕放在不同的活动中,但我宁愿先看看是否有一个适合撰写的解决方案。

android-jetpack-compose
2个回答
0
投票

您需要观察生命周期,然后适当地设置安全标志。

这篇文章看起来不错,尽管我发现我没有看到 ON_START 生命周期事件,所以我根据 ON_RESUME 做了我的。

我已经有了一个生命周期观察者,所以我这样做了:

Composable
fun Lifecycle.observeAsState(): State<Lifecycle.Event> {
    val state = remember { mutableStateOf(Lifecycle.Event.ON_ANY) }
    DisposableEffect(this) {
        val observer = LifecycleEventObserver { _, event ->
            state.value = event
        }
        addObserver(observer)
        onDispose {
            removeObserver(observer)
        }
    }
    return state
}
@Composable
fun ProtectScreen() {
    val lifecycleState by LocalLifecycleOwner.current.lifecycle.observeAsState()

    val activity = LocalContext.current.getActivity()

    /* When screen has focus, set secure flag */
    when (lifecycleState) {
        Lifecycle.Event.ON_RESUME -> activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
        Lifecycle.Event.ON_PAUSE -> activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
        else -> Unit
    }
    /* Also reset the flag when the composable is disposed */
    DisposableEffect(Unit) {
        onDispose { activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) }
    }
}

其中(如文章中所示)Context.getActivity() 是一个非常标准的扩展方法,用于获取给定上下文(可以是 ContextWrapper)的活动


0
投票

我是这样做的 LifecycleEventListener.kt

import androidx.activity.ComponentActivity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver

@Composable
fun ComponentActivity.LifecycleEventListener(event: (Lifecycle.Event) -> Unit) {
    val eventHandler by rememberUpdatedState(newValue = event)
    val lifecycle = [email protected]
    DisposableEffect(lifecycle) {
        val observer = LifecycleEventObserver { _, event ->
            eventHandler(event)
        }
        lifecycle.addObserver(observer)
        onDispose {
            lifecycle.removeObserver(observer)
        }
    }
}

受保护的屏幕.kt

import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.Lifecycle

@Composable
fun ProtectedScreen() {
    val activityContext = LocalContext.current as ComponentActivity
    activityContext.LifecycleEventListener(event = { lifecycleEvent ->
        when (lifecycleEvent) {
            Lifecycle.Event.ON_RESUME -> {
                activityContext.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
            }
            Lifecycle.Event.ON_PAUSE -> {
                activityContext.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
            }
            else -> return@LifecycleEventListener
        }
    })
    DisposableEffect(Unit) {
        onDispose { activityContext.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.