diff --git a/.gitignore b/.gitignore index 4cd3d5ce..4d13492f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,10 +8,12 @@ .externalNativeBuild output.json output-metadata.json +desktop.ini + +.git/ +.gradle/ +.idea/ -/.git/ -/.gradle/ -/.idea/ /build/ /libs/**/build/ /captures/ @@ -21,4 +23,5 @@ output-metadata.json /local.properties /sign.properties -**/assets/declarations/ \ No newline at end of file +**/assets/declarations/ +**/assets/sample/.declarations/ \ No newline at end of file diff --git a/README.md b/README.md index 7c39580b..c566faff 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,14 @@

GitHub release (latest by date) GitHub closed issues - Rhino CodeFactor Grade LGTM Grade
+ Rhino + Android Studio +
Created GitHub Code Size - GitHub Code Lines GitHub License

@@ -26,7 +27,7 @@ ### 简介 * Android 平台支持无障碍服务的 JavaScript 自动化工具 -* 需要 [Android 7.0](https://zh.wikipedia.org/wiki/Android_Nougat) (`API 24`) 及以上 +* 需要 [Android 7.0](https://zh.wikipedia.org/wiki/Android_Nougat) ([API](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels) [24](https://developer.android.com/reference/android/os/Build.VERSION_CODES#N)) 及以上 * 复刻 (Fork) 自 [hyb1996/Auto.js](https://github.com/hyb1996/Auto.js) ****** @@ -35,7 +36,7 @@ ****** -* [项目文档](http://docs.autojs.org) +* [项目文档](https://hyb1996.github.io/AutoJs-Docs) (临时参考文档) ****** @@ -65,7 +66,7 @@ * VSCode 插件支持客户端 (LAN) 及服务端 (LAN/ADB) 连接方式 -* Rhino 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升级至 [v1.7.14](https://github.com/mozilla/rhino/) +* [Rhino](https://github.com/mozilla/rhino/) 引擎由 [v1.7.7.2](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_7_2_Release) 升级至 [v1.7.15-SNAPSHOT](https://github.com/SuperMonster003/Rhino-For-AutoJs6/commits/master) * 支持 [Object.values()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/values) @@ -103,12 +104,60 @@ [comment]: <> "Version history only shows last 3 versions" +# v6.1.0 + +###### 2022/05/26 - 包名变更 谨慎升级 + +* `提示` 修改应用包名为 org.autojs.autojs6 避免与开源 Auto.js 应用包名冲突 +* `新增` 首页抽屉增加 "投影媒体权限" 开关 (Root / ADB 方式) (开关状态检测为实验性) +* `新增` 文件浏览器支持显示隐藏文件和文件夹 (参阅 设置页面) +* `新增` 强制 Root 检查功能 (参阅 设置页面 及 示例代码) +* `新增` 内置 autojs 模块 (参阅 示例代码 > AutoJs6) +* `新增` 内置 tasks 模块 (参阅 示例代码 > 任务) +* `新增` console.launch() 方法启动日志活动页面 +* `新增` util.morseCode 工具 (参阅 示例代码 > 工具 > 摩斯电码) +* `新增` util.versionCodes 工具 (参阅 示例代码 > 工具 > 安卓版本信息查询) +* `新增` util.getClass() 等方法 (参阅 示例代码 > 工具 > 获取类与类名) +* `新增` timers.setIntervalExt() 方法 (参阅 示例代码 > 定时器 > 条件周期执行) +* `新增` colors.toInt() / rgba() 等方法 (参阅 示例代码 > 图像与颜色 > 基本颜色转换) +* `新增` automator.isServiceEnabled() / ensureService() 方法 +* `新增` automator.lockScreen() 等方法 (参阅 示例代码 > 无障碍服务 > 安卓 9 新增) +* `新增` automator.headsethook() 等方法 (参阅 示例代码 > 无障碍服务 > 安卓 11 新增) +* `新增` automator.captureScreen() 方法 (参阅 示例代码 > 无障碍服务 > 获取屏幕截图) +* `新增` dialogs.build() 选项参数属性 animation, linkify 等 (参阅 示例代码 > 对话框 > 个性化对话框) +* `修复` dialogs.build() 选项参数属性 inputHint, itemsSelectedIndex 等功能异常 +* `修复` JsDialog#on('multi_choice') 回调参数功能异常 +* `修复` UiObject#parent().indexInParent() 总是返回 -1 的问题 _[`issue #16`](https://github.com/SuperMonster003/AutoJs6/issues/16)_ +* `修复` Promise.resolve() 返回的 Thenable 在临近脚本结束时可能不被调用的问题 +* `修复` 包名或类名中可能的拼写失误 (boardcast -> broadcast / auojs -> autojs) +* `修复` images.requestScreenCapture() 在高版本安卓系统可能导致应用崩溃的问题 (API >= 31) +* `修复` images.requestScreenCapture() 多个脚本实例同时申请可能导致应用崩溃的问题 +* `修复` 调用 new RootAutomator() 可能出现的假死问题 +* `优化` RootAutomator 在无 Root 权限时将无法实例化 +* `优化` 重新设计 "关于应用与开发者" 页面 +* `优化` 重构全部内置 JavaScript 模块 +* `优化` 重构全部 Gradle 构建脚本并增加公共配置脚本 (config.gradle) +* `优化` Gradle 构建工具支持版本号自动管理及构建文件自动命名 +* `优化` Gradle 构建工具增加 task 支持附加 CRC32 摘要到构建文件 (appendDigestToReleasedFiles) +* `优化` shell() 调用时将异常写入返回结果而非直接将异常抛出 (无需 try/catch) +* `优化` 使用 Rhino 内置的 JSON 替代原 json2 模块 +* `优化` auto.waitFor() 支持超时参数 +* `优化` threads.start() 支持箭头函数参数 +* `优化` console.trace() 支持按日志等级参数 (参阅 示例代码 > 控制台 > 打印调用栈) +* `优化` device.vibrate() 支持模式震动及摩斯电码震动 (参阅 示例代码 > 设备 > 模式震动 / 摩斯电码震动) +* `优化` 外部存储读写权限适配高版本安卓系统 (API >= 30) +* `优化` 控制台字体采用 Material Color 增强普通及夜间主题下的字体可读性 +* `优化` 保存 ImageWrapper 所有实例弱引用并在脚本结束时自动回收 (实验性) +* `优化` 附加 CircleImageView 版本 3.1.0 +* `优化` 升级 Rhino 引擎版本 1.7.14 -> 1.7.15-snapshot +* `优化` 部分依赖或本地库版本调整 (详见 [`CHANGELOG.md`](https://github.com/SuperMonster003/AutoJs6/blob/master/app/src/main/assets/doc/CHANGELOG.md#v610)) + # v6.0.3 ###### 2022/03/19 * `新增` 多语言切换功能 (尚不完善) -* `新增` recorder 模块 (参阅 示例代码 > 计时器 > *.js × 4) +* `新增` 内置 recorder 模块 (参阅 示例代码 > 计时器) * `新增` 使用 "修改安全设置权限" 自动启用无障碍服务及开关设置 * `修复` 点击 "快速设置" 中相关图标后面板未自动收起的问题 (试修) _[`issue #7`](https://github.com/SuperMonster003/AutoJs6/issues/7)_ * `修复` toast 使用强制显示参数时可能导致 AutoJs6 崩溃的问题 @@ -126,15 +175,7 @@ * `优化` 转移打包插件下载地址 GitHub -> JsDelivr * `优化` 附加 Zeugma Solutions LocaleHelper 版本 1.5.1 * `优化` 降级 Android Material 版本 1.6.0-alpha02 -> 1.5.0 -* `优化` 升级 Kotlinx Coroutines 版本 1.6.0-native-mt -> 1.6.0 -* `优化` 升级 OpenCV 版本 3.4.3 -> 4.5.4 -> 4.5.5 (Ref to TonyJiangWJ) -* `优化` 升级 Okhttp3 版本 3.10.0 -> 5.0.0-alpha.4 -> 5.0.0-alpha.6 -* `优化` 升级 Android Gradle 插件版本 7.2.0-beta01 -> 7.3.0-alpha06 -* `优化` 升级 Auto.js-ApkBuilder 版本 1.0.1 -> 1.0.3 -* `优化` 升级 Glide Compiler 版本 4.12.0 -> 4.13.1 -* `优化` 升级 Gradle 发行版本 7.4-rc-2 -> 7.4.1 -* `优化` 升级 Gradle Compile 版本 31 -> 32 -* `优化` 升级 Gson 版本 2.8.9 -> 2.9.0 +* `优化` 部分依赖或本地库版本调整 (详见 [`CHANGELOG.md`](https://github.com/SuperMonster003/AutoJs6/blob/master/app/src/main/assets/doc/CHANGELOG.md#v603)) # v6.0.2 @@ -148,30 +189,8 @@ * `修复` Android 7 解析 UI 模式 text 元素异常 (Ref to TonyJiangWJ) _[`issue #4`](https://github.com/SuperMonster003/AutoJs6/issues/4)_ _[`#9`](https://github.com/SuperMonster003/AutoJs6/issues/9)_ * `优化` 忽略 sleep() 的 ScriptInterruptedException 异常 * `优化` 附加 Androidx AppCompat (Legacy) 版本 1.0.2 -* `优化` 升级 Androidx AppCompat 版本 1.4.0 -> 1.4.1 -* `优化` 升级 Androidx Preference 版本 1.1.1 -> 1.2.0 -* `优化` 升级 Okhttp3 版本 3.10.0 -> 5.0.0-alpha.3 -> 5.0.0-alpha.4 -* `优化` 升级 Android Material 版本 1.6.0-alpha01 -> 1.6.0-alpha02 -* `优化` 升级 Android Gradle 插件版本 7.2.0-alpha06 -> 7.2.0-beta01 -* `优化` 升级 Gradle 发行版本 7.3.3 -> 7.4-rc-2 - -# v6.0.1 - -###### 2022/01/01 - -* `新增` 连接 VSCode 插件支持客户端 (LAN) 及服务端 (LAN/ADB) 方式 (Ref to Auto.js Pro) -* `新增` 增加 $base64 全局对象 (Ref to Auto.js Pro) -* `新增` 增加 isInteger/isNullish/isPlainObject/isPrimitive/isReference 全局方法 -* `新增` 增加 polyfill (Object.getOwnPropertyDescriptors) -* `新增` 增加 polyfill (Array.prototype.flat) -* `优化` 扩展 global.sleep 支持 随机范围/负数兼容 -* `优化` 扩展 global.toast 支持 时长控制/强制覆盖控制/dismiss -* `优化` 包名对象全局化 (okhttp3/androidx/de) -* `优化` 升级 Android Material 版本 1.5.0-beta01 -> 1.6.0-alpha01 -* `优化` 升级 Android Gradle 插件版本 7.2.0-alpha04 -> 7.2.0-alpha06 -* `优化` 升级 Kotlinx Coroutines 版本 1.5.2-native-mt -> 1.6.0-native-mt -* `优化` 升级 Kotlin Gradle 插件版本 1.6.0 -> 1.6.10 -* `优化` 升级 Gradle 发行版本 7.3 -> 7.3.3 +* `优化` 升级 Rhino 引擎版本 1.7.14-snapshot -> 1.7.14 +* `优化` 部分依赖或本地库版本调整 (详见 [`CHANGELOG.md`](https://github.com/SuperMonster003/AutoJs6/blob/master/app/src/main/assets/doc/CHANGELOG.md#v602)) ##### 更多版本历史可参阅 diff --git a/app/build.gradle b/app/build.gradle index 3785fd0b..de389287 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,155 +1,27 @@ -plugins { - id 'com.android.application' - id 'com.jakewharton.butterknife' - id 'kotlin-android' - id 'kotlin-kapt' +ext { + applicationId = 'org.autojs.autojs6' + namespace = applicationId } -def properties = new Properties() -def propFile = new File('sign.properties') -def isPropFileExists = propFile.exists() - -isPropFileExists && properties.load(new FileInputStream(propFile)) - -tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { - kotlinOptions { - jvmTarget = JavaVersion.VERSION_16 - } -} - -// tasks.withType(JavaCompile) { -// options.compilerArgs << '-Xlint:deprecation' << '-Xlint:unchecked' -// } - -android { - signingConfigs { - isPropFileExists && release { - storeFile file(properties['storeFile']) - keyPassword properties['keyPassword'] - keyAlias properties['keyAlias'] - storePassword properties['storePassword'] - } - } - compileSdkVersion versions.project.compile - defaultConfig { - applicationId 'org.autojs.autojs' - minSdkVersion versions.project.mini - targetSdkVersion versions.project.target - versionCode versions.project.appVersionCode - versionName versions.project.appVersionName - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' - multiDexEnabled true - javaCompileOptions { - annotationProcessorOptions { - arguments = [ - 'resourcePackageName': applicationId, - 'androidManifestFile': "$projectDir/src/main/AndroidManifest.xml".toString() - ] - } - } - } - buildTypes { - debug { - shrinkResources false - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - if (isPropFileExists) { - signingConfig signingConfigs.release - } - // Disable Crashlytics reports. - ext.enableCrashlytics = false - // Disables PNG crunching for the release build type. - crunchPngs false - } - release { - shrinkResources false - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - if (isPropFileExists) { - signingConfig signingConfigs.release - } - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_16 - targetCompatibility JavaVersion.VERSION_16 - encoding = 'utf-8' - } - lintOptions { - abortOnError false - disable 'MissingTranslation' - disable 'ExtraTranslation' - } - configurations.all { - resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1' - } - flavorDimensions 'channel' - splits { - // Configures multiple APKs based on ABI. - abi { - // Enables building multiple APKs per ABI. - enable true - - // By default all ABIs are included, so use reset() and include to specify that we only - // want APKs for x86 and x86_64. - - // Resets the list of ABIs that Gradle should create APKs for to none. - reset() - - // Specifies a list of ABIs that Gradle should create APKs for. - include 'x86', 'armeabi-v7a', 'arm64-v8a', 'x86_64' - - // Specifies that we do not want to also generate a universal APK that includes all ABIs. - universalApk true - } - } - productFlavors { - common { - buildConfigField 'String', 'CHANNEL', '"common"' - buildConfigField 'String', 'APP_SINCE_DATE', "\"${versions.project.appSinceDate}\"" - } - } - applicationVariants.all { variant -> - variant.outputs.all { output -> - def aj = "AutoJs6" - def ver = versionName.replaceAll(/\s/, "-") - - // FIXME by SuperMonster003 as of Mar 19, 2022. - // ! Interface com.android.build.OutputFile is deprecated. - // ! Another way of getting ABI is needed. - def abi = getFilter(com.android.build.OutputFile.ABI) - - output.outputFileName = "${aj}-v${ver}-${abi ? "${abi}" : "universal"}.apk".toLowerCase() - } - variant.mergeAssetsProvider.configure { - doLast { - delete(fileTree(dir: outputDir, includes: ['declarations/**'])) - } - } - } -} - -repositories { - google() +apply { + from rootProject.file('config.gradle') + plugin 'kotlin-kapt' } dependencies { - // JUnit - testImplementation "junit:junit:${versions.junit}" - // LeakCanary - debugImplementation "com.squareup.leakcanary:leakcanary-android:${versions.leakcanary}" + debugImplementation "com.squareup.leakcanary:leakcanary-android:2.9.1" // Kotlin - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1-native-mt' // Android Annotations - kapt "org.androidannotations:androidannotations:${versions.annotations}" - implementation "org.androidannotations:androidannotations-api:${versions.annotations}" + kapt "org.androidannotations:androidannotations:4.8.0" + implementation "org.androidannotations:androidannotations-api:4.8.0" // ButterKnife - kapt "com.jakewharton:butterknife-compiler:${versions.butterKnife}" - implementation "com.jakewharton:butterknife:${versions.butterKnife}" + kapt "com.jakewharton:butterknife-compiler:10.2.3" + implementation "com.jakewharton:butterknife:10.2.3" // Android supports implementation 'androidx.cardview:cardview:1.0.0' @@ -194,19 +66,19 @@ dependencies { implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' // Glide - kapt "com.github.bumptech.glide:compiler:${versions.glide}" + kapt "com.github.bumptech.glide:compiler:4.13.2" // Joda Time - implementation 'joda-time:joda-time:2.10.13' + implementation 'joda-time:joda-time:2.10.14' // Tasker Plugin implementation 'com.twofortyfouram:android-plugin-client-sdk-for-locale:4.0.3' // Flurry - implementation 'com.flurry.android:analytics:13.1.0' + implementation 'com.flurry.android:analytics:13.3.0' // Android Job - implementation 'com.evernote:android-job:1.4.2' + implementation 'com.evernote:android-job:1.4.3' // Extracted from com.github.hyb1996:MutableTheme:1.0.0 implementation 'com.jrummyapps:colorpicker:2.1.7' @@ -214,14 +86,8 @@ dependencies { implementation 'com.github.ozodrukh:CircularReveal:2.0.1' // Bugly - implementation project(':libs:com.tencent.bugly.crashreport-2.6.6') + implementation project(':libs:com.tencent.bugly.crashreport-4.0.4') - implementation project(':automator') - implementation project(':common') + // Indirect: automator, common implementation project(':autojs') } - -java { - sourceCompatibility = JavaVersion.VERSION_16 - targetCompatibility = JavaVersion.VERSION_16 -} \ No newline at end of file diff --git a/app/src/androidTest/java/org/autojs/autojs/statics/RhinoE4XTest.java b/app/src/androidTest/java/org/autojs/autojs/statics/RhinoE4XTest.java index e094792b..89674fd7 100644 --- a/app/src/androidTest/java/org/autojs/autojs/statics/RhinoE4XTest.java +++ b/app/src/androidTest/java/org/autojs/autojs/statics/RhinoE4XTest.java @@ -7,7 +7,6 @@ import org.mozilla.javascript.Scriptable; /** * Created by Stardust on 2017/5/13. */ - public class RhinoE4XTest { @Test diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 78616f31..2c542d96 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,33 +2,37 @@ xmlns:tools="http://schemas.android.com/tools" package="org.autojs.autojs"> - - - + + + + + android:name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS" + tools:ignore="ProtectedPermissions" /> - + + - - - - + tools:replace="android:label, android:allowBackup" + tools:ignore="DataExtractionRules"> - + @@ -165,7 +170,7 @@ android:exported="true" android:icon="@drawable/ic_android_eat_js" android:label="@string/app_name" - android:targetActivity=".external.tasker.TaskPrefEditActivity_" + android:targetActivity="org.autojs.autojs.external.tasker.TaskPrefEditActivity_" tools:ignore="ExportedActivity"> diff --git a/app/src/main/assets/doc/CHANGELOG.md b/app/src/main/assets/doc/CHANGELOG.md index dc7b5044..d2d633fa 100644 --- a/app/src/main/assets/doc/CHANGELOG.md +++ b/app/src/main/assets/doc/CHANGELOG.md @@ -4,12 +4,73 @@ ****** +# v6.1.0 + +###### 2022/05/26 - 包名变更 谨慎升级 + +* `提示` 修改应用包名为 org.autojs.autojs6 避免与开源 Auto.js 应用包名冲突 +* `新增` 首页抽屉增加 "投影媒体权限" 开关 (Root / ADB 方式) (开关状态检测为实验性) +* `新增` 文件浏览器支持显示隐藏文件和文件夹 (参阅 设置页面) +* `新增` 强制 Root 检查功能 (参阅 设置页面 及 示例代码) +* `新增` 内置 autojs 模块 (参阅 示例代码 > AutoJs6) +* `新增` 内置 tasks 模块 (参阅 示例代码 > 任务) +* `新增` console.launch() 方法启动日志活动页面 +* `新增` util.morseCode 工具 (参阅 示例代码 > 工具 > 摩斯电码) +* `新增` util.versionCodes 工具 (参阅 示例代码 > 工具 > 安卓版本信息查询) +* `新增` util.getClass() 等方法 (参阅 示例代码 > 工具 > 获取类与类名) +* `新增` timers.setIntervalExt() 方法 (参阅 示例代码 > 定时器 > 条件周期执行) +* `新增` colors.toInt() / rgba() 等方法 (参阅 示例代码 > 图像与颜色 > 基本颜色转换) +* `新增` automator.isServiceEnabled() / ensureService() 方法 +* `新增` automator.lockScreen() 等方法 (参阅 示例代码 > 无障碍服务 > 安卓 9 新增) +* `新增` automator.headsethook() 等方法 (参阅 示例代码 > 无障碍服务 > 安卓 11 新增) +* `新增` automator.captureScreen() 方法 (参阅 示例代码 > 无障碍服务 > 获取屏幕截图) +* `新增` dialogs.build() 选项参数属性 animation, linkify 等 (参阅 示例代码 > 对话框 > 个性化对话框) +* `修复` dialogs.build() 选项参数属性 inputHint, itemsSelectedIndex 等功能异常 +* `修复` JsDialog#on('multi_choice') 回调参数功能异常 +* `修复` UiObject#parent().indexInParent() 总是返回 -1 的问题 _[`issue #16`](https://github.com/SuperMonster003/AutoJs6/issues/16)_ +* `修复` Promise.resolve() 返回的 Thenable 在临近脚本结束时可能不被调用的问题 +* `修复` 包名或类名中可能的拼写失误 (boardcast -> broadcast / auojs -> autojs) +* `修复` images.requestScreenCapture() 在高版本安卓系统可能导致应用崩溃的问题 (API >= 31) +* `修复` images.requestScreenCapture() 多个脚本实例同时申请可能导致应用崩溃的问题 +* `修复` 调用 new RootAutomator() 可能出现的假死问题 +* `优化` RootAutomator 在无 Root 权限时将无法实例化 +* `优化` 重新设计 "关于应用与开发者" 页面 +* `优化` 重构全部内置 JavaScript 模块 +* `优化` 重构全部 Gradle 构建脚本并增加公共配置脚本 (config.gradle) +* `优化` Gradle 构建工具支持版本号自动管理及构建文件自动命名 +* `优化` Gradle 构建工具增加 task 支持附加 CRC32 摘要到构建文件 (appendDigestToReleasedFiles) +* `优化` shell() 调用时将异常写入返回结果而非直接将异常抛出 (无需 try/catch) +* `优化` 使用 Rhino 内置的 JSON 替代原 json2 模块 +* `优化` auto.waitFor() 支持超时参数 +* `优化` threads.start() 支持箭头函数参数 +* `优化` console.trace() 支持按日志等级参数 (参阅 示例代码 > 控制台 > 打印调用栈) +* `优化` device.vibrate() 支持模式震动及摩斯电码震动 (参阅 示例代码 > 设备 > 模式震动 / 摩斯电码震动) +* `优化` 外部存储读写权限适配高版本安卓系统 (API >= 30) +* `优化` 控制台字体采用 Material Color 增强普通及夜间主题下的字体可读性 +* `优化` 保存 ImageWrapper 所有实例弱引用并在脚本结束时自动回收 (实验性) +* `优化` 附加 CircleImageView 版本 3.1.0 +* `优化` 升级 Android Analytics 版本 13.1.0 -> 13.3.0 +* `优化` 升级 Android Gradle 插件版本 7.3.0-alpha06 -> 7.4.0-alpha02 +* `优化` 升级 Android Job 版本 1.4.2 -> 1.4.3 +* `优化` 升级 Android Material 版本 1.5.0 -> 1.6.0 +* `优化` 升级 CrashReport 版本 2.6.6 -> 4.0.4 +* `优化` 升级 Glide 版本 4.13.1 -> 4.13.2 +* `优化` 升级 Joda Time 版本 2.10.13 -> 2.10.14 +* `优化` 升级 Kotlin Gradle 插件版本 1.6.10 -> 1.6.21 +* `优化` 升级 Kotlinx Coroutines 版本 1.6.0 -> 1.6.1-native-mt +* `优化` 升级 Leakcanary 版本 2.8.1 -> 2.9.1 +* `优化` 升级 Okhttp3 版本 5.0.0-alpha.6 -> 5.0.0-alpha.7 +* `优化` 升级 Rhino 引擎版本 1.7.14 -> 1.7.15-snapshot +* `优化` 升级 Zip4j 版本 2.9.1 -> 2.10.0 +* `优化` 移除 Groovy JSON 版本 3.0.8 +* `优化` 移除 Kotlin Stdlib JDK7 版本 1.6.21 + # v6.0.3 ###### 2022/03/19 * `新增` 多语言切换功能 (尚不完善) -* `新增` recorder 模块 (参阅 示例代码 > 计时器 > *.js × 4) +* `新增` 内置 recorder 模块 (参阅 示例代码 > 计时器) * `新增` 使用 "修改安全设置权限" 自动启用无障碍服务及开关设置 * `修复` 点击 "快速设置" 中相关图标后面板未自动收起的问题 (试修) _[`issue #7`](https://github.com/SuperMonster003/AutoJs6/issues/7)_ * `修复` toast 使用强制显示参数时可能导致 AutoJs6 崩溃的问题 @@ -51,6 +112,7 @@ * `优化` 附加 Androidx AppCompat (Legacy) 版本 1.0.2 * `优化` 升级 Androidx AppCompat 版本 1.4.0 -> 1.4.1 * `优化` 升级 Androidx Preference 版本 1.1.1 -> 1.2.0 +* `优化` 升级 Rhino 引擎版本 1.7.14-snapshot -> 1.7.14 * `优化` 升级 Okhttp3 版本 3.10.0 -> 5.0.0-alpha.3 -> 5.0.0-alpha.4 * `优化` 升级 Android Material 版本 1.6.0-alpha01 -> 1.6.0-alpha02 * `优化` 升级 Android Gradle 插件版本 7.2.0-alpha06 -> 7.2.0-beta01 @@ -61,7 +123,7 @@ ###### 2022/01/01 * `新增` 连接 VSCode 插件支持客户端 (LAN) 及服务端 (LAN/ADB) 方式 (Ref to Auto.js Pro) -* `新增` 增加 $base64 "工具类" (Ref to Auto.js Pro) +* `新增` 内置 base64 模块 (Ref to Auto.js Pro) * `新增` 增加 isInteger/isNullish/isPlainObject/isPrimitive/isReference 全局方法 * `新增` 增加 polyfill (Object.getOwnPropertyDescriptors) * `新增` 增加 polyfill (Array.prototype.flat) diff --git a/app/src/main/assets/doc/RHINO.md b/app/src/main/assets/doc/RHINO.md index cfd898ba..a3e89c0e 100644 --- a/app/src/main/assets/doc/RHINO.md +++ b/app/src/main/assets/doc/RHINO.md @@ -174,4 +174,41 @@ pad = o => o.padEnd(2, '_'); `${pad(h)}:${pad(m)}:${pad(s)}`; // '9_:30:7_' + ``` + +* [Object.hasOwn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn) + + ```javascript + let o = {a: 1}; + Object.defineProperty(o, 'b', {value: 2}); + + Object.hasOwn(o, 'a'); // true + o.hasOwnProperty('a'); // true + 'a' in o; // true + + Object.hasOwn(o, 'b'); // true + o.hasOwnProperty('b'); // true + 'b' in o; // true + + Object.hasOwn(o, 'toString'); // false + o.hasOwnProperty('toString'); // false + 'toString' in o; // true + + let p = Object.create(null); + Object.defineProperties(p, { + a: {value: 1, enumerable: true}, + b: {value: 2, enumerable: false}, + }); + + Object.hasOwn(p, 'a'); // true + // p.hasOwnProperty('a'); // TypeError + 'a' in p; // true + + Object.hasOwn(p, 'b'); // true + // p.hasOwnProperty('b'); // TypeError + 'b' in p; // true + + Object.hasOwn(p, 'toString'); // false + // p.hasOwnProperty('toString'); // TypeError + 'toString' in p; // false ``` \ No newline at end of file diff --git a/app/src/main/assets/docs/assets/sh_main.js b/app/src/main/assets/docs/assets/sh_main.js index fa9d8efd..6c4f70d0 100644 --- a/app/src/main/assets/docs/assets/sh_main.js +++ b/app/src/main/assets/docs/assets/sh_main.js @@ -529,7 +529,7 @@ function highlight(prefix, suffix, tag) { sh_highlightElement(element, sh_languages[language]); highlighted = true; } - else if (typeof(prefix) === 'string' && typeof(suffix) === 'string') { + else if (typeof prefix === 'string' && typeof suffix === 'string') { sh_load(language, element, prefix, suffix); } else { @@ -538,7 +538,7 @@ function highlight(prefix, suffix, tag) { break; } } - if (highlighted === false && donthighlight == false) { + if (highlighted === false && donthighlight === false) { sh_highlightElement(element, sh_languages["javascript"]); } } diff --git a/app/src/main/assets/indices/glossary.json b/app/src/main/assets/indices/glossary.json new file mode 100644 index 00000000..ceab3742 --- /dev/null +++ b/app/src/main/assets/indices/glossary.json @@ -0,0 +1,399 @@ +{ + "AXR": "Arrow function returns without (X) the Return keyword", + "a11y": "accessibility", + "acc": "account", + "accu": "accumulated", + "act": [ + "action", + "activity" + ], + "addn": [ + "addition", + "additional" + ], + "af": "ant forest", + "ahd": "ahead", + "amt": "amount", + "anm": "animation", + "app": "application", + "args": "arguments", + "argv": "argument values", + "asg": [ + "assign", + "assignment" + ], + "async": "asynchronous", + "avail": "available", + "avt": "avatar", + "b": [ + "bottom", + "bounds", + "backup", + "blue", + "bomb" + ], + "bak": "backup", + "blist": "blacklist", + "blt": "bilateral", + "bnd": [ + "bound", + "bounds" + ], + "bo": "bitmap options", + "btm": "bottom", + "btn": "button", + "buf": "buffer", + "c": [ + "checked", + "click", + "clickable", + "color", + "compass" + ], + "cbk": "callback", + "cf": "comparison (latin: conferatur)", + "cfg": "configuration", + "cfm": "confirm", + "chk": "check", + "cmd": "command", + "cmps": "compass", + "cnsl": "console", + "cnt": "count", + "col": "color", + "cond": "condition", + "constr": "constructor", + "cont": "content", + "coord": "coordination", + "ctd": "countdown", + "ctr": "counter", + "ctx": "context", + "cur": "current", + "cvr": "cover", + "cwd": "current working directory", + "cwp": "current working path", + "cxn": "connection", + "d": "dialog", + "dat": "data", + "dbg": "debug", + "dc": "decrease", + "dec": [ + "decode", + "decrypt" + ], + "def": "default", + "del": [ + "delete", + "deletion" + ], + "desc": "description", + "dev": [ + "device", + "development" + ], + "diag": "dialog", + "dic": "dictionary", + "diff": "difference", + "dis": "dismiss", + "disp": "display", + "dist": [ + "distance", + "disturb", + "disturbance" + ], + "dn": "down", + "dnt": "donation", + "dny": "dynamic", + "drxn": "direction", + "ds": "data source", + "dsk": "data source key", + "du": "duration", + "dupe": [ + "duplicate", + "duplicated", + "duplication" + ], + "dys": "dysfunctional", + "e": [ + "error", + "engine", + "event" + ], + "eball": "energy ball", + "eballs": "energy balls", + "ele": "element", + "emount": "energy amount", + "enabl": [ + "enable", + "enabled" + ], + "enc": [ + "encode", + "encrypt" + ], + "ens": "ensure", + "ent": "entrance", + "eq": "equal", + "eql": "equal", + "et": "elapsed time", + "ev": "event", + "evt": "event", + "ex": "exception", + "exc": "exclude", + "excl": "exclusive", + "excpt": "exception", + "exec": "execution", + "exp": "expected", + "ext": "extension", + "f": "function", + "fg": [ + "foreground", + "flag" + ], + "flg": "flag", + "flo": "floaty", + "fltr": "filter", + "forc": [ + "force", + "forcible", + "forcibly" + ], + "frac": "fraction", + "fri": "friend", + "frst": "forest", + "ft": "fault tolerance", + "fx": [ + "function", + "special effects" + ], + "fxo": "function object (an object with some functions)", + "fxs": "functions", + "g": "green", + "glob": "global", + "grn": "green", + "gt": "greater than", + "h": [ + "height", + "head", + "heads" + ], + "his": "history", + "horiz": "horizontal", + "i": [ + "intent", + "increment" + ], + "ic": "increase", + "ident": "identification", + "idt": "identification", + "idx": "index", + "ifn": "if needed", + "IIFE": "Immediately-Invoked Function Expression", + "inc": "increment", + "inf": "information", + "info": "information", + "inp": "input", + "ins": "insurance", + "inst": "instant", + "intrp": "interrupt", + "invt": "invitation", + "ipt": "input", + "itp": "interpolate", + "itv": "interval", + "js": "javascript", + "k": "key", + "kg": "keyguard", + "kw": "keyword", + "l": "left", + "lbl": "label", + "lch": "launch", + "len": "length", + "lmt": "limit", + "ln": "line", + "loc": "locator", + "ls": "list", + "lsn": [ + "listener", + "listeners" + ], + "lv": "level", + "lyt": "layout", + "man": [ + "manual", + "manually" + ], + "mch": [ + "match", + "matched" + ], + "mod": "module", + "mon": "monitor", + "msg": "message", + "mthd": "method", + "mv": "move", + "n": "name", + "nec": "necessary", + "neg": "negative", + "neu": "neutral", + "nm": "name", + "num": "number", + "nxt": "next", + "o": [ + "object", + "orange" + ], + "opr": "operation", + "opt": [ + "option", + "optional" + ], + "or": "orientation", + "ovl": "overlap", + "p": [ + "press", + "parent" + ], + "par": "parameter", + "param": "parameter", + "pat": "pattern", + "pct": "percentage", + "pg": "page", + "pkg": "package", + "pos": "position", + "pref": "prefix", + "prog": "progress", + "prv": "privilege", + "pw": "password", + "pwr": "power", + "q": "queue", + "qte": "quote", + "que": "queue", + "r": [ + "red", + "right", + "region" + ], + "rand": "random", + "rch": [ + "reach", + "reached" + ], + "rec": [ + "record", + "recorded" + ], + "recog": "recognition", + "rect": "rectangle", + "req": [ + "require", + "request" + ], + "res": [ + "resource", + "result", + "restore" + ], + "reso": [ + "resolve", + "resolver" + ], + "resp": "response", + "ret": "return", + "rev": "review", + "rl": "rank list", + "rls": "release", + "rm": "remove", + "rmng": "remaining", + "rsn": "reason", + "s": [ + "second", + "seconds", + "stack" + ], + "sav": "save", + "sc": "script", + "scr": "screen", + "sec": "second", + "sect": "section", + "sel": [ + "selector", + "select", + "selected" + ], + "sels": "selectors", + "sep": "separator", + "set": "settings", + "sgl": "single", + "sgn": "signal", + "simpl": "simplify", + "sltr": "selector", + "smp": "sample", + "spl": "special", + "src": "source", + "stab": "stable", + "stat": "statistics", + "stg": "strategy", + "sto": "storage", + "stp": "stripe", + "str": "string", + "succ": [ + "success", + "successful" + ], + "suff": "suffix", + "svc": "service", + "svr": "server", + "sw": "switch", + "swp": "swipe", + "sxn": [ + "section", + "sections" + ], + "sym": "symbol", + "sz": "size", + "t": [ + "top", + "time" + ], + "tar": "target", + "thd": "thread", + "thds": "threads", + "thrd": "threshold", + "tmp": "temporary", + "tpl": "template", + "treas": [ + "treasury", + "treasuries" + ], + "trig": [ + "trigger", + "triggered" + ], + "ts": "timestamp", + "tt": [ + "title", + "timeout" + ], + "tv": "text view", + "txt": "text", + "u": "unit", + "unexp": "unexpected", + "unintrp": "uninterrupted", + "unlk": [ + "unlock", + "unlocked" + ], + "usr": "user", + "util": "utility", + "v": [ + "value", + "view" + ], + "val": "value", + "vert": "vertical", + "vw": "view", + "w": "widget", + "wball": "water ball", + "wballs": "water balls", + "wc": "widget collection", + "win": "window" +} \ No newline at end of file diff --git a/app/src/main/assets/indices/xml-nodes.json b/app/src/main/assets/indices/xml-nodes.json new file mode 100644 index 00000000..91483dc6 --- /dev/null +++ b/app/src/main/assets/indices/xml-nodes.json @@ -0,0 +1,82 @@ +{ + ":about": "classes of Auto.js xml nodes", + ":example_1": "console.log(ui.inflate() instanceof android.widget.CheckBox); // true", + ":example_2": "console.log(ui.inflate() instanceof com.google.android.material.appbar.AppBarLayout); // true", + "appbar": "com.google.android.material.appbar.AppBarLayout", + "button": "com.stardust.autojs.core.ui.widget.JsButton", + "canvas": "com.stardust.autojs.core.graphics.ScriptCanvasView", + "card": "androidx.cardview.widget.CardView", + "checkbox": "android.widget.CheckBox", + "datepicker": "android.widget.DatePicker", + "drawer": "androidx.drawerlayout.widget.DrawerLayout", + "fab": "com.google.android.material.floatingactionbutton.FloatingActionButton", + "frame": "com.stardust.autojs.core.ui.widget.JsFrameLayout", + "grid": "com.stardust.autojs.core.ui.widget.JsGridView", + "img": "com.stardust.autojs.core.ui.widget.JsImageView", + "input": "com.stardust.autojs.core.ui.widget.JsEditText", + "linear": "com.stardust.autojs.core.ui.widget.JsLinearLayout", + "list": "com.stardust.autojs.core.ui.widget.JsListView", + "progressbar": "android.widget.ProgressBar", + "radio": "android.widget.RadioButton", + "radiogroup": "android.widget.RadioGroup", + "relative": "com.stardust.autojs.core.ui.widget.JsRelativeLayout", + "scroll": "android.widget.ScrollView", + "seekbar": "android.widget.SeekBar", + "spinner": "com.stardust.autojs.core.ui.widget.JsSpinner", + "tabs": "com.stardust.autojs.core.ui.widget.JsTabLayout", + "text": "com.stardust.autojs.core.ui.widget.JsTextView", + "timepicker": "android.widget.TimePicker", + "toolbar": "com.stardust.autojs.core.ui.widget.JsToolbar", + "vertical": "com.stardust.autojs.core.ui.widget.JsLinearLayout", + "viewpager": "com.stardust.autojs.core.ui.widget.JsViewPager", + "AbsoluteLayout": "android.widget.AbsoluteLayout", + "ActionMenuView": "android.widget.ActionMenuView", + "AnalogClock": "android.widget.AnalogClock", + "AutoCompleteTextView": "android.widget.AutoCompleteTextView", + "Button": "android.widget.Button", + "CalendarView": "android.widget.CalendarView", + "CheckBox": "android.widget.CheckBox", + "CheckedTextView": "android.widget.CheckedTextView", + "Chronometer": "android.widget.Chronometer", + "DatePicker": "android.widget.DatePicker", + "DialerFilter": "android.widget.DialerFilter", + "DigitalClock": "android.widget.DigitalClock", + "EditText": "android.widget.EditText", + "FrameLayout": "android.widget.FrameLayout", + "GridLayout": "android.widget.GridLayout", + "horizontal": "com.stardust.autojs.core.ui.widget.JsLinearLayout", + "HorizontalScrollView": "android.widget.HorizontalScrollView", + "ImageButton": "android.widget.ImageButton", + "ImageSwitcher": "android.widget.ImageSwitcher", + "ImageView": "android.widget.ImageView", + "LinearLayout": "android.widget.LinearLayout", + "MediaController": "android.widget.MediaController", + "MultiAutoCompleteTextView": "android.widget.MultiAutoCompleteTextView", + "NumberPicker": "android.widget.NumberPicker", + "ProgressBar": "android.widget.ProgressBar", + "QuickContactBadge": "android.widget.QuickContactBadge", + "RadioButton": "android.widget.RadioButton", + "RadioGroup": "android.widget.RadioGroup", + "RelativeLayout": "android.widget.RelativeLayout", + "ScrollView": "android.widget.ScrollView", + "SearchView": "android.widget.SearchView", + "Space": "android.widget.Space", + "Switch": "android.widget.Switch", + "TabHost": "android.widget.TabHost", + "TableLayout": "android.widget.TableLayout", + "TableRow": "android.widget.TableRow", + "TabWidget": "android.widget.TabWidget", + "TextClock": "android.widget.TextClock", + "TextSwitcher": "android.widget.TextSwitcher", + "TextView": "android.widget.TextView", + "TimePicker": "android.widget.TimePicker", + "ToggleButton": "android.widget.ToggleButton", + "Toolbar": "android.widget.Toolbar", + "TwoLineListItem": "android.widget.TwoLineListItem", + "VideoView": "android.widget.VideoView", + "ViewAnimator": "android.widget.ViewAnimator", + "ViewFlipper": "android.widget.ViewFlipper", + "ViewSwitcher": "android.widget.ViewSwitcher", + "ZoomButton": "android.widget.ZoomButton", + "ZoomControls": "android.widget.ZoomControls" +} \ No newline at end of file diff --git a/app/src/main/assets/js/js-beautify/beautify.js b/app/src/main/assets/js/js-beautify/beautify.js index a797a2c9..7252bd6a 100644 --- a/app/src/main/assets/js/js-beautify/beautify.js +++ b/app/src/main/assets/js/js-beautify/beautify.js @@ -324,7 +324,7 @@ function sanitizeOperatorPosition(opPosition) { opPosition = opPosition || OPERATOR_POSITION.before_newline; if (!in_array(opPosition, validPositionValues)) { - throw new Error("Invalid Option Value: The option 'operator_position' must be one of the following values\n" + + throw Error("Invalid Option Value: The option 'operator_position' must be one of the following values\n" + validPositionValues + "\nYou passed in: '" + opPosition + "'"); } @@ -705,7 +705,7 @@ function Beautifier(js_source_text, options) { printable_token = printable_token || current_token.text; print_token_line_indentation(); - if(current_token.type == "TK_XML" && printable_token){ + if(current_token.type === "TK_XML" && printable_token){ var indent_count = output.current_line._indent_count; println("indent_count: " + indent_count); var indent = output.indent_cache[Math.max(0, indent_count - 1)]; diff --git a/app/src/main/assets/sample/AutoJs6/基本信息 [v6.1.0+].js b/app/src/main/assets/sample/AutoJs6/基本信息 [v6.1.0+].js new file mode 100644 index 00000000..a4256f29 --- /dev/null +++ b/app/src/main/assets/sample/AutoJs6/基本信息 [v6.1.0+].js @@ -0,0 +1,18 @@ +let {versionName, versionCode, versionDate} = autojs; +Object.entries({versionName, versionCode, versionDate}).forEach((entry) => { + let [key, value] = entry; + console.log(`${key}: ${value}`); +}); + +console.verbose(); + +console.log(`RootMode: ${autojs.getRootMode()}`); +console.log(`Root: ${autojs.isRootAvailable() ? 'available' : 'not available'}`); + +console.verbose(); + +console.log(`Display over other apps: ${autojs.canDisplayOverOtherApps()}`); +console.log(`Modify system settings: ${autojs.canModifySystemSettings()}`); +console.log(`Write secure settings: ${autojs.canWriteSecureSettings()}`); + +console.launch(); \ No newline at end of file diff --git a/app/src/main/assets/sample/AutoJs6/强制 Root 检查 [v6.1.0+].js b/app/src/main/assets/sample/AutoJs6/强制 Root 检查 [v6.1.0+].js new file mode 100644 index 00000000..4481ff68 --- /dev/null +++ b/app/src/main/assets/sample/AutoJs6/强制 Root 检查 [v6.1.0+].js @@ -0,0 +1,50 @@ +// If you have exotic root or abnormal state for root access, you can force set root to root or non-root. +// zh-CN: 如果设备使用非常规 Root 方式或 Root 权限检测异常, 可设置强制 Root 或 强制非 Root 模式. + +// depends on system +// zh-CN: 取决于系统检测结果 +console.log(`Root access: ${autojs.isRootAvailable()}`); + +// 1 or true or 'root' (force set root mode) +// zh-CN: 1 或 true 或 'root' (强制设置 Root 模式) +autojs.setRootMode(true); +console.log(`setRootMode(true)`) +// true +console.log(`Root access: ${autojs.isRootAvailable()}`); + +// 0 or false or 'non-root' (force set non-root mode) +// zh-CN: 0 或 false 或 'non-root' (强制设置非 Root 模式) +autojs.setRootMode(false); +console.log(`setRootMode(false)`) +// false +console.log(`Root access: ${autojs.isRootAvailable()}`); + +// -1 or 'auto' (auto detect) +// zh-CN: -1 或 'auto' (自动检测 Root 模式) +autojs.setRootMode('auto'); +console.log(`setRootMode(auto)`) +// depends on system again +// zh-CN: 再次取决于系统检测结果 +console.log(`Root access: ${autojs.isRootAvailable()}`); + +console.launch(); + +// autojs.setRootMode() doesn't change preference settings. +// e.g. autojs.isRootAvailable(); // false +// autojs.setRootMode(true); +// autojs.isRootAvailable(); // true +// However, when running a new script, autojs.isRootAvailable() still returns false. +// To apply to preference settings, go to "AutoJs6 > Settings". +// The second parameter of autojs.setRootMode() also works. +// To forcibly set non-root mode: autojs.setRootMode('non-root', true); +// Also available for string param: autojs.setRootMode('non-root', 'write_into_pref'); +// zh-CN: +// autojs.setRootMode() 仅在单个脚本实例运行期间有效 即不改变软件配置参数 +// 例如 autojs.isRootAvailable() 返回 false +// 此时使用 autojs.setRootMode(true) +// autojs.isRootAvailable() 将返回 true +// 如果脚本结束后再次获取 autojs.isRootAvailable() 则依然返回 false +// 如需改变软件配置参数 可在 "AutoJs6 > 设置" 中更改 +// 也可通过 autojs.setRootMode() 的第二项参数直接将修改应用到软件配置参数 +// 如强制非 Root 模式: autojs.setRootMode('non-root', true); +// 也可使用字符串参数: autojs.setRootMode('non-root', 'write_into_pref'); \ No newline at end of file diff --git a/app/src/main/assets/sample/HTTP网络请求/文件下载.js b/app/src/main/assets/sample/HTTP网络请求/文件下载.js index e41bd1ef..6a4b0cb3 100644 --- a/app/src/main/assets/sample/HTTP网络请求/文件下载.js +++ b/app/src/main/assets/sample/HTTP网络请求/文件下载.js @@ -1,6 +1,6 @@ var url = "http://www.autojs.org/assets/uploads/profile/3-profileavatar.png"; var res = http.get(url); -if(res.statusCode != 200){ +if(res.statusCode !== 200){ toast("请求失败"); } files.writeBytes("/sdcard/1.png", res.body.bytes()); diff --git a/app/src/main/assets/sample/HTTP网络请求/获取网页.js b/app/src/main/assets/sample/HTTP网络请求/获取网页.js index f62a4d5c..a85c3ce3 100644 --- a/app/src/main/assets/sample/HTTP网络请求/获取网页.js +++ b/app/src/main/assets/sample/HTTP网络请求/获取网页.js @@ -1,6 +1,6 @@ var url = "www.baidu.com"; var res = http.get(url); -if(res.statusCode == 200){ +if(res.statusCode === 200){ toast("请求成功"); console.show(); log(res.body.string()); diff --git a/app/src/main/assets/sample/事件与按键、触摸监听/Toast监听.js b/app/src/main/assets/sample/事件与监听/Toast监听.js similarity index 100% rename from app/src/main/assets/sample/事件与按键、触摸监听/Toast监听.js rename to app/src/main/assets/sample/事件与监听/Toast监听.js diff --git a/app/src/main/assets/sample/事件与按键、触摸监听/按键监听.js b/app/src/main/assets/sample/事件与监听/按键监听.js similarity index 86% rename from app/src/main/assets/sample/事件与按键、触摸监听/按键监听.js rename to app/src/main/assets/sample/事件与监听/按键监听.js index f49e92e4..1dc2bcd5 100644 --- a/app/src/main/assets/sample/事件与按键、触摸监听/按键监听.js +++ b/app/src/main/assets/sample/事件与监听/按键监听.js @@ -13,9 +13,9 @@ var keyNames = { events.on("key", function(code, event){ var keyName = getKeyName(code, event); - if(event.getAction() == event.ACTION_DOWN){ + if(event.getAction() === event.ACTION_DOWN){ toast(keyName + "被按下"); - }else if(event.getAction() == event.ACTION_UP){ + }else if(event.getAction() === event.ACTION_UP){ toast(keyName + "弹起"); } }); diff --git a/app/src/main/assets/sample/事件与按键、触摸监听/触摸监听.js b/app/src/main/assets/sample/事件与监听/触摸监听.js similarity index 100% rename from app/src/main/assets/sample/事件与按键、触摸监听/触摸监听.js rename to app/src/main/assets/sample/事件与监听/触摸监听.js diff --git a/app/src/main/assets/sample/事件与按键、触摸监听/通知监听.js b/app/src/main/assets/sample/事件与监听/通知监听.js similarity index 100% rename from app/src/main/assets/sample/事件与按键、触摸监听/通知监听.js rename to app/src/main/assets/sample/事件与监听/通知监听.js diff --git a/app/src/main/assets/sample/事件与按键、触摸监听/长按返回退出当前程序.js b/app/src/main/assets/sample/事件与监听/长按返回退出当前程序.js similarity index 90% rename from app/src/main/assets/sample/事件与按键、触摸监听/长按返回退出当前程序.js rename to app/src/main/assets/sample/事件与监听/长按返回退出当前程序.js index a0b88751..05691620 100644 --- a/app/src/main/assets/sample/事件与按键、触摸监听/长按返回退出当前程序.js +++ b/app/src/main/assets/sample/事件与监听/长按返回退出当前程序.js @@ -21,7 +21,7 @@ events.onKeyUp("back", function(event){ loop(); function backBackBackBack(){ - while(curPackage == currentPackage()){ + while(curPackage === currentPackage()){ back(); sleep(200); } diff --git a/app/src/main/assets/sample/事件与按键、触摸监听/音量键控制程序.js b/app/src/main/assets/sample/事件与监听/音量键控制程序.js similarity index 96% rename from app/src/main/assets/sample/事件与按键、触摸监听/音量键控制程序.js rename to app/src/main/assets/sample/事件与监听/音量键控制程序.js index f5782d60..1fb8a059 100644 --- a/app/src/main/assets/sample/事件与按键、触摸监听/音量键控制程序.js +++ b/app/src/main/assets/sample/事件与监听/音量键控制程序.js @@ -6,7 +6,7 @@ var interval = 5000; var task = task1; events.onKeyDown("volume_up", function(event){ - if(task == task1){ + if(task === task1){ task = task2; }else{ task = task1; diff --git a/app/src/main/assets/sample/任务/一次性任务 [v6.1.0+].js b/app/src/main/assets/sample/任务/一次性任务 [v6.1.0+].js new file mode 100644 index 00000000..b7329c95 --- /dev/null +++ b/app/src/main/assets/sample/任务/一次性任务 [v6.1.0+].js @@ -0,0 +1,13 @@ +tasks.addDisposableTask({ + date: Date.now() + 3.6e6 * 12, + path: files.path('./test.js'), + callback(task) { + console.log(`已添加的一次性任务: ${task}`); + console.log(`ID: ${task.id}`); + console.log(`运行时间: ${new Date(task.nextTime).toLocaleString()}`); + console.log(`脚本路径: ${task.scriptPath}`); + console.info('可在 AutoJs6 任务面板查看或管理任务'); + }, +}); + +console.launch(); \ No newline at end of file diff --git a/app/src/main/assets/sample/任务/意图 (Intent) 任务 [v6.1.0+].js b/app/src/main/assets/sample/任务/意图 (Intent) 任务 [v6.1.0+].js new file mode 100644 index 00000000..bc5d5655 --- /dev/null +++ b/app/src/main/assets/sample/任务/意图 (Intent) 任务 [v6.1.0+].js @@ -0,0 +1,13 @@ +tasks.addIntentTask({ + action: 'android.intent.action.SCREEN_OFF', + path: files.path('./test.js'), + callback(task) { + console.log(`已添加的意图任务: ${task}`); + console.log(`ID: ${task.id}`); + console.log(`意图动作: ${task.action}`); + console.log(`脚本路径: ${task.scriptPath}`); + console.info('可在 AutoJs6 任务面板查看或管理任务'); + } +}); + +console.launch(); \ No newline at end of file diff --git a/app/src/main/assets/sample/任务/每周任务 [v6.1.0+].js b/app/src/main/assets/sample/任务/每周任务 [v6.1.0+].js new file mode 100644 index 00000000..7ff93378 --- /dev/null +++ b/app/src/main/assets/sample/任务/每周任务 [v6.1.0+].js @@ -0,0 +1,15 @@ +tasks.addWeeklyTask({ + time: Date.now() + 3.6e6 * 12, + path: files.path('./test.js'), + daysOfWeek: ['六', 3, 'Fri', 'Sunday'], + callback(task) { + console.log(`已添加的每周任务: ${task}`); + console.log(`ID: ${task.id}`); + console.log(`运行时间: ${new Date(task.nextTime).toLocaleString()}`); + console.log(`脚本路径: ${task.scriptPath}`); + console.log(`周内日期: [ ${tasks.timeFlagToDays(task.timeFlag).join(', ')} ]`); + console.info('可在 AutoJs6 任务面板查看或管理任务'); + }, +}); + +console.launch(); \ No newline at end of file diff --git a/app/src/main/assets/sample/任务/每日任务 [v6.1.0+].js b/app/src/main/assets/sample/任务/每日任务 [v6.1.0+].js new file mode 100644 index 00000000..83c09e24 --- /dev/null +++ b/app/src/main/assets/sample/任务/每日任务 [v6.1.0+].js @@ -0,0 +1,13 @@ +tasks.addDailyTask({ + time: Date.now() + 3.6e6 * 12, + path: files.path('./test.js'), + callback(task) { + console.log(`已添加的每日任务: ${task}`); + console.log(`ID: ${task.id}`); + console.log(`运行时间: ${new Date(task.nextTime).toLocaleString()}`); + console.log(`脚本路径: ${task.scriptPath}`); + console.info('可在 AutoJs6 任务面板查看或管理任务'); + }, +}); + +console.launch(); \ No newline at end of file diff --git a/app/src/main/assets/sample/图片与图色处理/区域找色1.js b/app/src/main/assets/sample/图像与颜色/区域找色1.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/区域找色1.js rename to app/src/main/assets/sample/图像与颜色/区域找色1.js diff --git a/app/src/main/assets/sample/图片与图色处理/区域找色2.js b/app/src/main/assets/sample/图像与颜色/区域找色2.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/区域找色2.js rename to app/src/main/assets/sample/图像与颜色/区域找色2.js diff --git a/app/src/main/assets/sample/图片与图色处理/图片处理.js b/app/src/main/assets/sample/图像与颜色/图片处理.js similarity index 96% rename from app/src/main/assets/sample/图片与图色处理/图片处理.js rename to app/src/main/assets/sample/图像与颜色/图片处理.js index 654c56ad..83ea3fac 100644 --- a/app/src/main/assets/sample/图片与图色处理/图片处理.js +++ b/app/src/main/assets/sample/图像与颜色/图片处理.js @@ -5,10 +5,10 @@ var logo = null; var currentImg = null; events.on("exit", function(){ - if(logo != null){ + if(logo){ logo.recycle(); } - if(currentImg != null){ + if(currentImg){ currentImg.recycle(); } }); @@ -39,7 +39,7 @@ function setImage(img) { var oldImg = currentImg; //不能立即回收currentImg,因为此时img控件还在使用它,应该在下次消息循环再回收它 ui.post(()=>{ - if(oldImg != null){ + if(oldImg){ oldImg.recycle(); } }); @@ -55,7 +55,7 @@ var imgProcess = threads.start(function () { //处理图片的函数,把任务交给图片处理线程处理 function processImg(process) { imgProcess.setTimeout(() => { - if (logo == null) { + if (!logo) { logo = images.load(url); } //处理图片 @@ -77,7 +77,7 @@ ui.rotate.on("click", () => { ui.concat.on("click", () => { processImg(img => { - if(currentImg == null){ + if(!currentImg){ toast("请先点击其他按钮,再点击本按钮"); return img.clone(); } diff --git a/app/src/main/assets/sample/图像与颜色/基本颜色转换 [v6.1.0+].js b/app/src/main/assets/sample/图像与颜色/基本颜色转换 [v6.1.0+].js new file mode 100644 index 00000000..6ac02b19 --- /dev/null +++ b/app/src/main/assets/sample/图像与颜色/基本颜色转换 [v6.1.0+].js @@ -0,0 +1,25 @@ +let color = '#BF00363A'; +let colorInt = colors.toInt(color); + +let cR = colors.red(colorInt); +let cG = colors.green(color); +let cB = colors.blue(colorInt); +let cA = colors.alpha(color); + +console.log(`Color string: ${color}`); +console.log(`Color int: ${colorInt}`); +console.log(`Color rgba: [ ${[`R: ${cR}`, `G: ${cG}`, `B: ${cB}`, `A: ${cA}`].join(', ')} ]`); + +let test = o => console.log(`Test instance ${o ? `passed` : `failed`}`); + +test(colors.red(color) === colors.red(colorInt)); +test(colors.toInt(color) === colors.toInt(colorInt)); + +test(colors.argb('#FF224466') === colors.rgba('#224466FF')); +test(colors.argb(color) === colors.rgba(cR, cG, cB, cA)); + +test(colors.toString(color) === colors.toString(colorInt)); +test(colors.toString('#224466') === colors.toString('#FF224466', 6 /* none */)); +test(colors.toString('#FF224466') === colors.toString('#224466', 8 /* keep */)); + +console.launch(); \ No newline at end of file diff --git a/app/src/main/assets/sample/图片与图色处理/实时显示触摸点颜色.js b/app/src/main/assets/sample/图像与颜色/实时显示触摸点颜色.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/实时显示触摸点颜色.js rename to app/src/main/assets/sample/图像与颜色/实时显示触摸点颜色.js diff --git a/app/src/main/assets/sample/图片与图色处理/截图并保存.js b/app/src/main/assets/sample/图像与颜色/截图并保存.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/截图并保存.js rename to app/src/main/assets/sample/图像与颜色/截图并保存.js diff --git a/app/src/main/assets/sample/图片与图色处理/找到QQ红点位置.js b/app/src/main/assets/sample/图像与颜色/找到QQ红点位置.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/找到QQ红点位置.js rename to app/src/main/assets/sample/图像与颜色/找到QQ红点位置.js diff --git a/app/src/main/assets/sample/图片与图色处理/找图/block.png b/app/src/main/assets/sample/图像与颜色/找图/block.png similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/找图/block.png rename to app/src/main/assets/sample/图像与颜色/找图/block.png diff --git a/app/src/main/assets/sample/图片与图色处理/找图/mario.png b/app/src/main/assets/sample/图像与颜色/找图/mario.png similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/找图/mario.png rename to app/src/main/assets/sample/图像与颜色/找图/mario.png diff --git a/app/src/main/assets/sample/图片与图色处理/找图/super_mario.jpg b/app/src/main/assets/sample/图像与颜色/找图/super_mario.jpg similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/找图/super_mario.jpg rename to app/src/main/assets/sample/图像与颜色/找图/super_mario.jpg diff --git a/app/src/main/assets/sample/图片与图色处理/找图/找出所有问号方块.js b/app/src/main/assets/sample/图像与颜色/找图/找出所有问号方块.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/找图/找出所有问号方块.js rename to app/src/main/assets/sample/图像与颜色/找图/找出所有问号方块.js diff --git a/app/src/main/assets/sample/图片与图色处理/找图/找出问号方块并画出位置.js b/app/src/main/assets/sample/图像与颜色/找图/找出问号方块并画出位置.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/找图/找出问号方块并画出位置.js rename to app/src/main/assets/sample/图像与颜色/找图/找出问号方块并画出位置.js diff --git a/app/src/main/assets/sample/图片与图色处理/找图/找出马里奥.js b/app/src/main/assets/sample/图像与颜色/找图/找出马里奥.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/找图/找出马里奥.js rename to app/src/main/assets/sample/图像与颜色/找图/找出马里奥.js diff --git a/app/src/main/assets/sample/图片与图色处理/模糊找色.js b/app/src/main/assets/sample/图像与颜色/模糊找色.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/模糊找色.js rename to app/src/main/assets/sample/图像与颜色/模糊找色.js diff --git a/app/src/main/assets/sample/图片与图色处理/精确找色.js b/app/src/main/assets/sample/图像与颜色/精确找色.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/精确找色.js rename to app/src/main/assets/sample/图像与颜色/精确找色.js diff --git a/app/src/main/assets/sample/图片与图色处理/获取网络图片并保存.js b/app/src/main/assets/sample/图像与颜色/获取网络图片并保存.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/获取网络图片并保存.js rename to app/src/main/assets/sample/图像与颜色/获取网络图片并保存.js diff --git a/app/src/main/assets/sample/图片与图色处理/颜色获取和检测.js b/app/src/main/assets/sample/图像与颜色/颜色获取和检测.js similarity index 100% rename from app/src/main/assets/sample/图片与图色处理/颜色获取和检测.js rename to app/src/main/assets/sample/图像与颜色/颜色获取和检测.js diff --git a/app/src/main/assets/sample/复杂界面/WannaCry(仅为娱乐).js b/app/src/main/assets/sample/复杂界面/WannaCry (仅为娱乐).js similarity index 97% rename from app/src/main/assets/sample/复杂界面/WannaCry(仅为娱乐).js rename to app/src/main/assets/sample/复杂界面/WannaCry (仅为娱乐).js index 47052005..335c9a63 100644 --- a/app/src/main/assets/sample/复杂界面/WannaCry(仅为娱乐).js +++ b/app/src/main/assets/sample/复杂界面/WannaCry (仅为娱乐).js @@ -19,7 +19,7 @@ ui.layout( ); -ui.text.text("我的手机出了什么问题?\n您的一些重要文件被我加密保存了。\n" + +ui.text.text("我的手机出了什么问题?\n您的一些重要文件被我加密保存了。\n" + "照片、图片、文档、压缩包、音频、视频文件、apk文件等,几乎所有类型的文件都被加密了,因此不能正常打开。\n" + "这和一般文件损坏有本质上的区别。您大可在网上找找恢复文件的方法,我敢保证,没有我们的解密服务,就算老天爷来了也不能恢复这些文档。\n\n" + "有没有恢复这些文档的方法?\n当然有可恢复的方法。只能通过我们的解密服务才能恢复。我以人格担保,能够提供安全有效的恢复服务。\n" + @@ -30,7 +30,7 @@ ui.text.text("我的手机出了什么问题?\n您的一些重要文件被我 ui.oops.click(() => toast("Fuck you!")); ui.oops.longClick(() => { var thisjoke="This is a joke : )"; - if(ui.oops.text() != thisjoke){ + if(ui.oops.text() !== thisjoke){ ui.oops.text(thisjoke); }else{ ui.oops.text("Oops, your files have been encrypted!"); diff --git a/app/src/main/assets/sample/多线程/多线程按键监听.js b/app/src/main/assets/sample/多线程/多线程按键监听.js index 88f07921..a1dfbf07 100644 --- a/app/src/main/assets/sample/多线程/多线程按键监听.js +++ b/app/src/main/assets/sample/多线程/多线程按键监听.js @@ -5,7 +5,7 @@ threads.start(function(){ events.observeKey(); events.on("key_down", function(keyCode, events){ //音量键关闭脚本 - if(keyCode == keys.volume_up){ + if(keyCode === keys.volume_up){ exit(); } }); diff --git a/app/src/main/assets/sample/定时器/循环执行.js b/app/src/main/assets/sample/定时器/循环执行.js index 8747c0f8..4217f5e4 100644 --- a/app/src/main/assets/sample/定时器/循环执行.js +++ b/app/src/main/assets/sample/定时器/循环执行.js @@ -3,7 +3,7 @@ var i = 0; setInterval(function(){ i++; toast(i * 4 + "秒"); - if(i == 5){ + if(i === 5){ exit(); } }, 4000); diff --git a/app/src/main/assets/sample/定时器/条件周期执行 [v6.1.0+].js b/app/src/main/assets/sample/定时器/条件周期执行 [v6.1.0+].js new file mode 100644 index 00000000..a5b6dbd1 --- /dev/null +++ b/app/src/main/assets/sample/定时器/条件周期执行 [v6.1.0+].js @@ -0,0 +1,48 @@ +let config = { + greeting: 'Good luck comes later...', + interval: 100, + listener() { + console.log(config.greeting); + }, + condition() { + let num = Math.random() * 100 + 1; + return num >= 97 && Math.floor(num); + }, + callback(res) { + toastLog(`Your lucky number is ${res}`, 's', 'f'); + }, +}; + +toast(config.greeting, 'l', 'f'); + + +// @Example timers.setIntervalExt() + +timers.setIntervalExt(config.listener, config.interval, config.condition, config.callback); + + +// @Example setInterval() +// @Hint Method setInterval() may be not reliable for time intensive operations. +// @See https://dev.to/akanksha_9560/why-not-to-use-setinterval--2na9 + +// let intervalId = setInterval(() => { +// let result; +// config.listener(); +// if ((result = config.condition())) { +// clearInterval(intervalId); +// config.callback(result); +// } +// }, config.interval); + + +// @Example do/while loop and sleep() +// @Hint Method sleep() is not available in ui thread and will block current thread. + +// let result; +// +// do { +// sleep(config.interval); +// config.listener(); +// } while (!(result = config.condition())); +// +// config.callback(result); \ No newline at end of file diff --git a/app/src/main/assets/sample/对话框/个性化对话框 [v6.1.0+].js b/app/src/main/assets/sample/对话框/个性化对话框 [v6.1.0+].js new file mode 100644 index 00000000..abe4a677 --- /dev/null +++ b/app/src/main/assets/sample/对话框/个性化对话框 [v6.1.0+].js @@ -0,0 +1,66 @@ +const ColorDrawable = android.graphics.drawable.ColorDrawable; +const Snackbar = com.google.android.material.snackbar.Snackbar; + +let dialog = dialogs.build({ + title: 'Time', + content: null, + positive: 'EXIT', + neutral: 'CHANGE_BG', + stubborn: true, + linkify: 'webUrls', + onBackKey: (d) => Snackbar + .make(d.getView(), 'Please choose a button', 0) + .setDuration(1.2e3) + .show(), + animation: true, + dimAmount: 90, + background: '#D7FFD9', + keepScreenOn: true, + buttonRippleColor: colors.rgba('#00bbff20'), + contentLineSpacing: 1.9, +}).on('neutral', (d) => { + let bg = materialColor.pick(); + let win = d.getWindow(); + ui.post(() => win.setBackgroundDrawable(new ColorDrawable(colors.toInt(bg)))); +}).on('positive', (d) => { + exitNow(d); +}).show(); + +let urlStr = 'Visit https://time.is/beijing for more info'; +let cachedTimeStr; +let materialColor = { + _index: 0, + _list: [ + '#E2F1F8', '#FFFFFF', '#EFDCD5', '#FFDDC1', '#FFFFB0', + '#FFFFB3', '#FFFFCF', '#FFFFCE', '#F8FFD7', '#D7FFD9', + '#B2FEF7', '#B4FFFF', '#B6FFFF', '#C3FDFF', '#D1D9FF', + '#E6CEFF', '#FFC4FF', '#FFC1E3', '#FFCCCB', '#C1D5E0', + ], + pick() { + let color = this._list[this._index++]; + if (this._index === this._list.length) { + this._index = 0; + } + return color; + }, +}; +let exitNow = (d) => { + d.dismiss(); + exit(); +}; + +let getTimeStr = () => { + let now = new Date(); + let hh = now.getHours().toString().padStart(2, '0'); + let mm = now.getMinutes().toString().padStart(2, '0'); + let ss = now.getSeconds().toString().padStart(2, '0'); + return `${hh}:${mm}:${ss}`; +}; + +setInterval(() => { + let timeStr = getTimeStr(); + if (cachedTimeStr !== timeStr) { + cachedTimeStr = timeStr; + dialog.setContent(`${timeStr}\n${urlStr}`); + } +}, 30); \ No newline at end of file diff --git a/app/src/main/assets/sample/对话框/多选框.js b/app/src/main/assets/sample/对话框/多选框.js index 88d958c5..f0edab4e 100644 --- a/app/src/main/assets/sample/对话框/多选框.js +++ b/app/src/main/assets/sample/对话框/多选框.js @@ -1,6 +1,6 @@ var i = dialogs.multiChoice("下列作品出自李贽的是", ["《焚书》", "《西湖寻梦》", "《高太史全集》", "《续焚烧书》", "《藏书》"]); toast("选择了: " + i); -if(i.length == 2 && i.toString() == [0, 4].toString()){ +if(i.length === 2 && i.toString() === [0, 4].toString()){ toast("答对辣"); }else{ toast("答错辣"); diff --git a/app/src/main/assets/sample/对话框/模拟更新下载对话框.js b/app/src/main/assets/sample/对话框/模拟更新下载对话框.js index ec0c78b2..9154d364 100644 --- a/app/src/main/assets/sample/对话框/模拟更新下载对话框.js +++ b/app/src/main/assets/sample/对话框/模拟更新下载对话框.js @@ -29,7 +29,7 @@ function download(){ autoDismiss: false }) .on("positive", ()=>{ - if(downloadDialog.getActionButton("positive") == "暂停"){ + if(downloadDialog.getActionButton("positive") === "暂停"){ stopDownload(); downloadDialog.setActionButton("positive", "继续"); }else{ diff --git a/app/src/main/assets/sample/对话框/菜单.js b/app/src/main/assets/sample/对话框/菜单.js index 58229795..db7bf4cf 100644 --- a/app/src/main/assets/sample/对话框/菜单.js +++ b/app/src/main/assets/sample/对话框/菜单.js @@ -1,10 +1,10 @@ while(true){ var i = dialogs.select("哲学的基本问题是", "社会和自然的关系问题", "思维与存在的关系问题", "政治和经济的关系问题", "实践和理论的关系问题"); - if(i == -1){ + if(i === -1){ toast("猜一下呗"); continue; } - if(i == 1){ + if(i === 1){ toast("答对辣"); break; }else{ diff --git a/app/src/main/assets/sample/工具/安卓版本信息查询 [v6.1.0+].js b/app/src/main/assets/sample/工具/安卓版本信息查询 [v6.1.0+].js new file mode 100644 index 00000000..d8ddbc78 --- /dev/null +++ b/app/src/main/assets/sample/工具/安卓版本信息查询 [v6.1.0+].js @@ -0,0 +1,112 @@ +// noinspection BadExpressionStatementJS,JSXNamespaceValidation + +'ui'; + +/* Here, importClass() is not recommended for intelligent code completion in IDE like WebStorm. */ +/* The same is true of destructuring assignment syntax (like `let {Uri} = android.net`). */ + +const InputType = android.text.InputType; +const TextWatcher = android.text.TextWatcher; + +let _ = { + colors: { + inputText: colors.rgba('#000000DE'), + sampleText: colors.rgba('#00000091'), + splitLine: colors.rgba('#00000055'), + }, + textSize: 16, + inputHint: '输入要检索的内容', + sampleTitle: '检索示例', + samples: ['30', 'R', 'Android 11', 'oreo', 'pie', 'cookie', 'nougat', 'jelly bean', + '7.1.1', '7.1', '8.0', '8', '2022', '2022 Mar', '2022 March', '2022 3', '2022/3', + '2022/03', 'Mar 2022', 'March 2022', 'Mar, 2022', 'March, 2022', '2022 Mar 07', + '2022 Mar 7', '2022 March 7', '2022 3 7', '2022/3/7', '2022/3/07', '2022/03/07', + 'Mar 7 2022', 'March 7 2022', 'Mar 7, 2022', 'March 7, 2022'], + infoKeys: ['versionCode', 'apiLevel', 'platformVersion', 'releaseName', 'internalCodename', 'releaseDate'], +}; + +let $ = { + show() { + this.initUiLayout(); + this.addSampleText(); + this.addTextChangedListener(); + }, + initUiLayout() { + ui.layout( + + + + + + + ); + + ui['input'].setHint(_.inputHint); + ui['input'].setTextColor(_.colors.inputText); + ui['input'].setTextSize(_.textSize); + // to disable multi-line feature + ui['input'].setInputType(InputType.TYPE_CLASS_TEXT); + }, + addSampleText() { + let view = ui.inflate( + + ); + + view.text.setText(`${_.sampleTitle}:\n\n${_.samples.join('\n')}`); + view.text.setTextColor(_.colors.sampleText); + + ui['info'].addView(view); + }, + addTextChangedListener() { + ui['input'].addTextChangedListener(new TextWatcher({ + beforeTextChanged: () => void 0, + onTextChanged: () => void 0, + afterTextChanged: this.afterTextChanged.bind(this), + })); + }, + afterTextChanged(inputText) { + ui['info'].removeAllViews(); + + if (inputText.length() > 0) { + this.parseInputAndSetView(inputText); + } else { + this.addSampleText(); + } + }, + parseInputAndSetView(inputText) { + let result = util.versionCodes.search(inputText.toString()); + let infos = Array.isArray(result) ? result : result ? [result] : []; + infos.forEach((info) => { + this.setInfoView(info); + this.setSplitLineView(); + }); + }, + setInfoView(info) { + _.infoKeys.forEach((key) => { + let infoView = ui.inflate( + + ); + + // e.g. versionCode -> Version Code + // e.g. platformVersion -> Platform Version + let prop = key.replace(/^([a-z]+)(([A-Z][a-z]+)*)$/, ($, $1, $2) => /* @AXR */ ( + $1[0].toUpperCase() + $1.slice(1) + $2.replace(/[A-Z](?=[a-z])/g, ' $&') + )); + infoView['text'].setText(`${prop}: ${info[key]}`); + infoView['text'].setTextSize(_.textSize); + + ui['info'].addView(infoView); + }); + }, + setSplitLineView() { + let splitLineView = ui.inflate( + + ); + + splitLineView['line'].setBackgroundColor(_.colors.splitLine); + + ui['info'].addView(splitLineView); + }, +}; + +$.show(); \ No newline at end of file diff --git a/app/src/main/assets/sample/工具/摩斯电码 [v6.1.0+].js b/app/src/main/assets/sample/工具/摩斯电码 [v6.1.0+].js new file mode 100644 index 00000000..1d0cceb9 --- /dev/null +++ b/app/src/main/assets/sample/工具/摩斯电码 [v6.1.0+].js @@ -0,0 +1,24 @@ +let string = 'HIM'; +let morse = util.morseCode(string); + +// The input string is not case-sensitive. +// zh-CN: 输入字符串不区分大小写. + +console.log('string: ' + string); + +// The morse code is '···· ·· --'. +// zh-CN: 摩斯密码为 '···· ·· --'. + +console.log('code: ' + morse.code); + +// The pattern could be used for device.vibrate(). +// zh-CN: 模式参数可用于 device.vibrate(). + +console.log('pattern: ' + morse.pattern); + +// Call vibrate() if you need your device play this morse code by vibration. +// zh-CN: Call vibrate() if you need your device play this morse code by vibration. + +// morse.vibrate(); + +console.launch(); \ No newline at end of file diff --git a/app/src/main/assets/sample/工具/获取类与类名 [v6.1.0+].js b/app/src/main/assets/sample/工具/获取类与类名 [v6.1.0+].js new file mode 100644 index 00000000..58ee6ad8 --- /dev/null +++ b/app/src/main/assets/sample/工具/获取类与类名 [v6.1.0+].js @@ -0,0 +1,23 @@ +// noinspection JSIncompatibleTypesComparison + +let Clazz = android.os.BatteryManager; + +console.log(util.getClass(Clazz)); +console.log(util.getClassName(Clazz)); + +let test = o => console.log(`Test instance ${o ? `passed` : `failed`}`); + +test(util.getClass(Clazz) === Clazz); +test(util.getClassName(Clazz) === 'android.os.BatteryManager'); + +// @Caution by SuperMonster003 on May 25, 2022. +// ! This test won't pass. +// ! Use util.getClass(C) instanceof P instead. +test(Clazz instanceof java.lang.Class); +test(util.getClass(Clazz) instanceof java.lang.Class); + +test(new java.lang.Integer(0.5).getClass() === java.lang.Integer); +test(util.getClass(new java.lang.Integer(0.5)) === java.lang.Integer); +test(util.getClass(new java.lang.Integer(0.5)) === util.getClass(java.lang.Integer)); + +console.launch(); \ No newline at end of file diff --git a/app/src/main/assets/sample/应用/app.intentToShell.js b/app/src/main/assets/sample/应用/app.intentToShell.js new file mode 100644 index 00000000..7d927918 --- /dev/null +++ b/app/src/main/assets/sample/应用/app.intentToShell.js @@ -0,0 +1,23 @@ +console.show(); + +// -n 'org.autojs.autojs6/Test' +// --ei 'a' 1 +// --eia 'b' 2,2 +// --es 'c' 'hello' +// --ez 'd' false +// --esa 'e' 'r','s','t' +// -c cat003 +// -a 'android.intent.action.VIEW' +// -f 335544320 +// -t application/pics-rules +// -d protocol://xxx +console.log(app.intentToShell({ + action: 'VIEW', + className: 'Test', + packageName: context.packageName, + extras: {a: 1, b: [2, 2], c: 'hello', d: false, e: ['r', 's', 't']}, + flags: ['ACTIVITY_NEW_TASK', 'ACTIVITY_CLEAR_TOP'], + type: 'application/pics-rules', + data: 'protocol://xxx', + category: 'cat003', +}).split(/ (?=-)/).join('\n')); \ No newline at end of file diff --git a/app/src/main/assets/sample/应用/应用工具.js b/app/src/main/assets/sample/应用/应用工具.js index 85284052..01ddef2b 100644 --- a/app/src/main/assets/sample/应用/应用工具.js +++ b/app/src/main/assets/sample/应用/应用工具.js @@ -1,6 +1,6 @@ var i = dialogs.select("请选择工具", "获取应用包名", "打开应用详情页", "卸载应用"); -if(i == -1){ +if(i === -1){ alert("没有选择任何工具!"); } @@ -22,7 +22,7 @@ case 2: //卸载应用 appName = rawInput("请输入应用名称"); packageName = getPackageName(appName); - if(packageName == ""){ + if(packageName === ""){ toast("应用不存在"); }else if(confirm("确定卸载应用" + packageName + "吗?")){ app.uninstall(packageName); diff --git a/app/src/main/assets/sample/悬浮窗/悬浮窗输入框.js b/app/src/main/assets/sample/悬浮窗/悬浮窗输入框.js index 65ca39d4..eb7ea2bc 100644 --- a/app/src/main/assets/sample/悬浮窗/悬浮窗输入框.js +++ b/app/src/main/assets/sample/悬浮窗/悬浮窗输入框.js @@ -10,7 +10,7 @@ window.exitOnClose(); toast("长按确定键可调整位置"); window.input.on("key", function(keyCode, event){ - if(event.getAction() == event.ACTION_DOWN && keyCode == keys.back){ + if(event.getAction() === event.ACTION_DOWN && keyCode === keys.back){ window.disableFocus(); event.consumed = true; } diff --git a/app/src/main/assets/sample/悬浮窗/悬浮窗运行脚本按钮简单版.js b/app/src/main/assets/sample/悬浮窗/悬浮窗运行脚本按钮简单版.js index 205137d4..f8e4462a 100644 --- a/app/src/main/assets/sample/悬浮窗/悬浮窗运行脚本按钮简单版.js +++ b/app/src/main/assets/sample/悬浮窗/悬浮窗运行脚本按钮简单版.js @@ -14,7 +14,7 @@ window.exitOnClose(); var execution = null; window.action.click(()=>{ - if(window.action.getText() == '开始运行'){ + if(window.action.getText() === '开始运行'){ execution = engines.execScriptFile(path); window.action.setText('停止运行'); }else{ diff --git a/app/src/main/assets/sample/悬浮窗/悬浮运行脚本按钮.js b/app/src/main/assets/sample/悬浮窗/悬浮运行脚本按钮.js index 69387145..23add16f 100644 --- a/app/src/main/assets/sample/悬浮窗/悬浮运行脚本按钮.js +++ b/app/src/main/assets/sample/悬浮窗/悬浮运行脚本按钮.js @@ -49,7 +49,7 @@ window.action.setOnTouchListener(function(view, event){ }); function onClick(){ - if(window.action.getText() == '开始运行'){ + if(window.action.getText() === '开始运行'){ execution = engines.execScriptFile(path); window.action.setText('停止运行'); }else{ diff --git a/app/src/main/assets/sample/控制台/打印调用栈 [v6.1.0+].js b/app/src/main/assets/sample/控制台/打印调用栈 [v6.1.0+].js new file mode 100644 index 00000000..b00a5883 --- /dev/null +++ b/app/src/main/assets/sample/控制台/打印调用栈 [v6.1.0+].js @@ -0,0 +1,23 @@ +function print() { + console.trace('This is a "normal" message for test'); + console.trace('This is an "info" message for test', 'info'); + console.trace('This is a "warn" message for test', 'warn'); + console.trace('This is an "error" message for test', 'error'); + console.launch(); +} + +({ + init() { + this.intermediate(); + }, + intermediate() { + print(); + }, +}).init(); + +// @OutputSnippet: +// 20:46:00.709/E: This is an "error" message for test +// at consoleTrace.js:5 (print) +// at consoleTrace.js:14 +// at consoleTrace.js:11 +// at consoleTrace.js:9 \ No newline at end of file diff --git a/app/src/main/assets/sample/控制台/终端模拟器.js b/app/src/main/assets/sample/控制台/终端模拟器.js index 2adebcd8..d8ada623 100644 --- a/app/src/main/assets/sample/控制台/终端模拟器.js +++ b/app/src/main/assets/sample/控制台/终端模拟器.js @@ -8,5 +8,5 @@ console.show(); do { var cmd = console.rawInput(); sh.exec(cmd); -}while(cmd != "exit"); +}while(cmd !== "exit"); sh.exit(); \ No newline at end of file diff --git a/app/src/main/assets/sample/文件读写/删除所有空文件夹.js b/app/src/main/assets/sample/文件读写/删除所有空文件夹.js index 8bb9eef7..8b92da13 100644 --- a/app/src/main/assets/sample/文件读写/删除所有空文件夹.js +++ b/app/src/main/assets/sample/文件读写/删除所有空文件夹.js @@ -7,7 +7,7 @@ if(confirm("该操作会删除SD卡目录及其子目录下所有空文件夹, function deleteAllEmptyDirs(dir){ var list = files.listDir(dir); var len = list.length; - if(len == 0){ + if(len === 0){ log("删除目录 " + dir + " " + (files.remove(dir) ? "成功" : "失败")); return; } diff --git a/app/src/main/assets/sample/文件读写/文件编码转换(高级).js b/app/src/main/assets/sample/文件读写/文件编码转换 (高级).js similarity index 100% rename from app/src/main/assets/sample/文件读写/文件编码转换(高级).js rename to app/src/main/assets/sample/文件读写/文件编码转换 (高级).js diff --git a/app/src/main/assets/sample/文件读写/读写文本文件.js b/app/src/main/assets/sample/文件读写/读写文本文件.js index 5e9f65d5..b9b0df30 100644 --- a/app/src/main/assets/sample/文件读写/读写文本文件.js +++ b/app/src/main/assets/sample/文件读写/读写文本文件.js @@ -1,22 +1,22 @@ //以写入模式打开SD卡根目录文件1.txt -var file = open("/sdcard/1.txt", "w") +var file = open('/sdcard/1.txt', 'w'); //写入aaaa -file.write("aaaa"); +file.write('aaaa'); //写入bbbbb后换行 -file.writeline("bbbbb"); +file.writeline('bbbbb'); //写入ccc与ddd两行 -file.writelines(["ccc", "ddd"]); +file.writelines(['ccc', 'ddd']); //关闭文件 file.close(); //以附加模式打开文件 -file = open("/sdcard/1.txt", "a"); +file = open('/sdcard/1.txt', 'a'); //附加一行"啦啦啦啦" -file.writeline("啦啦啦啦"); +file.writeline('啦啦啦啦'); //附加一行"哈哈哈哈" -file.writeline("哈哈哈哈"); +file.writeline('哈哈哈哈'); //附加两行ccc, ddd -file.writelines(["ccc", "ddd"]); +file.writelines(['ccc', 'ddd']); //输出缓冲区 file.flush(); //关闭文件 @@ -24,14 +24,14 @@ file.close(); //以读取模式打开文件 -file = open("/sdcard/test.txt", "r") +file = open('/sdcard/test.txt', 'r'); //读取一行并打印 print(file.readline()); //读取剩余所有行并打印 -for each(line in file.readlines()){ - print(line) +for (let line in file.readlines()) { + print(line); } -file.close() +file.close(); //显示控制台 -console.show() \ No newline at end of file +console.show(); \ No newline at end of file diff --git a/app/src/main/assets/sample/安卓7.0+点按和手势/三指下滑.js b/app/src/main/assets/sample/无障碍服务/三指下滑.js similarity index 100% rename from app/src/main/assets/sample/安卓7.0+点按和手势/三指下滑.js rename to app/src/main/assets/sample/无障碍服务/三指下滑.js diff --git a/app/src/main/assets/sample/安卓7.0+点按和手势/三指捏合.js b/app/src/main/assets/sample/无障碍服务/三指捏合.js similarity index 100% rename from app/src/main/assets/sample/安卓7.0+点按和手势/三指捏合.js rename to app/src/main/assets/sample/无障碍服务/三指捏合.js diff --git a/app/src/main/assets/sample/安卓7.0+点按和手势/双指捏合.js b/app/src/main/assets/sample/无障碍服务/双指捏合.js similarity index 100% rename from app/src/main/assets/sample/安卓7.0+点按和手势/双指捏合.js rename to app/src/main/assets/sample/无障碍服务/双指捏合.js diff --git a/app/src/main/assets/sample/无障碍服务/安卓 11 (R) 新增 [v6.1.0+].js b/app/src/main/assets/sample/无障碍服务/安卓 11 (R) 新增 [v6.1.0+].js new file mode 100644 index 00000000..bf8dc0e8 --- /dev/null +++ b/app/src/main/assets/sample/无障碍服务/安卓 11 (R) 新增 [v6.1.0+].js @@ -0,0 +1,38 @@ +// noinspection BadExpressionStatementJS,JSXNamespaceValidation,JSXNamespaceValidation + +'ui'; + +let config = { + textSize: 15, + textMargin: 8, + requiredApi: 30, + methodNames: [ + 'headsethook', + 'accessibilityButton', + 'accessibilityButtonChooser', + 'accessibilityShortcut', + 'accessibilityAllApps', + 'dismissNotificationShade', + ], +}; + +ui.layout( + + + +); + +ui['requiredApi'].setText(`Required API Level: ${config.requiredApi}`); +ui['requiredApi'].setTextSize(config.textSize); + +ui['currentApi'].setText(`Current API Level: ${device.sdkInt}`); +ui['currentApi'].setTextSize(config.textSize); + +config.methodNames.forEach((methodName) => { + let view = ui.inflate(