index.uts 4.8 KB
Newer Older
lizhongyi_'s avatar
lizhongyi_ 已提交
1 2
import { NotificationCenter } from 'Foundation';
import { CGRect } from "CoreFoundation";
3
import { UIApplication, UIView, UITextField, UIScreen, UIDevice } from "UIKit"
4
import { UTSiOS } from "DCloudUTSFoundation"
5
import { DispatchQueue } from 'Dispatch';
6
import { SetUserCaptureScreenOptions, OnUserCaptureScreenCallbackResult, OnUserCaptureScreen, OffUserCaptureScreen, SetUserCaptureScreen, UserCaptureScreenCallback, OnUserCaptureScreenResult, SetUserCaptureScreenSuccess, SetUserCaptureScreenFail  } from "../interface.uts"
7 8 9 10 11

/**
	* 定义监听截屏事件工具类
	*/
class CaptureScreenTool {
12 13
	static listener : UserCaptureScreenCallback | null;
	static secureView : UIView | null;
14 15

	// 监听截屏
16
	static listenCaptureScreen(callback : UserCaptureScreenCallback | null) {
17
		this.listener = callback
18
 
19 20 21 22 23 24 25 26 27
		// 注册监听截屏事件及回调方法
		// target-action 回调方法需要通过 Selector("方法名") 构建
		const method = Selector("userDidTakeScreenshot")
		NotificationCenter.default.addObserver(this, selector = method, name = UIApplication.userDidTakeScreenshotNotification, object = null)
	}

	// 捕获截屏回调的方法
	// target-action 的方法前需要添加 @objc 前缀
	@objc static userDidTakeScreenshot() {
28
		// 回调
29 30
		const res: OnUserCaptureScreenCallbackResult = {

31 32
		}
		this.listener?.(res)
33 34 35
	}

	// 移除监听事件
36
	static removeListen(callback : UserCaptureScreenCallback | null) {
37
		this.listener = null
38
		NotificationCenter.default.removeObserver(this)
39 40 41
	}

	static createSecureView() : UIView | null {
lizhongyi_'s avatar
lizhongyi_ 已提交
42
		let field = new UITextField(frame = CGRect.zero)
43
		field.isSecureTextEntry = true
44 45 46 47 48 49 50
		if (field.subviews.length > 0 && UIDevice.current.systemVersion != '15.1') {
			let view = field.subviews[0]
			view.subviews.forEach((item) => {
				item.removeFromSuperview()
			})
			view.isUserInteractionEnabled = true
			return view
51 52 53 54 55
		}
		return null
	}

	// 开启防截屏
56
	static onAntiScreenshot(option : SetUserCaptureScreenOptions) {
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
		// 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
				}
73
			}
74
			let res: SetUserCaptureScreenSuccess = {
75 76 77 78 79 80 81
			}
			option.success?.(res)
			option.complete?.(res)
		})
	}

	// 关闭防截屏
82
	static offAntiScreenshot(option : SetUserCaptureScreenOptions) {
83 84 85 86 87 88 89 90 91 92 93 94
		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
95
			}
96
			let res: SetUserCaptureScreenSuccess = {
97 98 99 100 101 102 103 104 105 106
			}
			option.success?.(res)
			option.complete?.(res)
		})
	}
}

/**
	* 开启截图监听
	*/
107
export const onUserCaptureScreen : OnUserCaptureScreen = function (callback : UserCaptureScreenCallback | null) {
108 109 110 111 112 113
	CaptureScreenTool.listenCaptureScreen(callback)
}

/**
	* 关闭截屏监听
	*/
114
export const offUserCaptureScreen : OffUserCaptureScreen = function (callback : UserCaptureScreenCallback | null) {
115 116 117 118 119 120
	CaptureScreenTool.removeListen(callback)
}

/**
	* 开启/关闭防截屏
	*/
121 122
export const setUserCaptureScreen : SetUserCaptureScreen = function (options : SetUserCaptureScreenOptions) {
	if (UIDevice.current.systemVersion < "13.0") {
123
		let res: SetUserCaptureScreenFail = {
124 125 126 127
			errCode: 12001,
			errSubject: "uni-usercapturescreen",
			errMsg: "setUserCaptureScreen:system not support"
		}
128 129 130
		options.fail?.(res);
		options.complete?.(res);

131
	} else if (UIDevice.current.systemVersion == "15.1") {
132
		let res: SetUserCaptureScreenFail = {
133 134 135 136
			errCode: 12010,
			errSubject: "uni-usercapturescreen",
			errMsg: "setUserCaptureScreen:system internal error"
		}
137 138 139
		options.fail?.(res);
		options.complete?.(res);
	} else {
140
		if (options.enable == true) {
141
			CaptureScreenTool.offAntiScreenshot(options)
142 143
		} else {
			CaptureScreenTool.onAntiScreenshot(options)
144 145 146
		}
	}
}
lizhongyi_'s avatar
lizhongyi_ 已提交
147