index.uts 4.4 KB
Newer Older
1
import { UTSAndroid } from "io.dcloud.uts";
2 3 4 5 6 7 8 9
import ActivityCompat from "androidx.core.app.ActivityCompat";
import Manifest from "android.Manifest";
import PackageManager from "android.content.pm.PackageManager";
import Build from "android.os.Build";
import FileObserver from "android.os.FileObserver";
import File from "java.io.File";
import Environment from "android.os.Environment";
import System from 'java.lang.System';
10
import WindowManager from 'android.view.WindowManager';
11
import { UserCaptureScreenResult, OnUserCaptureScreenResult, SetUserCaptureScreenOptions, UserCaptureScreenCallback, OnUserCaptureScreen, OffUserCaptureScreen, SetUserCaptureScreen } from "../interface.uts";
12 13

/**
14 15 16
	* 文件监听器
	*/
let observer : ScreenFileObserver | null = null;
17
/**
18 19 20
	* 记录文件监听器上次监听的时间戳,避免重复监听
	*/
let lastObserverTime : number = 0;
21
/**
22 23 24
	* 截屏回调
	*/
let listener : UserCaptureScreenCallback | null = null;
25 26

/**
27 28
	* android 文件监听实现
	*/
29 30 31
class ScreenFileObserver extends FileObserver {

	/**
32 33 34
		* 截屏文件目录
		*/
	private screenFile : File;
35

36 37 38
	constructor(screenFile : File) {
		super(screenFile);
		this.screenFile = screenFile;
39 40
	}

41
	override onEvent(event : Int, path : string | null) : void {
42 43
		// 只监听文件新增事件
		if (event == FileObserver.CREATE) {
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
			if (path != null) {
				const currentTime = System.currentTimeMillis();
				if ((currentTime - lastObserverTime) < 1000) {
					// 本地截屏行为比上一次超过1000ms, 才认为是一个有效的时间
					return;
				}
				lastObserverTime = currentTime;

				const screenShotPath = new File(this.screenFile, path).getPath();
				const res : OnUserCaptureScreenResult = {
					errCode: 0,
					errMsg: "onUserCaptureScreen:ok",
					errSubject: "uni-onUserCaptureScreen",
					path: screenShotPath
				}
				listener?.(res);
60 61 62 63 64 65
			}
		}
	}
}

/**
66 67 68 69 70 71 72
	* 开启截图监听
	*/
export const onUserCaptureScreen : OnUserCaptureScreen = function (callback : UserCaptureScreenCallback | null) {
	// 检查相关权限是否已授予
	if (ActivityCompat.checkSelfPermission(UTSAndroid.getAppContext()!, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
		// 无权限,申请权限,并且告知用户监听失败
		ActivityCompat.requestPermissions(UTSAndroid.getUniActivity()!, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1001);
73
		// 因权限缺失导致监听失败
74 75 76 77
		const res : OnUserCaptureScreenResult = {
			errCode: -1,
			errMsg: "onUserCaptureScreen:permission denied",
			errSubject: "uni-onUserCaptureScreen"
78
		}
79 80
		callback?.(res);
		return;
81 82
	}

83 84 85 86
	// 更新监听
	listener = callback;

	let directory_screenshot : File;
杜庆泉's avatar
杜庆泉 已提交
87
	if (Build.MANUFACTURER.toLowerCase() === "xiaomi") {
88 89
		// @Suppress("DEPRECATION")
		directory_screenshot = new File(new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM), "Screenshots");
90
	} else {
91 92
		// @Suppress("DEPRECATION")
		directory_screenshot = new File(new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_PICTURES), "Screenshots");
93
	}
94 95 96 97
	// 先结束监听 再开启监听
	observer?.stopWatching();
	observer = new ScreenFileObserver(directory_screenshot);
	observer?.startWatching();
98 99 100
}

/**
101 102 103 104 105 106 107
	* 关闭截屏监听
	*/
export const offUserCaptureScreen : OffUserCaptureScreen = function (_ : UserCaptureScreenCallback | null) {
	// android10以上,关闭监听通过移除文件监听器实现
	observer?.stopWatching();
	observer = null;
	lastObserverTime = 0;
108 109
}

110
/**
111 112 113
	* 设置是否禁止截屏
	*/
export const setUserCaptureScreen : SetUserCaptureScreen = function (option : SetUserCaptureScreenOptions) {
114
	// 切换到UI线程
115
	UTSAndroid.getUniActivity()?.runOnUiThread(new SetUserCaptureScreenRunnable(option.enable));
116 117 118 119 120
	const res : UserCaptureScreenResult = {
		errCode: 0,
		errMsg: "setUserCaptureScreen:ok",
		errSubject: "uni-setUserCaptureScreen"
	}
121 122 123 124 125
	option.success?.(res);
	option.complete?.(res);
}

class SetUserCaptureScreenRunnable extends Runnable {
126

127
	/**
128 129 130 131
		* ture: 允许用户截屏
		* false: 不允许用户截屏,防止用户截屏到应用页面内容
		*/
	private enable : boolean;
132

133
	constructor(enable : boolean) {
134
		super();
135
		this.enable = enable;
136 137
	}

138
	override run() : void {
139
		if (this.enable) {
140
			UTSAndroid.getUniActivity()?.getWindow()?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
141 142
		} else {
			UTSAndroid.getUniActivity()?.getWindow()?.addFlags(WindowManager.LayoutParams.FLAG_SECURE);
143 144 145
		}
	}
}