import { UTSAndroid } from "io.dcloud.uts"; 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'; import WindowManager from 'android.view.WindowManager'; /** * setUserCaptureScreen 参数定义 */ type SetUserCaptureScreenOption = { open: boolean; success?: (res: UTSJSONObject) => void; fail?: (res: UTSJSONObject) => void; complete?: (res: UTSJSONObject) => void; } /** * 文件监听器 */ let screenOB: ScreenFileObserver | null = null; /** * 记录文件监听器上次监听的时间戳,避免重复监听 */ let lastFileObserverTime: number = 0; /** * 图片被捕获的实现 */ let imageChange: UTSCallback | null = null; /** * android 文件监听实现 */ @Suppress("DEPRECATION") class ScreenFileObserver extends FileObserver { /** * 所有截屏文件的存放目录 */ allScreen: File; constructor(screenFile: string) { super(new File(screenFile)) this.allScreen = new File(screenFile); } override onEvent(event: Int, path?: string): void { // 只监听文件新增事件 if (event == FileObserver.CREATE) { let newPath: string = new File(this.allScreen, path!).getPath(); let currentTime = System.currentTimeMillis(); if ((currentTime - lastFileObserverTime) < 1000) { // 本地截屏行为比上一次超过1000ms,才认为是一个有效的时间 return; } lastFileObserverTime = System.currentTimeMillis() let ret = { errCode:1, image:newPath } imageChange!(ret); } } } /** * 开启截图监听 */ @Suppress("DEPRECATION") export function onUserCaptureScreen(callback: (res:UTSJSONObject) => void) { // 检查相关权限是否已经具备 if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 不具备权限,申请权限,并且告知用户监听失败 ActivityCompat.requestPermissions(UTSAndroid.getUniActivity()!, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1001) // 因权限缺失导致监听失败 let ret = { errCode:-1 } callback(ret); return ; } imageChange = callback; let directory_screenshot: File; // 找到设备存放截屏文件的目录 let directory_pictures = new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_PICTURES); let directory_dcim = new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM); if (Build.MANUFACTURER.toLowerCase() === "xiaomi") { directory_screenshot = new File(directory_dcim, "Screenshots"); } else { directory_screenshot = new File(directory_pictures, "Screenshots"); } if (screenOB != null) { screenOB!.stopWatching() } //开始监听 screenOB = new ScreenFileObserver(directory_screenshot.path) screenOB!.startWatching() // 监听成功 let ret = { errCode:0 } callback(ret); } /** * 关闭截屏监听 */ export function offUserCaptureScreen(success: (res: any) => void) { // android 10以上,关闭监听通过移除文件监听器实现 if (screenOB != null) { screenOB!.stopWatching() screenOB = null } lastFileObserverTime = 0; success({}); } /** * 设置是否禁止截屏 */ export function setUserCaptureScreen(option: SetUserCaptureScreenOption) { const res = { errCode: 0, errMsg: "setUserCaptureScreen:ok", errSubject: "uni-setUserCaptureScreen" }; UTSAndroid.getUniActivity()?.runOnUiThread(new SetUserCaptureScreenRunnable(option.open)); option.success?.(res); option.complete?.(res); } class SetUserCaptureScreenRunnable extends Runnable { /** * true 表示禁止截屏 * false 表示允许截屏 */ private open: boolean = false; constructor(open: boolean) { super(); this.open = open; } override run(): void { if (this.open) { UTSAndroid.getUniActivity()?.getWindow()?.addFlags(WindowManager.LayoutParams.FLAG_SECURE); } else { UTSAndroid.getUniActivity()?.getWindow()?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE); } } }