import { NotificationCenter } from 'Foundation'; import { UIApplication, UIView, UITextField, UIScreen, UIDevice } from "UIKit" import { UTSiOS, UTSCallback } from "DCloudUTSFoundation" import { DispatchQueue } from 'Dispatch'; import { SetUserCaptureScreenOption, UserCaptureScreenResult, OnUserCaptureScreen, OffUserCaptureScreen, SetUserCaptureScreen } from "../interface.uts" /** * 定义监听截屏事件工具类 */ class CaptureScreenTool { static listener ?: UTSCallback; static secureView ?: UIView; // 监听截屏 static listenCaptureScreen(callback ?: UTSCallback) { this.listener = callback // 注册监听截屏事件及回调方法 // target-action 回调方法需要通过 Selector("方法名") 构建 const method = Selector("userDidTakeScreenshot") NotificationCenter.default.addObserver(this, selector = method, name = UIApplication.userDidTakeScreenshotNotification, object = null) } // 捕获截屏回调的方法 // target-action 的方法前需要添加 @objc 前缀 @objc static userDidTakeScreenshot() { // 回调 this.listener?.({}) } // 移除监听事件 static removeListen(callback ?: UTSCallback) { this.listener = null NotificationCenter.default.removeObserver(this) callback?.({}) } static createSecureView() : UIView | null { let field = UITextField() field.isSecureTextEntry = true if (field.subviews.count > 0 && UIDevice.current.systemVersion != '15.1') { let view = field.subviews.first if (view != null) { view!.subviews.forEach((item) => { item.removeFromSuperview() }) view!.isUserInteractionEnabled = true return view } } return null } // 开启防截屏 static onAntiScreenshot(option : SetUserCaptureScreenOption) { // uts方法默认会在子线程中执行,涉及 UI 操作必须在主线程中运行,通过 DispatchQueue.main.async 方法可将代码在主线程中运行 DispatchQueue.main.async(execute = () : void => { let secureView = this.createSecureView() let window = UTSiOS.getKeyWindow() let rootView = window.rootViewController == null ? null : window.rootViewController!.view if (secureView != null && rootView != null) { let rootSuperview = rootView!.superview if (rootSuperview != null) { this.secureView = secureView rootSuperview!.addSubview(secureView!) rootView!.removeFromSuperview() secureView!.addSubview(rootView!) let rect = rootView!.frame secureView!.frame = UIScreen.main.bounds rootView!.frame = rect } } let res = new UserCaptureScreenResult() res.errCode = 0; res.errSubject = "uni-usercapturescreen"; res.errMsg = "setUserCaptureScreen:ok"; option.success?.(res) option.complete?.(res) }) } // 关闭防截屏 static offAntiScreenshot(option : SetUserCaptureScreenOption) { DispatchQueue.main.async(execute = () : void => { if (this.secureView != null) { let window = UTSiOS.getKeyWindow() let rootView = window.rootViewController == null ? null : window.rootViewController!.view if (rootView != null && this.secureView!.superview != null) { let rootSuperview = this.secureView!.superview if (rootSuperview != null) { rootSuperview!.addSubview(rootView!) this.secureView!.removeFromSuperview() } } this.secureView = null } let res = new UserCaptureScreenResult() res.errCode = 0; res.errSubject = "uni-usercapturescreen"; res.errMsg = "setUserCaptureScreen:ok"; option.success?.(res) option.complete?.(res) }) } } /** * 开启截图监听 */ export const onUserCaptureScreen : OnUserCaptureScreen = function (callback ?: UTSCallback) { CaptureScreenTool.listenCaptureScreen(callback) } /** * 关闭截屏监听 */ export const offUserCaptureScreen : OffUserCaptureScreen = function (callback ?: UTSCallback) { CaptureScreenTool.removeListen(callback) } /** * 开启/关闭防截屏 */ export const setUserCaptureScreen : SetUserCaptureScreen = function (options : SetUserCaptureScreenOption) { if (UIDevice.current.systemVersion < "13.0") { let res = new UserCaptureScreenResult() res.errCode = 12001; res.errSubject = "uni-usercapturescreen"; res.errMsg = "setUserCaptureScreen:system not support"; options.fail?.(res); options.complete?.(res); } else if (UIDevice.current.systemVersion == "15.1") { let res = new UserCaptureScreenResult() res.errCode = 12010; res.errSubject = "uni-usercapturescreen"; res.errMsg = "setUserCaptureScreen:system internal error"; options.fail?.(res); options.complete?.(res); } else { if (options.enable == true) { CaptureScreenTool.offAntiScreenshot(options) } else { CaptureScreenTool.onAntiScreenshot(options) } } }