如何在Android中编程检测是否有屏幕录制进程/应用正在运行?

23

我不希望用户对我的应用程序进行截图或录屏。我已经在窗口中添加了安全标志。这可以防止用户进行截屏和录制屏幕。

如果屏幕录制开启,我的应用程序会防止内容被录制,但是音频会被录制。

在一些已root的设备上,安全标志可能无法按预期工作。因此,我只想检测是否有任何屏幕录制应用程序/进程在后台运行,以便我可以隐藏敏感数据并防止其被录制。

是否有办法检测屏幕录制是否开启?


2
如果你在谈论root权限的话,那就没有办法了。使用root权限,用户可以记录不同层次的所有内容,直到GPU输出级别。我相信你对此无能为力。 - Vladyslav Matviienko
你需要有一个流行和不那么流行的市场录音应用程序列表(确保获取包名称),因为你将在当前运行的进程中比较这些应用程序包,因为Android不知道什么是录音应用程序。 - Enzokie
有没有解决这个问题的方法?我试图创建一个应用程序来检测屏幕共享和屏幕录制,但是 DisplayManager 在一些设备上无法工作,我正在尝试寻找另一个解决方案。 - Hoàng Vũ Anh
4个回答

13

有没有办法检测屏幕录制是否开启?

不行。

所以我想检测是否有任何屏幕录制应用程序/进程在后台运行,以便我可以隐藏敏感数据并防止其被记录下来。

由于屏幕录制不需要特定的应用程序或进程(例如adb shell screenrecord),而且您无法知道使用媒体投影API的特定应用程序或进程,因此这似乎是不切实际的。在现代Android版本中,您也无法知道正在运行哪些其他进程。此外,用户可以用另一台相机对准设备屏幕并以此记录内容。

我不希望用户截取我的应用程序的屏幕或录制屏幕

那就不要编写该应用程序。FLAG_SECURE的想法是帮助用户抵御第三方,而不是保护开发人员免受用户的攻击。


我对FLAG_SECURE没意见,但它仍然记录音频。他们也应该防止这种情况。 - Boy
5
虽然答案的内容完全正确,但是我认为你对FLAG_SECURE背后的想法有误。有许多用例需要开发人员保护数据,例如只向付费用户提供数据时,不应通过截屏在用户之间共享。 - Abbas
2
@Abbas:FLAG_SECURE并不是作为数字版权管理(DRM)解决方案而设计的。 - CommonsWare

1
这里的答案对于安全问题而言只是一般性的。一旦数据流向某人的设备,您必须假定他们可以完全不受限制地访问它。其他所有内容在某种程度上都只是混淆,最多只是使其稍微困难一些。即使设备软件提供了一些保护,用户也可以物理接触设备并对其进行root操作。在某个时刻,数据必须解密和反混淆,以便向用户显示,并且恶意用户可以进行中间人攻击。如果您想要更好的安全性,那么需要通过硬件由设备提供。这是首次将电影流式传输到移动设备时遇到的一个大问题。设备需要一个特殊的硬件加密通道,每秒解密一些超乎想象的数据量,这样如果有人试图在未加密的数据到达屏幕之前进行中间人攻击,则很难写回磁盘。
现在,以上内容只是为了说明当数据传输到用户设备时,无法保证您能够控制数据。相反,您应该退一步并问问自己想要实现什么?您想要防止哪种类型的行为?如果一小部分技术熟练的用户能够绕过您的保护措施,这样做是否可以接受或者是一个大问题?数据“泄漏”的可接受速率是多少?这实际上取决于数据的敏感性以及您向用户承诺的保证类型。这方面是最关键的部分。如果您告诉用户发送的数据保证是短暂的,那是不可能的。试图构建并修补所有漏洞并打击鼹鼠游戏是徒劳的。唯一的赢法是不参与游戏。

0

正如@CommonsWare所说,没有办法知道使用媒体投影API的特定应用程序或进程,这似乎不切实际。

然而,您可以像这样使用FLAG_SECURE

getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE); 

此文档所述。

这个功能大部分情况下都能正常工作,但是我收到了一些反馈,说有一些品牌比如华为似乎会忽略这个限制,导致用户仍然可以录屏。 我需要找到一个解决方案,因为我的应用程序用于展示门票,而一些用户通过分享屏幕录像来作弊。 到目前为止,我还没有找到可行的解决方案。 - Christian

0

我认为有一种方法可以通过DisplayManager.DisplayListener来检测屏幕录制的开启或关闭。

以下是我的代码:

val listener = object : DisplayManager.DisplayListener {

        override fun onDisplayChanged(displayId: Int) {
               Log.d("test","1")
           //it detect something chnage in screen 
           //you can mute it from here

        }

        override fun onDisplayAdded(displayId: Int) {
         Log.d("test","2")
             //you can mute it to here from
             

        }

        override fun onDisplayRemoved(displayId: Int) {
                    Log.d("test","3")
                    //final here you can unMute it 
            }
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接