Пользовательское наложение при обнаружении записи устройстваAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Пользовательское наложение при обнаружении записи устройства

Сообщение Anonymous »

Я пытаюсь создать собственное наложение для своего приложения, которое будет скрывать экран, если в моем приложении начнется какой-либо общий доступ к экрану или несанкционированная запись. Но здесь возникает проблема, которую я пытаюсь избежать использования FLAG_SECURE, потому что он не позволяет мне добавлять пользовательские элементы, чтобы информировать пользователя о том, что экран записывается, и показывать им, что происходит. Я попытался создать собственную логику и вот к чему пришел:

Мне удалось создать собственное обнаружение с помощью DisplayManager и поймать, обнаружена ли запись. Но здесь возникает обходной путь, который я нашел и не могу исправить: если вы начинаете запись до входа в приложение, ваш экран не скрывается, потому что, если вы начинаете запись вне приложения, оно не может обнаружить происходящую запись и может определить только, началась ли запись, когда приложение находится в фоновом режиме или на экране. На данный момент я протестировал функцию «Поделиться своим экраном» и начать записывать, она отлично работает в приложении и выглядит очень приятно, информируя пользователя о том, что на самом деле происходит. Но все это можно просто пройти мимо, если начать запись не находясь в приложении, а снаружи. Я читал форумы и все такое, но все говорят, что это невозможно, поэтому просто используйте FLAG_SECURE, но это также заблокирует мои скриншоты, а это не то, чего я пытаюсь достичь, и мне нужно прийти к той же идее, что и мой коллега по IOS.
class ScreenRecordingDetectionManager(private val context: Context) {

private val controller: ScreenSecurityController =
(context as SmartApplication).getScreenSecurityController()
?: throw IllegalStateException("ScreenSecurityController not initialized")

private val displayListener = object : DisplayManager.DisplayListener {
override fun onDisplayAdded(id: Int) {
if (id != Display.DEFAULT_DISPLAY) {
controller.showSecurityOverlay()
}
}

override fun onDisplayRemoved(id: Int) {
if (id != Display.DEFAULT_DISPLAY) {
controller.hideSecurityOverlay()
}
}

override fun onDisplayChanged(id: Int) {}
}

fun startMonitoring() {
val dm = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
dm.registerDisplayListener(displayListener, null)

val handler = android.os.Handler(context.mainLooper)
handler.postDelayed({
val isExternalScreen =
dm.displays.any { it.displayId != Display.DEFAULT_DISPLAY }
val isMediaProjection =
controller.isMediaProjectionRecording()

if (isExternalScreen || isMediaProjection) {
controller.showSecurityOverlay()
}
}, 200)
}
}

class ScreenSecurityController(private val context: Context) :
Application.ActivityLifecycleCallbacks {

private var recordingOverlay: View? = null
private var isRecording = false

fun showSecurityOverlay() {
isRecording = true
applyOverlayToCurrentActivity()
}

fun hideSecurityOverlay() {
isRecording = false
recordingOverlay?.visibility = View.GONE
}

private fun applyOverlayToCurrentActivity() {

if (recordingOverlay != null && recordingOverlay?.parent != null)
return

val activity = (context as? SmartApplication)?.currentActivity ?: return

val root = activity.findViewById(android.R.id.content)

recordingOverlay = LayoutInflater.from(activity)
.inflate(R.layout.screen_recording_overlay, root, false)
root.addView(recordingOverlay)

recordingOverlay?.bringToFront()
recordingOverlay?.visibility = if (isRecording) View.VISIBLE else View.GONE
}

override fun onActivityResumed(activity: Activity) {
if (isRecording) applyOverlayToCurrentActivity()
}

override fun onActivityCreated(a: Activity, b: Bundle?) {}
override fun onActivityStarted(a: Activity) {}
override fun onActivityPaused(a: Activity) {}
override fun onActivityStopped(a: Activity) {}
override fun onActivitySaveInstanceState(a: Activity, outState: Bundle) {}
override fun onActivityDestroyed(a: Activity) {}

@SuppressLint("PrivateApi")
fun isMediaProjectionRecording(): Boolean {
return try {
val service = Class.forName("android.os.SystemProperties")
val getter = service.getMethod("get", String::class.java)
val value = getter.invoke(null, "sys.service.media.projection") as String
value.contains("running", ignoreCase = true)
} catch (e: Exception) {
false
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... -recording
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»