如何在Android平台使用Python Kivy实现截图检测或禁用功能?
解决Kivy Android应用的截图禁用与检测问题
一、禁用截图:正确使用FLAG_SECURE
你之前的代码问题在于手动定义FLAG_SECURE常量以及LayoutParams类的获取方式错误,以下是修正后的可行实现:
正确代码实现
在你的Kivy App的on_start方法中调用以下函数:
from jnius import autoclass def enable_secure_window(): # 获取当前Activity实例 PythonActivity = autoclass('org.kivy.android.PythonActivity') activity = PythonActivity.mActivity # 获取WindowManager.LayoutParams的正确类引用 WindowManagerLayoutParams = autoclass('android.view.WindowManager$LayoutParams') window = activity.getWindow() params = window.getAttributes() # 为窗口添加FLAG_SECURE标记 params.flags |= WindowManagerLayoutParams.FLAG_SECURE window.setAttributes(params) # 额外设置DecorView的系统UI可见性,确保覆盖所有显示场景 window.getDecorView().setSystemUiVisibility(WindowManagerLayoutParams.FLAG_SECURE)
关键修正点
- 直接通过
android.view.WindowManager$LayoutParams获取类,避免字符串拼接导致的类引用错误 - 无需手动赋值
FLAG_SECURE常量,直接使用系统定义的常量即可 - 补充设置DecorView的系统UI可见性,确保FLAG_SECURE的生效范围覆盖整个窗口
二、检测截图行为:监听媒体库变化
检测截图的可靠方式是监听Android媒体库的新增图片——绝大多数系统截图会被自动扫描并加入媒体库,以下是实现思路:
实现步骤
- 使用
pyjnius创建ContentObserver子类,重写onChange方法处理文件变化 - 将观察者注册到媒体图片的URI,监听新增文件事件
- 在
onChange中通过文件名、路径特征判断是否为截图
示例代码
from jnius import autoclass, PythonJavaClass, java_method # 创建ContentObserver子类,用于监听媒体库变化 class ScreenshotObserver(PythonJavaClass): __javainterfaces__ = ['android.database.ContentObserver'] def __init__(self, handler): super().__init__() self.handler = handler @java_method('(Z)V') def onChange(self, selfChange): # 查询媒体库中最新添加的图片 MediaStore = autoclass('android.provider.MediaStore') content_resolver = autoclass('org.kivy.android.PythonActivity').mActivity.getContentResolver() cursor = content_resolver.query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, [MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_ADDED], None, None, MediaStore.Images.Media.DATE_ADDED + " DESC" ) if cursor.moveToFirst(): image_path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)) # 根据文件名特征判断是否为截图(适配不同厂商命名规则) if "screenshot" in image_path.lower() or "screen_shot" in image_path.lower(): # 此处处理截图事件,比如弹窗提醒、记录操作日志等 print("检测到截图操作:", image_path) cursor.close() # 注册截图观察者 def register_screenshot_observer(): Handler = autoclass('android.os.Handler') observer = ScreenshotObserver(Handler()) MediaStore = autoclass('android.provider.MediaStore') autoclass('org.kivy.android.PythonActivity').mActivity.getContentResolver().registerContentObserver( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, True, observer )
三、注意事项
FLAG_SECURE仅能阻止系统自带的截图、录屏功能,无法完全防止Root设备或第三方工具的截图操作- 截图检测依赖媒体库扫描,部分自定义截图路径或未被系统扫描的图片可能无法被检测到
- 针对Android 10以下版本,需在
AndroidManifest.xml中添加READ_EXTERNAL_STORAGE权限;Android 10+使用媒体库访问框架无需额外权限
内容的提问来源于stack exchange,提问作者CocaColaCoder
相关产品推荐
相关产品推荐

