diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..582561b0c3f6fe39e97853dce405a30cc66748aa --- /dev/null +++ b/.hbuilderx/launch.json @@ -0,0 +1,16 @@ +{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ + // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 + "version": "0.0", + "configurations": [{ + "app-plus" : + { + "launchtype" : "local" + }, + "default" : + { + "launchtype" : "local" + }, + "type" : "uniCloud" + } + ] +} diff --git a/manifest.json b/manifest.json index 43e16b568c0943a40fd4dda7403ef233f61ca4be..48976f4a2ba008270be7c6090171f2905e21497f 100644 --- a/manifest.json +++ b/manifest.json @@ -68,5 +68,5 @@ "uniStatistics" : { "enable" : false }, - "vueVersion" : "2" + "vueVersion" : "3" } diff --git a/pages/index/index.vue b/pages/index/index.vue index ec0ec2608ed4473f337ab917121eef355d09a193..9d1af6dda9b2ea19f73554d0761a038d43590849 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -4,10 +4,17 @@ {{title}} + + + + diff --git a/uni_modules/uni-screen/changelog.md b/uni_modules/uni-screen/changelog.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/uni_modules/uni-screen/package.json b/uni_modules/uni-screen/package.json new file mode 100644 index 0000000000000000000000000000000000000000..8608904cf7ea41c3bcd306a91fb2815209b38f49 --- /dev/null +++ b/uni_modules/uni-screen/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-screen", + "displayName": "uni-screen", + "version": "1.0.0", + "description": "uni-screen", + "keywords": [ + "屏幕" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.6.0" + }, + "dcloudext": { + "type": "uts", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "", + "data": "", + "permissions": "" + }, + "npmurl": "" + }, + "uni_modules": { + "uni-ext-api":{ + "uni": { + "onUserCaptureScreen": "onUserCaptureScreen", + "offUserCaptureScreen": "offUserCaptureScreen" + } + }, + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "u", + "aliyun": "u" + }, + "client": { + "Vue": { + "vue2": "n", + "vue3": "y" + }, + "App": { + "app-android": "u", + "app-ios": "u" + }, + "H5-mobile": { + "Safari": "u", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} diff --git a/uni_modules/uni-screen/readme.md b/uni_modules/uni-screen/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..a9d321527993786643c0e055322439da63ce92fb --- /dev/null +++ b/uni_modules/uni-screen/readme.md @@ -0,0 +1,5 @@ +# uts-screenshot-listener +### 开发文档 +[UTS 语法](https://uniapp.dcloud.net.cn/tutorial/syntax-uts.html) +[UTS 原生插件](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html) +[Hello UTS](https://gitcode.net/dcloud/hello-uts/-/tree/dev) \ No newline at end of file diff --git a/uni_modules/uni-screen/utssdk/app-android/index.uts b/uni_modules/uni-screen/utssdk/app-android/index.uts new file mode 100644 index 0000000000000000000000000000000000000000..3ddae88956eb46dc1b414354c280881e7b1cc655 --- /dev/null +++ b/uni_modules/uni-screen/utssdk/app-android/index.uts @@ -0,0 +1,150 @@ + + +import { + getUniActivity +} from "io.dcloud.uts.android"; + + +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'; + + + +/** + * 文件监听器 + */ +let screenOB: ScreenFileObserver | null = null; +/** + * 记录文件监听器上次监听的时间戳,避免重复监听 + */ +let lastFileObserverTime: number = 0; +/** + * 图片被捕获的实现 + */ +let imageChange: UTSCallback | null = null; + + + + +/** + * android 文件监听实现 + */ + +class ScreenFileObserver extends FileObserver { + + /** + * 所有截屏文件的存放目录 + */ + allScreen: File; + + + constructor(screenFile: string) { + super(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 = { + code:1, + image:newPath + } + + imageChange!(ret); + } + } +} + + + + + + + + +/** + * 开启截图监听 + */ +export function onUserCaptureScreen(callback: (res:UTSJSONObject) => void) { + + // 检查相关权限是否已经具备 + if (ActivityCompat.checkSelfPermission(getUniActivity()!, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + // 不具备权限,申请权限,并且告知用户监听失败 + ActivityCompat.requestPermissions(getUniActivity()!, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1001) + + // 因权限缺失导致监听失败 + let ret = { + code:-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.lowercase() === "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 = { + code:0 + } + callback(ret); + +} + + +/** + * 关闭截屏监听 + */ +export function offUserCaptureScreen(success: (res: any) => void) { + + // android 10以上,关闭监听通过移除文件监听器实现 + if (screenOB != null) { + screenOB!.stopWatching() + screenOB = null + } + lastFileObserverTime = 0; + + let ret = { + + } + success(ret); +} + + + diff --git a/uni_modules/uni-screen/utssdk/app-ios/index.uts b/uni_modules/uni-screen/utssdk/app-ios/index.uts new file mode 100644 index 0000000000000000000000000000000000000000..1151d9e520c6da0284812eac14f2147aa243919f --- /dev/null +++ b/uni_modules/uni-screen/utssdk/app-ios/index.uts @@ -0,0 +1,49 @@ +import { NotificationCenter} from 'Foundation'; +import { UIApplication } from "UIKit" + +/** + * 定义监听截屏事件工具类 + */ +class CaptureScreenTool { + static listener?: UTSCallback; + + // 监听截屏 + static listenCaptureScreen(callback?: UTSCallback) { + this.listener = callback + + // 注册监听截屏事件及回调方法 + // target-action 回调方法需要通过 Selector("方法名") 构建 + const method = Selector("userDidTakeScreenshot") + NotificationCenter.default.addObserver(this, selector = method, name = UIApplication.userDidTakeScreenshotNotification, object = null) + } + + // 捕获截屏回调的方法 + // target-action 的方法前需要添加 @objc 前缀 + @objc static userDidTakeScreenshot() { + const obj = new UTSJSONObject() + // 回调 + this.listener?.(obj) + } + + // 移除监听事件 + static removeListen(callback?: UTSCallback) { + this.listener = null + NotificationCenter.default.removeObserver(this) + const obj = new UTSJSONObject() + callback?.(obj) + } +} + +/** + * 开启截图监听 + */ +export function onUserCaptureScreen(callback?: UTSCallback) { + CaptureScreenTool.listenCaptureScreen(callback) +} + +/** + * 关闭截屏监听 + */ +export function offUserCaptureScreen(callback?: UTSCallback) { + CaptureScreenTool.removeListen(callback) +}