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'; import { SetUserCaptureScreenOption, UserCaptureScreenResult, OnUserCaptureScreen, OffUserCaptureScreen, SetUserCaptureScreen } from "../interface.uts"; /** * 文件监听器 */ 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 const onUserCaptureScreen : OnUserCaptureScreen = function (callback ?: UTSCallback) { // 检查相关权限是否已经具备 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.getPath()) screenOB!.startWatching() // 监听成功 let ret = { errCode:0 } callback?.(ret); } /** * 关闭截屏监听 */ export const offUserCaptureScreen : OffUserCaptureScreen = function (callback ?: UTSCallback) { // android 10以上,关闭监听通过移除文件监听器实现 if (screenOB != null) { screenOB!.stopWatching() screenOB = null } lastFileObserverTime = 0; callback?.({}); } /** * 设置是否禁止截屏 */ export const setUserCaptureScreen : SetUserCaptureScreen = function (option: SetUserCaptureScreenOption) { // 切换到UI线程 UTSAndroid.getUniActivity()?.runOnUiThread(new SetUserCaptureScreenRunnable(option.enable)); const res = new UserCaptureScreenResult(); res.errCode = 0; res.errMsg = "setUserCaptureScreen:ok"; res.errSubject = "uni-setUserCaptureScreen"; option.success?.(res); option.complete?.(res); } class SetUserCaptureScreenRunnable extends Runnable { /** * ture: 允许用户截屏 * false: 不允许用户截屏,防止用户截屏到应用页面内容 */ private enable: boolean; constructor(enable: boolean) { super(); this.enable = enable; } override run(): void { if (this.enable) { UTSAndroid.getUniActivity()?.getWindow()?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE); } else { UTSAndroid.getUniActivity()?.getWindow()?.addFlags(WindowManager.LayoutParams.FLAG_SECURE); } } }