提交 c1ef0e94 编写于 作者: dcloud_wdl's avatar dcloud_wdl

Merge remote-tracking branch 'origin/alpha'

{ // 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"
}
{
// 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"
},
{
"bundleId" : "io.dcloud.test123456",
"certificateFile" : "/Users/lizhongyi/Desktop/文件/证书/dev_123.p12",
"certificateProfileFile" : "/Users/lizhongyi/Desktop/文件/证书/io_dcloud_test123456.mobileprovision",
"type" : "uni-app:app-ios"
}
]
}
{
"name" : "uni-api",
"appid" : "__UNI__4F60974",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* 模块配置 */
"modules" : {},
/* 应用发布信息 */
"distribute" : {
/* android打包配置 */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios打包配置 */
"ios" : {},
/* SDK配置 */
"sdkConfigs" : {}
}
},
/* 快应用特有相关 */
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
{
"name": "uni-api",
"appid": "__UNI__ED9218B",
"description": "",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
/* 5+App特有相关 */
"app-plus": {
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
/* 模块配置 */
"modules": {},
/* 应用发布信息 */
"distribute": {
/* android打包配置 */
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios打包配置 */
"ios": {},
/* SDK配置 */
"sdkConfigs": {}
}
},
/* 快应用特有相关 */
"quickapp": {},
/* 小程序特有相关 */
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false
},
"usingComponents": true
},
"mp-alipay": {
"usingComponents": true
},
"mp-baidu": {
"usingComponents": true
},
"mp-toutiao": {
"usingComponents": true
},
"uniStatistics": {
"enable": false
},
"vueVersion": "2"
}
......@@ -6,6 +6,8 @@
</view>
<button @tap="testScreenShotListen">开启截屏监听</button>
<button @tap="testScreenShotOff">关闭截屏监听</button>
<button @tap="testSetUserCaptureScreen">{{setUserCaptureScreenText}}</button>
<button @tap="testGetBatteryInfo">获取电池电量</button>
<button @tap="testonMemoryWarning">开启内存不足告警监听</button>
<button @tap="testoffMemoryWarning">关闭内存不足告警监听</button>
......@@ -25,6 +27,9 @@
return {
title: 'Hello',
memListener:null,
setUserCaptureScreenFlag: false,
setUserCaptureScreenText: '禁止截屏',
permissionGranted: false
}
},
onLoad() {
......@@ -133,41 +138,20 @@
var that = this;
uni.onUserCaptureScreen(function(res) {
console.log(res);
if (uni.getSystemInfoSync().platform == "android") {
// 除android 之外的平台,不需要判断返回状态码
if(res.errCode == -1){
// 启动失败
return ;
}else if(res.errCode == 0){
uni.showToast({
icon:"none",
title:'截屏监听已开启'
})
}else {
uni.showToast({
icon:"none",
title:'捕获截屏事件'
})
that.screenImage = res.image
}
}else{
// 除android 之外的平台,不需要判断返回状态码
uni.showToast({
icon:"none",
title:'捕获截屏事件'
})
}
});
if (uni.getSystemInfoSync().platform != "android") {
// 除android 之外的平台,直接提示监听已开启
uni.showToast({
icon:"none",
title:'截屏监听已开启'
title:'捕获截屏事件'
})
}
that.screenImage = res.path
});
if (uni.getSystemInfoSync().platform != "android" || that.permissionGranted) {
// 除android 之外的平台,直接提示监听已开启
uni.showToast({
icon:"none",
title:'截屏监听已开启'
})
}
},
testScreenShotOff() {
uni.offUserCaptureScreen(function(res) {
......@@ -190,6 +174,31 @@
}
})
},
testSetUserCaptureScreen() {
let flag = this.setUserCaptureScreenFlag;
uni.setUserCaptureScreen({
enable: flag,
success: (res) => {
console.log("setUserCaptureScreen enable: " + flag + " success: " + JSON.stringify(res));
},
fail: (res) => {
console.log("setUserCaptureScreen enable: " + flag + " fail: " + JSON.stringify(res));
},
complete: (res) => {
console.log("setUserCaptureScreen enable: " + flag + " complete: " + JSON.stringify(res));
}
});
uni.showToast({
icon:"none",
title: this.setUserCaptureScreenText
});
this.setUserCaptureScreenFlag = !this.setUserCaptureScreenFlag;
if (this.setUserCaptureScreenFlag) {
this.setUserCaptureScreenText = '允许截屏';
} else {
this.setUserCaptureScreenText = '禁止截屏';
}
},
}
}
</script>
......
......@@ -32,7 +32,7 @@
},
"uni_modules": {
"uni-ext-api": {
"uni": "getBatteryInfo"
"uni": ["getBatteryInfo"]
},
"dependencies": [],
"encrypt": [],
......
import Context from "android.content.Context";
import BatteryManager from "android.os.BatteryManager";
import { UTSAndroid } from "io.dcloud.uts";
type GetBatteryInfoOptions = {
success?: (res: UTSJSONObject) => void
fail?: (res: UTSJSONObject) => void
complete?: (res: UTSJSONObject) => void
}
export default function getBatteryInfo(options: GetBatteryInfoOptions) {
const context = UTSAndroid.getAppContext();
if (context != null) {
const manager = context.getSystemService(
Context.BATTERY_SERVICE
) as BatteryManager;
const level = manager.getIntProperty(
BatteryManager.BATTERY_PROPERTY_CAPACITY
);
const res = {
errCode: 0,
errSubject: "uni-getBatteryInfo",
errMsg: 'getBatteryInfo:ok',
level,
isCharging: manager.isCharging()
}
options.success?.(res)
options.complete?.(res)
} else {
const res = {
errSubject: "uni-getBatteryInfo",
errCode: 1001,
errMsg: 'getBatteryInfo:fail getAppContext is null'
}
options.fail?.(res)
options.complete?.(res)
}
}
import Context from "android.content.Context";
import BatteryManager from "android.os.BatteryManager";
import { UTSAndroid } from "io.dcloud.uts";
import { GetBatteryInfo, GetBatteryInfoSuccess, GetBatteryInfoFail, GetBatteryInfoOptions } from '../interface.uts'
export const getBatteryInfo : GetBatteryInfo = function (options) {
const context = UTSAndroid.getAppContext();
if (context != null) {
const manager = context.getSystemService(
Context.BATTERY_SERVICE
) as BatteryManager;
const level = manager.getIntProperty(
BatteryManager.BATTERY_PROPERTY_CAPACITY
);
const res : GetBatteryInfoSuccess = {
errMsg: 'getBatteryInfo:ok',
level,
isCharging: manager.isCharging()
}
options.success?.(res)
options.complete?.(res)
} else {
const res : GetBatteryInfoFail = {
errSubject: "uni-getBatteryInfo",
errCode: 1001,
errMsg: 'getBatteryInfo:fail getAppContext is null',
cause: null
}
options.fail?.(res)
options.complete?.(res)
}
}
\ No newline at end of file
// 引用 iOS 原生平台 api
import { UIDevice } from "UIKit";
import { Int } from 'Swift';
/**
* 定义 接口参数
*/
type GetBatteryInfoOptions = {
success?: (res: object) => void;
fail?: (res: object) => void;
complete?: (res: object) => void;
};
/**
* 导出 获取电量方法
*/
export default function getBatteryInfo(options: GetBatteryInfoOptions) {
// 开启电量检测
UIDevice.current.isBatteryMonitoringEnabled = true
// 返回数据
const res = {
errCode: 0,
errSubject: "uni-getBatteryInfo",
errMsg: "getBatteryInfo:ok",
level: new Int(UIDevice.current.batteryLevel * 100),
isCharging: UIDevice.current.batteryState == UIDevice.BatteryState.charging,
};
options.success?.(res);
options.complete?.(res);
// 引用 iOS 原生平台 api
import { UIDevice } from "UIKit";
import { Int } from 'Swift';
import { GetBatteryInfo, GetBatteryInfoSuccess } from '../interface.uts';
/**
* 导出 获取电量方法
*/
export const getBatteryInfo : GetBatteryInfo = function (options) {
// 开启电量检测
UIDevice.current.isBatteryMonitoringEnabled = true
// 返回数据
const res : GetBatteryInfoSuccess = {
errMsg: "getBatteryInfo:ok",
level: new Int(UIDevice.current.batteryLevel * 100),
isCharging: UIDevice.current.batteryState == UIDevice.BatteryState.charging,
};
options.success?.(res);
options.complete?.(res);
}
\ No newline at end of file
type GetBatteryInfoResult = {
/**
* 错误码
*/
errCode: number,
/**
* 调用API的名称
*/
errSubject: string,
/**
* 错误的详细信息
*/
errMsg: string,
/**
* 设备电量,范围1 - 100
*/
level: number,
/**
* 是否正在充电中
*/
isCharging: boolean
}
interface UniError<T> {
/**
* 错误码
*/
errCode:T,
/**
* 调用API的名称
*/
errSubject:string,
/**
* 错误的详细信息
*/
errMsg:string,
/**
* 错误来源
*/
cause:any
}
/**
* 错误码
*/
type GetBatteryInfoErrorCode =
/** 成功 */
0
/** getAppContext is null */
| 1001
/** navigator.getBattery is unsupported */
| 1002
;
export type GetBatteryInfoOptions = {
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
*/
success?: (res: GetBatteryInfoResult) => void
/**
* 接口调用失败的回调函数
*/
fail?: (res: UniError<GetBatteryInfoErrorCode>) => void
/**
* 接口调用成功的回调
*/
complete?: (res: object) => void
}
/**
* 获取电量信息
* @param {GetBatteryInfoOptions} options
*
*
* @tutorial https://uniapp.dcloud.net.cn/api/system/batteryInfo.html
* @platforms APP-IOS = ^9.0,APP-ANDROID = ^22
* @since 3.6.11
*
* @assert () => success({errCode: 0, errSubject: "uni-getBatteryInfo", errMsg: "getBatteryInfo:ok", level: 60, isCharging: false })
* @assert () => fail({errCode: 1001, errSubject: "uni-getBatteryInfo", errMsg: "getBatteryInfo:fail getAppContext is null" })
*/
export default function getBatteryInfo(options: GetBatteryInfoOptions): void
export type GetBatteryInfoSuccess = {
errMsg : string,
/**
* 设备电量,范围1 - 100
*/
level : number,
/**
* 是否正在充电中
*/
isCharging : boolean
}
export type GetBatteryInfoFail = {
/**
* 错误码
*/
errCode : number,
/**
* 调用API的名称
*/
errSubject : string,
/**
* 错误的详细信息
*/
errMsg : string,
/**
* 错误来源
*/
cause : any | null
}
export type GetBatteryInfoOptions = {
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
*/
success ?: (res : GetBatteryInfoSuccess) => void
/**
* 接口调用失败的回调函数
*/
fail ?: (res : GetBatteryInfoFail) => void
/**
* 接口调用成功的回调
*/
complete ?: (res : any) => void
}
/**
* 获取电量信息
* @param {GetBatteryInfoOptions} options
*
*
* @tutorial https://uniapp.dcloud.net.cn/api/system/batteryInfo.html
* @platforms APP-IOS = ^9.0,APP-ANDROID = ^22
* @since 3.6.11
*
* @assert () => success({errCode: 0, errSubject: "uni-getBatteryInfo", errMsg: "getBatteryInfo:ok", level: 60, isCharging: false })
* @assert () => fail({errCode: 1001, errSubject: "uni-getBatteryInfo", errMsg: "getBatteryInfo:fail getAppContext is null" })
*/
export type GetBatteryInfo = (options : GetBatteryInfoOptions) => void
\ No newline at end of file
export default function getBatteryInfo(options) {
export function getBatteryInfo(options) {
return my.getBatteryInfo(options)
}
export default function getBatteryInfo(options) {
export function getBatteryInfo(options) {
return swan.getBatteryInfo(options)
}
export default function getBatteryInfo(options) {
export function getBatteryInfo(options) {
return qq.getBatteryInfo(options)
}
export default function getBatteryInfo(options) {
export function getBatteryInfo(options) {
return wx.getBatteryInfo(options)
}
export default function getBatteryInfo(options) {
export function getBatteryInfo(options) {
if (navigator.getBattery) {
navigator.getBattery().then(battery => {
const res = {
......
import { UTSAndroid } from "io.dcloud.uts"
let listeners: UTSCallback[] = []
const onAppTrimMemoryListener = (res: number) => {
const onAppTrimMemoryListener = (ret: number) => {
listeners.forEach(listener => {
let res = {
level:ret
}
listener(res)
})
}
@Suppress("DEPRECATION")
export function onMemoryWarning(callback: (res: number) => void) {
export function onMemoryWarning(callback: UTSCallback) {
if (listeners.length == 0) {
// 仅首次执行底层的实际监听
UTSAndroid.onAppTrimMemory(onAppTrimMemoryListener)
......@@ -22,8 +26,9 @@ export function onMemoryWarning(callback: (res: number) => void) {
listeners.push(callback)
}
@Suppress("DEPRECATION")
export function offMemoryWarning(callback: UTSCallback | null = null) {
export function offMemoryWarning(callback: UTSCallback | null) {
if(callback == null){
// 清除全部回调
......@@ -42,3 +47,4 @@ export function offMemoryWarning(callback: UTSCallback | null = null) {
UTSAndroid.offAppTrimMemory(onAppTrimMemoryListener)
}
}
......@@ -34,7 +34,8 @@
"uni-ext-api":{
"uni": {
"onUserCaptureScreen": "onUserCaptureScreen",
"offUserCaptureScreen": "offUserCaptureScreen"
"offUserCaptureScreen": "offUserCaptureScreen",
"setUserCaptureScreen": "setUserCaptureScreen"
}
},
"dependencies": [],
......
import {
UTSAndroid
} from "io.dcloud.uts";
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";
......@@ -13,137 +7,133 @@ 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 { OnUserCaptureScreenCallbackResult, UserCaptureScreenCallback, OnUserCaptureScreen, OffUserCaptureScreen, SetUserCaptureScreenSuccess, SetUserCaptureScreenOptions, SetUserCaptureScreen } from "../interface.uts";
/**
* 文件监听器
*/
let screenOB: ScreenFileObserver | null = null;
* 文件监听器
*/
let observer : ScreenFileObserver | null = null;
/**
* 记录文件监听器上次监听的时间戳,避免重复监听
*/
let lastFileObserverTime: number = 0;
* 记录文件监听器上次监听的时间戳,避免重复监听
*/
let lastObserverTime : number = 0;
/**
* 图片被捕获的实现
*/
let imageChange: UTSCallback | null = null;
* 截屏回调
*/
let listener : UserCaptureScreenCallback | null = null;
/**
* android 文件监听实现
*/
@Suppress("DEPRECATION")
* android 文件监听实现
*/
class ScreenFileObserver extends FileObserver {
/**
* 所有截屏文件的存放目录
*/
allScreen: File;
* 截屏文件目录
*/
private screenFile : File;
constructor(screenFile: string) {
super(new File(screenFile))
this.allScreen = new File(screenFile);
constructor(screenFile : File) {
super(screenFile);
this.screenFile = screenFile;
}
override onEvent(event: Int, path?: string): void {
override onEvent(event : Int, path : string | null) : 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
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 : OnUserCaptureScreenCallbackResult = {
path: screenShotPath
}
listener?.(res);
}
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 ;
* 开启截图监听
*/
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);
return;
}
imageChange = callback;
// 更新监听
listener = 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");
let directory_screenshot : File;
if (Build.MANUFACTURER.toLowerCase() == "xiaomi") {
// @Suppress("DEPRECATION")
directory_screenshot = new File(new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM), "Screenshots");
} else {
directory_screenshot = new File(directory_pictures, "Screenshots");
// @Suppress("DEPRECATION")
directory_screenshot = new File(new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_PICTURES), "Screenshots");
}
// 先结束监听 再开启监听
observer?.stopWatching();
observer = new ScreenFileObserver(directory_screenshot);
observer?.startWatching();
UTSAndroid.onAppActivityDestroy(function(){
observer?.stopWatching()
observer = null
})
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) {
* 关闭截屏监听
*/
export const offUserCaptureScreen : OffUserCaptureScreen = function (_ : UserCaptureScreenCallback | null) {
// android10以上,关闭监听通过移除文件监听器实现
observer?.stopWatching();
observer = null;
lastObserverTime = 0;
}
// android 10以上,关闭监听通过移除文件监听器实现
if (screenOB != null) {
screenOB!.stopWatching()
screenOB = null
}
lastFileObserverTime = 0;
success({});
/**
* 设置是否禁止截屏
*/
export const setUserCaptureScreen : SetUserCaptureScreen = function (option : SetUserCaptureScreenOptions) {
// 切换到UI线程
UTSAndroid.getUniActivity()?.runOnUiThread(new SetUserCaptureScreenRunnable(option.enable));
const res : SetUserCaptureScreenSuccess = {}
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);
}
}
}
import { NotificationCenter } from 'Foundation';
import { UIApplication } from "UIKit"
import { Selector } from "ObjectiveC"
/**
* 定义监听截屏事件工具类
*/
class CaptureScreenTool {
static listener: UTSCallback | null;
// 监听截屏
static listenCaptureScreen(callback: UTSCallback | null) {
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() {
// 触发回调
this.listener?.({})
}
// 移除监听事件
static removeListen(callback: UTSCallback | null) {
import { CGRect } from "CoreFoundation";
import { UIApplication, UIView, UITextField, UIScreen, UIDevice } from "UIKit"
import { UTSiOS } from "DCloudUTSFoundation"
import { DispatchQueue } from 'Dispatch';
import { SetUserCaptureScreenOptions, OnUserCaptureScreenCallbackResult, OnUserCaptureScreen, OffUserCaptureScreen, SetUserCaptureScreen, UserCaptureScreenCallback, SetUserCaptureScreenSuccess, SetUserCaptureScreenFail } from "../interface.uts"
/**
* 定义监听截屏事件工具类
*/
class CaptureScreenTool {
static listener : UserCaptureScreenCallback | null;
static secureView : UIView | null;
// 监听截屏
static listenCaptureScreen(callback : UserCaptureScreenCallback | null) {
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 res: OnUserCaptureScreenCallbackResult = {
}
this.listener?.(res)
}
// 移除监听事件
static removeListen(callback : UserCaptureScreenCallback | null) {
this.listener = null
NotificationCenter.default.removeObserver(this)
callback?.({})
}
}
/**
* 开启截图监听
*/
export function onUserCaptureScreen(callback: UTSCallback | null) {
CaptureScreenTool.listenCaptureScreen(callback)
}
}
static createSecureView() : UIView | null {
let field = new UITextField(frame = CGRect.zero)
field.isSecureTextEntry = true
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
}
return null
}
// 开启防截屏
static onAntiScreenshot(option : SetUserCaptureScreenOptions) {
// 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
}
}
let res: SetUserCaptureScreenSuccess = {
}
option.success?.(res)
option.complete?.(res)
})
}
// 关闭防截屏
static offAntiScreenshot(option : SetUserCaptureScreenOptions) {
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
}
let res: SetUserCaptureScreenSuccess = {
}
option.success?.(res)
option.complete?.(res)
})
}
}
/**
* 开启截图监听
*/
export const onUserCaptureScreen : OnUserCaptureScreen = function (callback : UserCaptureScreenCallback | null) {
CaptureScreenTool.listenCaptureScreen(callback)
}
/**
* 关闭截屏监听
*/
export const offUserCaptureScreen : OffUserCaptureScreen = function (callback : UserCaptureScreenCallback | null) {
CaptureScreenTool.removeListen(callback)
}
/**
* 开启/关闭防截屏
*/
export const setUserCaptureScreen : SetUserCaptureScreen = function (options : SetUserCaptureScreenOptions) {
if (UIDevice.current.systemVersion < "13.0") {
let res: SetUserCaptureScreenFail = {
errCode: 12001,
errSubject: "uni-usercapturescreen",
errMsg: "setUserCaptureScreen:system not support"
}
options.fail?.(res);
options.complete?.(res);
} else if (UIDevice.current.systemVersion == "15.1") {
let res: SetUserCaptureScreenFail = {
errCode: 12010,
errSubject: "uni-usercapturescreen",
errMsg: "setUserCaptureScreen:system internal error"
}
options.fail?.(res);
options.complete?.(res);
} else {
if (options.enable == true) {
CaptureScreenTool.offAntiScreenshot(options)
} else {
CaptureScreenTool.onAntiScreenshot(options)
}
}
}
/**
* 关闭截屏监听
*/
export function offUserCaptureScreen(callback: UTSCallback | null) {
CaptureScreenTool.removeListen(callback)
}
\ No newline at end of file
/**
* uni.onUserCaptureScreen/uni.offUserCaptureScreen回调参数
*/
export type OnUserCaptureScreenCallbackResult = {
/**
* 截屏文件路径(仅Android返回)
*/
path ?: string
}
/**
* uni.onUserCaptureScreen/uni.offUserCaptureScreen回调函数定义
*/
export type UserCaptureScreenCallback = (res : OnUserCaptureScreenCallbackResult) => void
/**
* uni.onUserCaptureScreen函数定义
* 开启截屏监听
*
* @param {UserCaptureScreenCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/capture-screen.html#onusercapturescreen
* @platforms APP-IOS = ^9.0,APP-ANDROID = ^19
* @since 3.6.8
*/
export type OnUserCaptureScreen = (callback : UserCaptureScreenCallback | null) => void
/**
* uni.offUserCaptureScreen函数定义
* 关闭截屏监听
*
* @param {UserCaptureScreenCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/capture-screen.html#offusercapturescreen
* @platforms APP-IOS = ^9.0,APP-ANDROID = ^19
* @since 3.6.8
*/
export type OffUserCaptureScreen = (callback : UserCaptureScreenCallback | null) => void
/**
* uni.setUserCaptureScreen成功回调参数
*/
export type SetUserCaptureScreenSuccess = {
}
/**
* uni.setUserCaptureScreen失败回调参数
*/
export type SetUserCaptureScreenFail = {
/**
* 错误码
* 0:成功
* -1:permission denied
* 12001:system not support
* 12010:system internal error
*/
errCode : number,
/**
* 调用API的名称
*/
errSubject : string,
/**
* 错误的详细信息
*/
errMsg : string,
}
/**
* uni.setUserCaptureScreen成功回调函数定义
*/
export type SetUserCaptureScreenSuccessCallback = (res : SetUserCaptureScreenSuccess) => void
/**
* uni.setUserCaptureScreen失败回调函数定义
*/
export type SetUserCaptureScreenFailCallback = (res : SetUserCaptureScreenFail) => void
/**
* uni.setUserCaptureScreen完成回调函数定义
*/
export type SetUserCaptureScreenCompleteCallback = (res : any) => void
/**
* uni.setUserCaptureScreen参数
*/
export type SetUserCaptureScreenOptions = {
/**
* true: 允许用户截屏 false: 不允许用户截屏,防止用户截屏到应用页面内容
*/
enable : boolean;
/**
* 接口调用成功的回调函数
*/
// success : SetUserCaptureScreenSuccessCallback | null,
success ?: SetUserCaptureScreenSuccessCallback,
/**
* 接口调用失败的回调函数
*/
// fail : SetUserCaptureScreenFailCallback | null,
fail ?: SetUserCaptureScreenFailCallback,
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
*/
// complete : SetUserCaptureScreenSuccessCallback | SetUserCaptureScreenFailCallback | null
complete ?: SetUserCaptureScreenCompleteCallback
}
/**
* * uni.setUserCaptureScreen函数定义
* 设置防截屏
*
* @param {SetUserCaptureScreenOptions} options
* @tutorial https://uniapp.dcloud.net.cn/api/system/capture-screen.html#setusercapturescreen
* @platforms APP-IOS = ^13.0,APP-ANDROID = ^19
* @since 3.7.3
*/
export type SetUserCaptureScreen = (options : SetUserCaptureScreenOptions) => void
interface uni {
onUserCaptureScreen : OnUserCaptureScreen,
offUserCaptureScreen : OffUserCaptureScreen,
setUserCaptureScreen : SetUserCaptureScreen
}
\ No newline at end of file
......@@ -42,7 +42,7 @@ type GetConnectedWifiOptions = {
*/
type WifiConnectOption = {
SSID:string;
BSSID:string;
BSSID?:string;
password:string;
maunal:boolean;
// 只返回ssid
......
......@@ -8,23 +8,23 @@ import { UIDevice } from 'UIKit';
* Wifi 函数通用入参封装
*/
type WifiOption = {
success?: (res: object) => void;
fail?: (res: object) => void;
complete?: (res: object) => void;
success?: (res: UniWifiResult) => void;
fail?: (res: UniWifiResult) => void;
complete?: (res: UniWifiResult) => void;
};
/**
* Wifi 链接参数封装
*/
type WifiConnectOption = {
SSID: string;
BSSID: string;
password: string;
maunal: boolean;
partialInfo: boolean; //ios不生效
success?: (res: object) => void;
fail?: (res: object) => void;
complete?: (res: object) => void;
SSID?: string;
BSSID?: string;
password?: string;
maunal?: boolean;
partialInfo?: boolean; //ios不生效
success?: (res: UniWifiResult) => void;
fail?: (res: UniWifiResult) => void;
complete?: (res: UniWifiResult) => void;
}
/**
......@@ -32,9 +32,9 @@ type WifiConnectOption = {
*/
type GetConnectedWifiOptions = {
partialInfo?: boolean
success?: (res: UTSJSONObject) => void
fail?: (res: UTSJSONObject) => void
complete?: (res: UTSJSONObject) => void
success?: (res: UniWifiResult) => void
fail?: (res: UniWifiResult) => void
complete?: (res: UniWifiResult) => void
}
/*
......@@ -48,6 +48,15 @@ type UniWifiInfo = {
frequency: number;
}
type UniWifiResult = {
errCode : number,
errSubject : string,
errMsg : string,
wifi: UniWifiInfo | null
}
type UniWifiCallback = () => void
/*
* 系统定位权限获取类
......@@ -114,12 +123,13 @@ function requestLocationPromise(@escaping completion: (res: boolean)=>void) {
*/
function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions) {
let arr = CNCopySupportedInterfaces()
let wifiInfo = new UniWifiInfo()
wifiInfo.BSSID = ""
wifiInfo.SSID = ""
wifiInfo.secure = false
wifiInfo.signalStrength = 0
wifiInfo.frequency = 0
let wifiInfo: UniWifiInfo = {
BSSID: "",
SSID: "",
secure: false,
signalStrength: 0,
frequency: 0
}
if (arr != null) {
let list = arr! as NSArray
......@@ -148,7 +158,7 @@ function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions)
}
if (wifiInfo.BSSID.length > 0 && wifiInfo.SSID.length > 0) {
let res = {
let res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 0,
errMsg: "getConnectedWifi:ok",
......@@ -157,19 +167,21 @@ function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions)
option.success?.(res)
option.complete?.(res)
}else {
const res = {
const res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 12010,
errMsg: "getConnectedWifi:system internal error"
errMsg: "getConnectedWifi:system internal error",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
}
}else {
const res = {
const res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 12010,
errMsg: "getConnectedWifi:system internal error"
errMsg: "getConnectedWifi:system internal error",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
......@@ -182,7 +194,7 @@ function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions)
* 保存全局数据信息
*/
class UniWiFiModuleGloabInfo {
static alreadyStartWifi: boolean
static alreadyStartWifi: boolean = false
}
/* =================================== 对外暴露的接口 ==============================================*/
......@@ -194,10 +206,11 @@ class UniWiFiModuleGloabInfo {
*/
export function startWifi(option: WifiOption) {
UniWiFiModuleGloabInfo.alreadyStartWifi = true
let res = {
let res: UniWifiResult = {
errSubject: "uni-startWifi",
errCode: 0,
errMsg: "startWifi:ok"
errMsg: "startWifi:ok",
wifi: null
}
option.success?.(res)
option.complete?.(res)
......@@ -209,10 +222,11 @@ export function startWifi(option: WifiOption) {
export function stopWifi(option: WifiOption) {
UniWiFiModuleGloabInfo.alreadyStartWifi = false
LocationPromiseService.promiseCompletionHandler = []
let res = {
let res: UniWifiResult = {
errSubject: "uni-stopWifi",
errCode: 0,
errMsg: "stopWifi:ok"
errMsg: "stopWifi:ok",
wifi: null
}
option.success?.(res)
option.complete?.(res)
......@@ -222,10 +236,11 @@ export function stopWifi(option: WifiOption) {
* 获取wifi列表, 在调用之前需要引导用户跳转到系统设置-WIFI设置页面,系统搜索周边wifi后app才能接收到回调
*/
export function getWifiList(option: WifiOption) {
let res = {
let res: UniWifiResult = {
errSubject: "uni-getWifiList",
errCode: 12001,
errMsg: "getWifiList:system not support"
errMsg: "getWifiList:system not support",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
......@@ -234,14 +249,14 @@ export function getWifiList(option: WifiOption) {
/* 获取wifi列表的回调
* note: 请在getWifiList方法的回调里调用该方法
*/
export function onGetWifiList(callback: UTSCallback) {
export function onGetWifiList(callback: UniWifiCallback) {
}
/*
* 注销获取wifi列表的回调
*/
export function offGetWifiList(callback: UTSCallback) {
export function offGetWifiList(callback: UniWifiCallback) {
}
......@@ -251,10 +266,11 @@ export function offGetWifiList(callback: UTSCallback) {
*/
export function getConnectedWifi(option: GetConnectedWifiOptions) {
if (UniWiFiModuleGloabInfo.alreadyStartWifi == false) {
let res = {
let res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 12000,
errMsg: "getConnectedWifi:not init",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
......@@ -264,10 +280,11 @@ export function getConnectedWifi(option: GetConnectedWifiOptions) {
if (success == true) {
fetchConnectedWifiWithLocationPromise(option)
}else {
let res = {
let res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 12007,
errMsg: "getConnectedWifi:user denied",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
......@@ -283,10 +300,11 @@ export function getConnectedWifi(option: GetConnectedWifiOptions) {
* 连接wifi
*/
export function connectWifi(option: WifiConnectOption) {
let res = {
let res: UniWifiResult = {
errSubject: "uni-connectWifi",
errCode: 12001,
errMsg: "connectWifi:system not support"
errMsg: "connectWifi:system not support",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
......@@ -296,28 +314,28 @@ export function connectWifi(option: WifiConnectOption) {
/*
* 连上wifi事件的监听函数
*/
export function onWifiConnected(callback: UTSCallback) {
export function onWifiConnected(callback: UniWifiCallback) {
}
/*
* 连上wifi事件的监听函数, wifiInfo仅包含ssid
*/
export function onWifiConnectedWithPartialInfo(callback: UTSCallback) {
export function onWifiConnectedWithPartialInfo(callback: UniWifiCallback) {
}
/*
* 移除连接上wifi的事件的监听函数,不传此参数则移除所有监听函数。
*/
export function offWifiConnected(callback: UTSCallback | null) {
export function offWifiConnected(callback: UniWifiCallback | null) {
}
/*
* 移除连接上wifi的事件的监听函数,不传此参数则移除所有监听函数。
*/
export function onOffWifiConnectedWithPartialInfo(callback: UTSCallback | null) {
export function onOffWifiConnectedWithPartialInfo(callback: UniWifiCallback | null) {
}
......@@ -325,10 +343,11 @@ export function onOffWifiConnectedWithPartialInfo(callback: UTSCallback | null)
* 设置 wifiList 中 AP 的相关信息。在 onGetWifiList 回调后调用,iOS特有接口。
*/
export function setWifiList(option: WifiOption) {
let res = {
let res: UniWifiResult = {
errSubject: "uni-setWifiList",
errCode: 12001,
errMsg: "setWifiList:system not support"
errMsg: "setWifiList:system not support",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册