index.uts 5.2 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, UserCaptureScreenResult, OnUserCaptureScreen, OffUserCaptureScreen, SetUserCaptureScreen, UserCaptureScreenCallback, OnUserCaptureScreenResult } 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 31 32 33 34 35
		// 回调
		const res: OnUserCaptureScreenResult = {
			errCode: 0,
			errSubject: "uni-usercapturescreen",
			errMsg: "onUserCaptureScreen: ok",
			path: null
		}
		this.listener?.(res)
36 37 38
	}

	// 移除监听事件
39
	static removeListen(callback : UserCaptureScreenCallback | null) {
40
		this.listener = null
41 42 43 44 45 46 47 48
		NotificationCenter.default.removeObserver(this)
		const res: OnUserCaptureScreenResult = {
			errCode: 0,
			errSubject: "uni-usercapturescreen",
			errMsg: "offUserCaptureScreen: ok",
			path: null
		}
		callback?.(res)
49 50 51
	}

	static createSecureView() : UIView | null {
lizhongyi_'s avatar
lizhongyi_ 已提交
52
		let field = new UITextField(frame = CGRect.zero)
53
		field.isSecureTextEntry = true
54 55 56 57 58 59 60
		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
61 62 63 64 65
		}
		return null
	}

	// 开启防截屏
66
	static onAntiScreenshot(option : SetUserCaptureScreenOptions) {
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
		// 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
				}
83 84 85 86 87
			}
			let res: UserCaptureScreenResult = {
				errCode: 0,
				errSubject: "uni-usercapturescreen",
				errMsg: "setUserCaptureScreen:ok"
88 89 90 91 92 93 94
			}
			option.success?.(res)
			option.complete?.(res)
		})
	}

	// 关闭防截屏
95
	static offAntiScreenshot(option : SetUserCaptureScreenOptions) {
96 97 98 99 100 101 102 103 104 105 106 107
		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
108 109 110 111 112
			}
			let res: UserCaptureScreenResult = {
				errCode: 0,
				errSubject: "uni-usercapturescreen",
				errMsg: "setUserCaptureScreen:ok"
113 114 115 116 117 118 119 120 121 122
			}
			option.success?.(res)
			option.complete?.(res)
		})
	}
}

/**
	* 开启截图监听
	*/
123
export const onUserCaptureScreen : OnUserCaptureScreen = function (callback : UserCaptureScreenCallback | null) {
124 125 126 127 128 129
	CaptureScreenTool.listenCaptureScreen(callback)
}

/**
	* 关闭截屏监听
	*/
130
export const offUserCaptureScreen : OffUserCaptureScreen = function (callback : UserCaptureScreenCallback | null) {
131 132 133 134 135 136
	CaptureScreenTool.removeListen(callback)
}

/**
	* 开启/关闭防截屏
	*/
137 138 139 140 141 142 143
export const setUserCaptureScreen : SetUserCaptureScreen = function (options : SetUserCaptureScreenOptions) {
	if (UIDevice.current.systemVersion < "13.0") {
		let res: UserCaptureScreenResult = {
			errCode: 12001,
			errSubject: "uni-usercapturescreen",
			errMsg: "setUserCaptureScreen:system not support"
		}
144 145 146
		options.fail?.(res);
		options.complete?.(res);

147 148 149 150 151 152
	} else if (UIDevice.current.systemVersion == "15.1") {
		let res: UserCaptureScreenResult = {
			errCode: 12010,
			errSubject: "uni-usercapturescreen",
			errMsg: "setUserCaptureScreen:system internal error"
		}
153 154 155
		options.fail?.(res);
		options.complete?.(res);
	} else {
156
		if (options.enable == true) {
157
			CaptureScreenTool.offAntiScreenshot(options)
158 159
		} else {
			CaptureScreenTool.onAntiScreenshot(options)
160 161 162
		}
	}
}
lizhongyi_'s avatar
lizhongyi_ 已提交
163