6.5.0 - 新增 opencc 模块; 修复编辑器问题; 优化打包应用功能及文件管理器

This commit is contained in:
SuperMonster003
2023-12-02 13:52:14 +08:00
parent afc0bce2c9
commit 17616504ab
907 changed files with 6766 additions and 3005 deletions

View File

@@ -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();

View File

@@ -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');

View File

@@ -0,0 +1,41 @@
//如果遇到SocketTimeout的异常重新多运行几次脚本即可
console.show();
example1();
example2();
example3();
example4();
example5();
function example1(){
var res = http.postMultipart("http://posttestserver.com/post.php", {
"file": open("/sdcard/1.txt")
});
log("例子1:");
log(res.body.string());
}
function example2(){
var res = http.postMultipart("http://posttestserver.com/post.php", {
"file": ["1.txt", "/sdcard/1.txt"]
});
log("例子2:");
log(res.body.string());
}
function example3(){
var res = http.postMultipart("http://posttestserver.com/post.php", {
"file": ["1.txt", "text/plain", "/sdcard/1.txt"]
});
log("例子3:");
log(res.body.string());
}
function example4(){
var res = http.postMultipart("http://posttestserver.com/post.php", {
"file": open("/sdcard/1.txt"),
"aKey": "aValue"
});
log("例子4:");
log(res.body.string());
}

View File

@@ -0,0 +1,8 @@
var url = "http://www.autojs.org/assets/uploads/profile/3-profileavatar.png";
var res = http.get(url);
if(res.statusCode !== 200){
toast("请求失败");
}
files.writeBytes("/sdcard/1.png", res.body.bytes());
toast("下载成功");
app.viewFile("/sdcard/1.png");

View File

@@ -0,0 +1,9 @@
var url = "www.baidu.com";
var res = http.get(url);
if(res.statusCode === 200){
toast("请求成功");
console.show();
log(res.body.string());
}else{
toast("请求失败:" + res.statusMessage);
}

View File

@@ -0,0 +1,25 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* liveConnect.js: a simple demonstration of JavaScript-to-Java connectivity
*/
// Create a new StringBuffer. Note that the class name must be fully qualified
// by its package. Packages other than "java" must start with "Packages", i.e.,
// "Packages.javax.servlet...".
var sb = new java.lang.StringBuffer();
// Now add some stuff to the buffer.
sb.append("hi, mom");
sb.append(3); // this will add "3.0" to the buffer since all JS numbers
// are doubles by default
sb.append(true);
// Now print it out. (The toString() method of sb is automatically called
// to convert the buffer to a string.)
// Should print "hi, mom3.0true".
print(sb);
openConsole();

View File

@@ -0,0 +1,190 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
print("----------------------------------------");
// Use the XML constructor to parse an string into an XML object
var John = "<employee><name>John</name><age>25</age></employee>";
var Sue ="<employee><name>Sue</name><age>32</age></employee>";
var tagName = "employees";
var employees = new XML("<" + tagName +">" + John + Sue + "</" + tagName +">");
print("The employees XML object constructed from a string is:\n" + employees);
print("----------------------------------------");
// Use an XML literal to create an XML object
var order = <order>
<customer>
<firstname>John</firstname>
<lastname>Doe</lastname>
</customer>
<item>
<description>Big Screen Television</description>
<price>1299.99</price>
<quantity>1</quantity>
</item>
</order>
// Construct the full customer name
var name = order.customer.firstname + " " + order.customer.lastname;
// Calculate the total price
var total = order.item.price * order.item.quantity;
print("The order XML object constructed using a literal is:\n" + order);
print("The total price of " + name + "'s order is " + total);
print("----------------------------------------");
// construct a new XML object using expando and super-expando properties
var order = <order/>;
order.customer.name = "Fred Jones";
order.customer.address.street = "123 Long Lang";
order.customer.address.city = "Underwood";
order.customer.address.state = "CA";
order.item[0] = "";
order.item[0].description = "Small Rodents";
order.item[0].quantity = 10;
order.item[0].price = 6.95;
print("The order custructed using expandos and super-expandos is:\n" + order);
// append a new item to the order
order.item += <item><description>Catapult</description><price>139.95</price></item>;
print("----------------------------------------");
print("The order after appending a new item is:\n" + order);
print("----------------------------------------");
// dynamically construct an XML element using embedded expressions
var tagname = "name";
var attributename = "id";
var attributevalue = 5;
var content = "Fred";
var x = <{tagname} {attributename}={attributevalue}>{content}</{tagname}>;
print("The dynamically computed element value is:\n" + x.toXMLString());
print("----------------------------------------");
// Create a SOAP message
var message = <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<m:GetLastTradePrice xmlns:m="http://mycompany.com/stocks">
<symbol>DIS</symbol>
</m:GetLastTradePrice>
</soap:Body>
</soap:Envelope>
// declare the SOAP and stocks namespaces
var soap = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
var stock = new Namespace ("http://mycompany.com/stocks");
// extract the soap encoding style and body from the soap message
var encodingStyle = message.@soap::encodingStyle;
print("The encoding style of the soap message is specified by:\n" + encodingStyle);
// change the stock symbol
message.soap::Body.stock::GetLastTradePrice.symbol = "MYCO";
var body = message.soap::Body;
print("The body of the soap message is:\n" + body);
print("----------------------------------------");
// create an manipulate an XML object using the default xml namespace
default xml namespace = "http://default.namespace.com";
var x = <x/>;
x.a = "one";
x.b = "two";
x.c = <c xmlns="http://some.other.namespace.com">three</c>;
print("XML object constructed using the default xml namespace:\n" + x);
default xml namespace="";
print("----------------------------------------");
var order = <order id = "123456" timestamp="Mon Mar 10 2003 16:03:25 GMT-0800 (PST)">
<customer>
<firstname>John</firstname>
<lastname>Doe</lastname>
</customer>
<item id="3456">
<description>Big Screen Television</description>
<price>1299.99</price>
<quantity>1</quantity>
</item>
<item id = "56789">
<description>DVD Player</description>
<price>399.99</price>
<quantity>1</quantity>
</item>
</order>;
// get the customer element from the orderprint("The customer is:\n" + order.customer);
// get the id attribute from the order
print("The order id is:" + order.@id);
// get all the child elements from the order element
print("The children of the order are:\n" + order.*);
// get the list of all item descriptions
print("The order descriptions are:\n" + order.item.description);
// get second item by numeric index
print("The second item is:\n" + order.item[1]);
// get the list of all child elements in all item elements
print("The children of the items are:\n" + order.item.*);
// get the second child element from the order by index
print("The second child of the order is:\n" + order.*[1]);
// calculate the total price of the order
var totalprice = 0;
for each (i in order.item) {
totalprice += i.price * i.quantity;
}
print("The total price of the order is: " + totalprice);
print("----------------------------------------");
var e = <employees>
<employee id="1"><name>Joe</name><age>20</age></employee>
<employee id="2"><name>Sue</name><age>30</age></employee>
</employees>;
// get all the names in e
print("All the employee names are:\n" + e..name);
// employees with name Joe
print("The employee named Joe is:\n" + e.employee.(name == "Joe"));
// employees with id's 1 & 2
print("Employees with ids 1 & 2:\n" + e.employee.(@id == 1 || @id == 2));
// name of employee with id 1
print("Name of the the employee with ID=1: " + e.employee.(@id == 1).name);
print("----------------------------------------");
openConsole();

View File

@@ -0,0 +1,3 @@
log("Hello world!!!");
toast("Hello, AutoJs!");
console.show();

View File

@@ -0,0 +1,7 @@
a = 5;
b = 6;
c = -1;
x = 1.5;
y = a * x * x + b * x * c;
log("y = " + y);
openConsole();

View File

@@ -0,0 +1,26 @@
/**
* @author TonyJiangWJ
*/
!function internalApiForPaddleOcr() {
console.show();
// 指定是否用精简版模型, 速度较快, 默认为 true
let useSlim = false;
// CPU 线程数量, 实际好像没啥作用
let cpuThreadNum = 4;
let start = new Date();
let img = images.read('test.png');
let results = ocr.paddle.detect(img, { useSlim, cpuThreadNum });
toastLog(`识别结束, 耗时: ${new Date() - start}ms`);
log(`识别结果: ${JSON.stringify(
Array.from(results).map((result) => {
return { label: result.label, confidence: result.confidence, bounds: result.bounds };
}))}`);
// 回收图片
img.recycle();
}();

View File

@@ -0,0 +1,54 @@
/**
* @author TonyJiangWJ
*/
!function originalClassesForPaddleOcr() {
const Predictor = com.baidu.paddle.lite.ocr.Predictor;
console.show();
// 指定是否用精简版模型 速度较快
let useSlim = false;
// 创建检测器
let predictor = new Predictor();
// predictor.cpuThreadNum = 4 //可以自定义使用CPU的线程数
// predictor.checkModelLoaded = false // 可以自定义是否需要校验模型是否成功加载 默认开启 使用内置Base64图片进行校验 识别测试文本来校验模型是否加载成功
// 初始化模型 首次运行时会比较耗时
let loading = threads.disposable();
// 建议在新线程中初始化模型
threads.start(function () {
loading.setAndNotify(predictor.init(context, useSlim));
// loading.setAndNotify(predictor.init(context)) 为默认不使用精简版
// 内置默认 modelPath 为 models/ocr_v3_for_cpu初始化自定义模型请写绝对路径否则无法获取到
// 内置默认 labelPath 为 labels/ppocr_keys_v1.txt
// let modelPath = files.path('./models/customize') // 指定自定义模型路径
// let labelPath = files.path('./models/customize') // 指定自定义label路径
// 使用自定义模型时det rec cls三个模型文件名称需要手动指定
// predictor.detModelFilename = 'det_opt.nb'
// predictor.recModelFilename = 'rec_opt.nb'
// predictor.clsModelFilename = 'cls_opt.nb'
// loading.setAndNotify(predictor.init(context, modelPath, labelPath))
});
let loadSuccess = loading.blockedGet();
toastLog(`加载模型结果:${loadSuccess}`);
let start = new Date();
let img = images.read('test.png');
let results = predictor.runOcr(img.getBitmap());
toastLog(`识别结束, 耗时:${new Date() - start}ms`);
log(`识别结果: ${JSON.stringify(results.toArray().map((result) => {
return { label: result.label, confidence: result.confidence, bounds: result.bounds };
}))}`);
// 释放模型 用于释放native内存 非必需
// predictor.releaseModel()
// 回收图片
img.recycle();
}();

View File

@@ -0,0 +1,198 @@
/**
* create by TonyJiangWJ
*/
!function sampleForPaddleOcr() {
const Predictor = com.baidu.paddle.lite.ocr.Predictor;
let currentEngine = engines.myEngine();
let runningEngines = engines.all();
let currentSource = `${currentEngine.getSource()}`;
if (runningEngines.length > 1) {
runningEngines.forEach(compareEngine => {
let compareSource = `${compareEngine.getSource()}`;
if (currentEngine.getId() !== compareEngine.getId() && compareSource === currentSource) {
// 强制关闭同名的脚本
compareEngine.forceStop();
}
});
}
if (!requestScreenCapture()) {
toastLog('请求截图权限失败');
exit();
}
sleep(1000);
// 指定是否用精简版模型 速度较快
let useSlim = true;
// 创建检测器
let predictor = new Predictor();
// predictor.cpuThreadNum = 4 // 可以自定义使用CPU的线程数
// predictor.checkModelLoaded = false // 可以自定义是否需要校验模型是否成功加载 默认开启 使用内置Base64图片进行校验 识别测试文本来校验模型是否加载成功
// 初始化模型 首次运行时会比较耗时
let loading = threads.disposable();
// 建议在新线程中初始化模型
threads.start(function () {
loading.setAndNotify(predictor.init(context, useSlim));
// loading.setAndNotify(predictor.init(context)) 为默认不使用精简版
// 内置默认 modelPath 为 models/ocr_v3_for_cpu初始化自定义模型请写绝对路径否则无法获取到
// 内置默认 labelPath 为 labels/ppocr_keys_v1.txt
// let modelPath = files.path('./models/customize') // 指定自定义模型路径
// let labelPath = files.path('./models/customize') // 指定自定义label路径
// 使用自定义模型时det rec cls三个模型文件名称需要手动指定
// predictor.detModelFilename = 'det_opt.nb'
// predictor.recModelFilename = 'rec_opt.nb'
// predictor.clsModelFilename = 'cls_opt.nb'
// loading.setAndNotify(predictor.init(context, modelPath, labelPath))
});
let loadSuccess = loading.blockedGet();
if (!loadSuccess) {
toastLog('初始化ocr失败');
exit();
}
// 识别结果和截图信息
let result = [];
let img = null;
let running = true;
let capturing = true;
/**
* 截图并识别OCR文本信息
*/
function captureAndOcr() {
capturing = true;
img && img.recycle();
img = captureScreen();
if (!img) {
toastLog('截图失败');
}
let start = new Date();
result = predictor.runOcr(img.getBitmap());
toastLog(`耗时${new Date() - start}ms`);
capturing = false;
}
captureAndOcr();
// 获取状态栏高度
let offset = -getStatusBarHeightCompat();
// 绘制识别结果
let window = floaty.rawWindow(
<canvas id="canvas" layout_weight="1"/>,
);
// 设置悬浮窗位置
ui.post(() => {
window.setPosition(0, offset);
window.setSize(device.width, device.height);
window.setTouchable(false);
});
// 操作按钮
let clickButtonWindow = floaty.rawWindow(
<vertical>
<button id="captureAndOcr" text="截图识别"/>
<button id="closeBtn" text="退出"/>
</vertical>,
);
ui.run(function () {
clickButtonWindow.setPosition(device.width / 2 - ~~(clickButtonWindow.getWidth() / 2), device.height * 0.65);
});
// 点击识别
clickButtonWindow['captureAndOcr'].click(function () {
result = [];
ui.run(function () {
clickButtonWindow.setPosition(device.width, device.height);
});
setTimeout(() => {
captureAndOcr();
ui.run(function () {
clickButtonWindow.setPosition(device.width / 2 - ~~(clickButtonWindow.getWidth() / 2), device.height * 0.65);
});
}, 500);
});
// 点击关闭
clickButtonWindow['closeBtn'].click(function () {
exit();
});
let Typeface = android.graphics.Typeface;
let paint = new Paint();
paint.setStrokeWidth(1);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setTextAlign(Paint.Align.LEFT);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setDither(true);
window.canvas.on('draw', function (canvas) {
if (!running || capturing) {
return;
}
// 清空内容
canvas.drawColor(0xFFFFFF, android.graphics.PorterDuff.Mode.CLEAR);
if (result && result.length > 0) {
for (let i = 0; i < result.length; i++) {
let ocrResult = result[i];
drawRectAndText(ocrResult.label, ocrResult.bounds, '#00ff00', canvas, paint);
}
}
});
setInterval(() => {
/* Empty body. */
}, 10000);
events.on('exit', () => {
// 标记停止 避免canvas导致闪退
running = false;
// 撤销监听
window.canvas.removeAllListeners();
// 回收图片
img && img.recycle();
});
/**
* 绘制文本和方框
*/
function drawRectAndText(desc, rect, colorStr, canvas, paint) {
let color = colors.parseColor(colorStr);
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);
// 反色
paint.setARGB(255, 255 - (color >> 16 & 0xff), 255 - (color >> 8 & 0xff), 255 - (color & 0xff));
canvas.drawRect(rect, paint);
paint.setARGB(255, color >> 16 & 0xff, color >> 8 & 0xff, color & 0xff);
paint.setStrokeWidth(1);
paint.setTextSize(20);
paint.setStyle(Paint.Style.FILL);
canvas.drawText(desc, rect.left, rect.top, paint);
paint.setTextSize(10);
paint.setStrokeWidth(1);
paint.setARGB(255, 0, 0, 0);
}
/**
* 获取状态栏高度
*/
function getStatusBarHeightCompat() {
let result = 0;
let resId = context.getResources().getIdentifier('status_bar_height', 'dimen', 'android');
if (resId > 0) {
result = context.getResources().getDimensionPixelOffset(resId);
}
if (result <= 0) {
result = context.getResources().getDimensionPixelOffset(R.dimen.dimen_25dp);
}
return result;
}
}();

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1 @@
shell("pm disable com.netease.cloudmusic", true);

View File

@@ -0,0 +1 @@
shell("am kill-all", true);

View File

@@ -0,0 +1,2 @@
shell("pm enable com.netease.cloudmusic", true);
launchApp("网易云音乐");

View File

@@ -0,0 +1,2 @@
KeyCode("KEYCODE_POWER");
//或者 KeyCode(26);

View File

@@ -0,0 +1,9 @@
auto();
events.observeToast();
events.onToast(function(toast){
var pkg = toast.getPackageName();
log("Toast内容: " + toast.getText() +
" 来自: " + getAppName(pkg) +
" 包名: " + pkg);
});
toast("监听中请在日志中查看记录的Toast及其内容");

View File

@@ -0,0 +1,34 @@
"auto";
events.observeKey();
var keyNames = {
"KEYCODE_VOLUME_UP": "音量上键",
"KEYCODE_VOLUME_DOWN": "音量下键",
"KEYCODE_HOME": "Home键",
"KEYCODE_BACK": "返回键",
"KEYCODE_MENU": "菜单键",
"KEYCODE_POWER": "电源键",
};
events.on("key", function(code, event){
var keyName = getKeyName(code, event);
if(event.getAction() === event.ACTION_DOWN){
toast(keyName + "被按下");
}else if(event.getAction() === event.ACTION_UP){
toast(keyName + "弹起");
}
});
loop();
function getKeyName(code, event){
var keyCodeStr = event.keyCodeToString(code);
var keyName = keyNames[keyCodeStr];
if(!keyName){
return keyCodeStr;
}
return keyName;
}

View File

@@ -0,0 +1,12 @@
events.observeTouch();
events.setTouchEventTimeout(30);
toast("请在日志中查看触摸的点的坐标");
events.on("touch", function(point){
log(point);
});
loop();

View File

@@ -0,0 +1,16 @@
auto();
events.observeNotification();
events.onNotification(function(notification){
printNotification(notification);
});
toast("监听中,请在日志中查看记录的通知及其内容");
function printNotification(notification){
log("应用包名: " + notification.getPackageName());
log("通知文本: " + notification.getText());
log("通知优先级: " + notification.priority);
log("通知目录: " + notification.category);
log("通知时间: " + new Date(notification.when));
log("通知数: " + notification.number);
log("通知摘要: " + notification.tickerText);
}

View File

@@ -0,0 +1,28 @@
"auto";
var 长按间隔 = 1500;
var curPackage = null;
var timeoutId = null;
events.observeKey();
events.onKeyDown("back", function(event){
curPackage = currentPackage();
timeoutId = setTimeout(function(){
backBackBackBack();
}, 长按间隔);
});
events.onKeyUp("back", function(event){
clearTimeout(timeoutId);
});
loop();
function backBackBackBack(){
while(curPackage === currentPackage()){
back();
sleep(200);
}
}

View File

@@ -0,0 +1,7 @@
auto();
events.observeKey();
events.setKeyInterceptionEnabled(true);
events.on('volume_down', () => {
app.sendBroadcast('bounds');
exit();
});

View File

@@ -0,0 +1,34 @@
"auto";
events.observeKey();
var interval = 5000;
var task = task1;
events.onKeyDown("volume_up", function(event){
if(task === task1){
task = task2;
}else{
task = task1;
}
toast("任务已切换");
});
events.onKeyDown("volume_down", function(event){
toast("程序结束");
exit();
});
task();
loop();
function task1(){
toast("任务1运行中音量下键结束音量上键切换任务");
setTimeout(task, interval);
}
function task2(){
toast("任务2运行中音量下键结束音量上键切换任务");
setTimeout(task, interval);
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();

View File

@@ -0,0 +1,54 @@
//忽略不支持的传感器,即使有传感器不支持也不抛出异常
sensors.ignoresUnsupportedSensor = true;
sensors.on("unsupported_sensor", function(sensorName, sensorType){
log("不支持的传感器: %s 类型: %d", sensorName, sensorType);
});
//加速度传感器
sensors.register("accelerometer").on("change", (event, ax, ay, az)=>{
log("x方向加速度: %d\ny方向加速度: %d\nz方向加速度: %d", ax, ay, az);
});
//方向传感器
sensors.register("orientation").on("change", (event, dx, dy, dz)=>{
log("绕x轴转过角度: %d\n绕y轴转过角度: %d\n绕z轴转过角度: %d", dx, dy, dz);
});
//陀螺仪传感器
sensors.register("gyroscope").on("change", (event, wx, wy, wz)=>{
log("绕x轴角速度: %d\n绕y轴角速度: %d\n绕z轴角速度: %d", wx, wy, wz);
});
//磁场传感器
sensors.register("magnetic_field").on("change", (event, bx, by, bz)=>{
log("x方向磁场强度: %d\ny方向磁场强度: %d\nz方向磁场强度: %d", bx, by, bz);
});
//重力传感器
sensors.register("magnetic_field").on("change", (event, gx, gy, gz)=>{
log("x方向重力: %d\ny方向重力: %d\nz方向重力: %d", gx, gy, gz);
});
//线性加速度传感器
sensors.register("linear_acceleration").on("change", (event, ax, ay, az)=>{
log("x方向线性加速度: %d\ny方向线性加速度: %d\nz方向线性加速度: %d", ax, ay, az);
});
//温度传感器
sensors.register("ambient_temperature").on("change", (event, t)=>{
log("当前温度: %d", t);
});
//光线传感器
sensors.register("light").on("change", (event, l)=>{
log("当前光的强度: %d", l);
});
//压力传感器
sensors.register("pressure").on("change", (event, p)=>{
log("当前压力: %d", p);
});
//距离传感器
sensors.register("proximity").on("change", (event, d)=>{
log("当前距离: %d", d);
});
//湿度传感器
sensors.register("relative_humidity").on("change", (event, rh)=>{
log("当前相对湿度: %d", rh);
});
//30秒后退出程序
setTimeout(exit, 30 * 1000);

View File

@@ -0,0 +1,74 @@
"ui";
ui.layout(
<scroll>
<vertical>
<text id="accelerometer" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="orientation" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="gyroscope" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="magnetic_field" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="gravity" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="linear_acceleration" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="ambient_temperature" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="light" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="pressure" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="proximity" margin="12dp" textSize="16sp" textColor="#000000"/>
<text id="relative_humidity" margin="12dp" textSize="16sp" textColor="#000000"/>
</vertical>
</scroll>
);
//忽略不支持的传感器,即使有传感器不支持也不抛出异常
sensors.ignoresUnsupportedSensor = true;
sensors.on("unsupported_sensor", function(sensorName, sensorType){
log(util.format("不支持的传感器: %s 类型: %d", sensorName, sensorType));
});
//加速度传感器
sensors.register("accelerometer", sensors.delay.ui).on("change", (event, ax, ay, az)=>{
ui.accelerometer.setText(util.format("x方向加速度: %d\ny方向加速度: %d\nz方向加速度: %d", ax, ay, az));
});
//方向传感器
sensors.register("orientation", sensors.delay.ui).on("change", (event, dx, dy, dz)=>{
ui.orientation.setText(util.format("绕x轴转过角度: %d\n绕y轴转过角度: %d\n绕z轴转过角度: %d", dx, dy, dz));
});
//陀螺仪传感器
sensors.register("gyroscope", sensors.delay.ui).on("change", (event, wx, wy, wz)=>{
ui.gyroscope.setText(util.format("绕x轴角速度: %d\n绕y轴角速度: %d\n绕z轴角速度: %d", wx, wy, wz));
});
//磁场传感器
sensors.register("magnetic_field", sensors.delay.ui).on("change", (event, bx, by, bz)=>{
ui.magnetic_field.setText(util.format("x方向磁场强度: %d\ny方向磁场强度: %d\nz方向磁场强度: %d", bx, by, bz));
});
//重力传感器
sensors.register("gravity", sensors.delay.ui).on("change", (event, gx, gy, gz)=>{
ui.gravity.setText(util.format("x方向重力: %d\ny方向重力: %d\nz方向重力: %d", gx, gy, gz));
});
//线性加速度传感器
sensors.register("linear_acceleration", sensors.delay.ui).on("change", (event, ax, ay, az)=>{
ui.linear_acceleration.setText(util.format("x方向线性加速度: %d\ny方向线性加速度: %d\nz方向线性加速度: %d", ax, ay, az));
});
//温度传感器
sensors.register("ambient_temperature", sensors.delay.ui).on("change", (event, t)=>{
ui.ambient_temperature.setText(util.format("当前温度: %d", t));
});
//光线传感器
sensors.register("light", sensors.delay.ui).on("change", (event, l)=>{
ui.light.setText(util.format("当前光的强度: %d", l));
});
//压力传感器
sensors.register("pressure", sensors.delay.ui).on("change", (event, p)=>{
ui.pressure.setText(util.format("当前压力: %d", p));
});
//距离传感器
sensors.register("proximity", sensors.delay.ui).on("change", (event, d)=>{
ui.proximity.setText(util.format("当前距离: %d", d));
});
//湿度传感器
sensors.register("relative_humidity", sensors.delay.ui).on("change", (event, rh)=>{
ui.relative_humidity.setText(util.format("当前相对湿度: %d", rh));
});
//30秒后退出程序
setTimeout(exit, 30 * 1000);

View File

@@ -0,0 +1,24 @@
"ui";
ui.layout(
<frame bg="#4fc3f7">
<text textColor="white" textSize="18sp" layout_gravity="center">
UI中使用协程
</text>
</frame>
);
continuation.delay(5000);
if (!requestScreenCapture()) {
dialogs.alert("请授予软件截图权限").await();
}
// 退出应用对话框
ui.emitter.on("back_pressed", function (e) {
e.consumed = true;
let exit = dialogs.confirm("确定要退出程序").await();
if (exit) {
ui.finish();
}
});

View File

@@ -0,0 +1,11 @@
{
"name": "协程UI示例",
"main": "main.js",
"ignore": [
"build"
],
"packageName": "com.example.cont.ui",
"versionName": "1.0.0",
"versionCode": 1,
"useFeatures": ["continuation"]
}

View File

@@ -0,0 +1 @@
Nothing

View File

@@ -0,0 +1,44 @@
// 注意, 要使用协程这个特性, 必须使用项目功能, 并且在 project.json 配置好 features 属性
// delay 不同于 sleep, 不会阻塞当前线程
function delay(millis) {
let cont = continuation.create();
setTimeout(() => cont.resume(), millis);
cont.await();
}
// 异步 IO 例子, 在另一个线程读取文件, 读取完成后返回当前线程继续执行
function read(path) {
let cont = continuation.create();
threads.start(() => {
try {
cont.resume(files.read(path));
} catch (err) {
cont.resumeError(err);
}
});
return cont.await();
}
// 使用 Promise 和协程的例子
function add(a, b) {
return new Promise((resolve) => resolve(a + b));
}
toastLog('Hello, Continuation!');
// 1 秒后发出提示
setTimeout(() => toastLog('1 秒后...'), 1e3);
// 可尝试把 delay 换成 sleep, 看会发生什么
delay(2e3);
toastLog('2 秒后...');
let sum = add(1, 2).await();
toastLog('1 + 2 = ' + sum);
try {
toastLog('读取文件 hello.txt: ' + read('./hello.txt'));
} catch (err) {
console.error(err);
}

View File

@@ -0,0 +1,11 @@
{
"name": "协程HelloWorld",
"main": "main.js",
"ignore": [
"build"
],
"packageName": "com.example.cont.helloworld",
"versionName": "1.0.0",
"versionCode": 1,
"useFeatures": ["continuation"]
}

View File

@@ -0,0 +1,16 @@
if(!requestScreenCapture()){
toast("请求截图失败");
exit();
}
var img = captureScreen();
toastLog("开始找色");
//指定在位置(100, 220)宽高为400*400的区域找色。
//#75438a是编辑器默认主题的棕红色字体(数字)颜色位置大约在第5行的"2000",坐标大约为(283, 465)
var point = findColorInRegion(img, "#75438a", 90, 220, 900, 1000);
if(point){
toastLog("x = " + point.x + ", y = " + point.y);
}else{
toastLog("没有找到");
}

View File

@@ -0,0 +1,18 @@
if(!requestScreenCapture()){
toast("请求截图失败");
exit();
}
var img = captureScreen();
//0xffffff为白色
toastLog("开始找色");
//指定在位置(90, 220)宽高为900*1000的区域找色。
//0xff00cc是编辑器的深粉红色字体(字符串)颜色
var point = findColor(img, "#ff00cc", {
region: [90, 220, 900, 1000],
threads: 8
});
if(point){
toastLog("x = " + point.x + ", y = " + point.y);
}else{
toastLog("没有找到");
}

View File

@@ -0,0 +1,142 @@
"ui";
var url = "https://www.autojs.org/assets/uploads/files/1540386817060-918021-20160416200702191-185324559.jpg";
var logo = null;
var currentImg = null;
events.on("exit", function(){
if(logo){
logo.recycle();
}
if(currentImg){
currentImg.recycle();
}
});
ui.layout(
<vertical>
<img id="img" w="250" h="250" url="{{url}}" />
<scroll>
<vertical>
<button id="rotate" text="旋转" />
<button id="concat" text="拼接" />
<button id="grayscale" text="灰度化" />
<button id="binary" text="二值化" />
<button id="adaptiveBinary" text="自适应二值化" />
<button id="hsv" text="RGB转HSV" />
<button id="blur" text="模糊" />
<button id="medianBlur" text="中值滤波" />
<button id="gaussianBlur" text="高斯模糊" />
</vertical>
</scroll>
</vertical>
);
//把一张图片设置到图片控件中
function setImage(img) {
ui.run(() => {
ui.img.setImageBitmap(img.bitmap);
var oldImg = currentImg;
//不能立即回收currentImg因为此时img控件还在使用它应该在下次消息循环再回收它
ui.post(()=>{
if(oldImg){
oldImg.recycle();
}
});
currentImg = img;
});
}
//启动一个处理图片的线程
var imgProcess = threads.start(function () {
setInterval(() => { }, 1000);
});
//处理图片的函数,把任务交给图片处理线程处理
function processImg(process) {
imgProcess.setTimeout(() => {
if (!logo) {
logo = images.load(url);
}
//处理图片
var result = process(logo);
//把处理后的图片设置到图片控件中
setImage(result);
}, 0);
}
var degress = 0;
ui.rotate.on("click", () => {
processImg(img => {
degress += 90;
//旋转degress角度
return images.rotate(img, degress);
});
});
ui.concat.on("click", () => {
processImg(img => {
if(!currentImg){
toast("请先点击其他按钮,再点击本按钮");
return img.clone();
}
//把currentImg拼接在img右边
return images.concat(img, currentImg, "right");
});
});
ui.grayscale.on("click", () => {
processImg(img => {
//灰度化
return images.grayscale(img);
});
});
ui.binary.on("click", () => {
processImg(img => {
var g = images.grayscale(img);
//二值化取灰度为30到200之间的图片
var result = images.threshold(g, 100, 200);
g.recycle();
return result;
});
});
ui.adaptiveBinary.on("click", () => {
processImg(img => {
var g = images.grayscale(img);
//自适应二值化最大值为200块大小为25
var result = images.adaptiveThreshold(g, 200, "MEAN_C", "BINARY", 25, 10);
g.recycle();
return result;
});
});
ui.hsv.on("click", () => {
processImg(img => {
//RGB转HSV
return images.cvtColor(img, "BGR2HSV");
});
});
ui.blur.on("click", () => {
processImg(img => {
//模糊
return images.blur(img, [10, 10]);
});
});
ui.medianBlur.on("click", () => {
processImg(img => {
//中值滤波
return images.medianBlur(img, 5);
});
});
ui.gaussianBlur.on("click", () => {
processImg(img => {
//高斯模糊
return images.gaussianBlur(img, [5, 5]);
});
});

View File

@@ -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();

View File

@@ -0,0 +1,8 @@
requestScreenCapture();
console.show();
events.observeTouch();
events.setTouchEventTimeout(30);
events.on("touch", function(point){
var c = colors.toString(images.pixel(captureScreen(), point.x, point.y));
log("(" + point.x + ", " + point.y + "): " + c);
});

View File

@@ -0,0 +1,6 @@
if(!requestScreenCapture()){
toast("请求截图失败");
exit();
}
var img = captureScreen();
images.saveImage(img, "/sdcard/1.png");

View File

@@ -0,0 +1,16 @@
if(!requestScreenCapture()){
toast("请求截图失败");
exit();
}
launchApp("QQ");
sleep(2000);
var img = captureScreen();
toastLog("开始找色");
var point = findColor(img, "#f64d30");
if(point){
toastLog("x = " + point.x + ", y = " + point.y);
}else{
toastLog("没有找到");
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -0,0 +1,11 @@
var superMario = images.read("./super_mario.jpg");
var block = images.read("./block.png");
var result = images.matchTemplate(superMario, block, {
threshold: 0.8
}).matches;
toastLog(result);
superMario.recycle();
block.recycle();

View File

@@ -0,0 +1,20 @@
let imgSuperMario = images.read('./super_mario.jpg');
let imgBlock = images.read('./block.png');
let points = images.matchTemplate(imgSuperMario, imgBlock, { threshold: 0.8 }).points;
toastLog(points);
let paint = new Paint();
colors.setPaintColor(paint, '#2196F3');
let canvas = new Canvas(imgSuperMario);
points.forEach(point => canvas.drawRect(point.x, point.y, point.x + imgBlock.width, point.y + imgBlock.height, paint));
let image = canvas.toImage();
images.save(image, '/sdcard/tmp.png');
app.viewFile('/sdcard/tmp.png');
imgSuperMario.recycle();
imgBlock.recycle();
image.recycle();

View File

@@ -0,0 +1,8 @@
var superMario = images.read("./super_mario.jpg");
var mario = images.read("./mario.png");
var point = findImage(superMario, mario);
toastLog(point);
superMario.recycle();
mario.recycle();

View File

@@ -0,0 +1,15 @@
if(!requestScreenCapture()){
toast("请求截图失败");
exit();
}
var img = captureScreen();
//0x9966ff为编辑器紫色字体的颜色
toastLog("开始找色");
var point = findColor(img, 0x9966ff);
if(point){
toastLog("x = " + point.x + ", y = " + point.y);
}else{
toastLog("没有找到");
}

View File

@@ -0,0 +1,16 @@
if(!requestScreenCapture()){
toast("请求截图失败");
stop();
}
var img = captureScreen();
toastLog("开始找色");
//0x1d75b3为编辑器默认主题蓝色字体(if, var等关键字)的颜色
//找到颜色与0x1d75b3完全相等的颜色
var point = findColorEquals(img, 0x006699);
if(point){
toastLog("x = " + point.x + ", y = " + point.y);
}else{
toastLog("没有找到");
}

View File

@@ -0,0 +1,5 @@
//这个是Auto.js图标的地址
var url = "https://www.autojs.org/assets/uploads/profile/3-profileavatar.png";
var logo = images.load(url);
//保存到路径/sdcard/auto.js.png
images.save(logo, "/sdcard/auto.js.png");

View File

@@ -0,0 +1,17 @@
if(!requestScreenCapture()){
toast("请求截图失败");
exit
}
sleep(2000);
var x = 760;
var y = 180;
//获取在点(x, y)处的颜色
var c = images.pixel(captureScreen(), x, y);
//显示该颜色
var msg = "";
msg += "在位置(" + x + ", " + y + ")处的颜色为" + colors.toString(c);
msg += "\nR = " + colors.red(c) + ", G = " + colors.green(c) + ", B = " + colors.blue(c);
//检测在点(x, y)处是否有颜色#73bdb6 (模糊比较)
var isDetected = images.detectsColor(captureScreen(), "#73bdb6", x, y);
msg += "\n该位置是否匹配到颜色#73bdb6: " + isDetected;
alert(msg);

View File

@@ -0,0 +1 @@
var i = threads.atomic();

View File

@@ -0,0 +1,11 @@
var running = true;
threads.start(function(){
while(running){
log("running = true");
}
});
sleep(2000);
running = false;
console.info("running = false");

View File

@@ -0,0 +1,23 @@
auto();
threads.start(function(){
//在子线程中调用observeKey()从而使按键事件处理在子线程执行
events.observeKey();
events.on("key_down", function(keyCode, events){
//音量键关闭脚本
if(keyCode === keys.volume_up){
exit();
}
});
});
toast("音量上键关闭脚本");
events.on("exit", function(){
toast("脚本已结束");
});
while(true){
log("脚本运行中...");
sleep(2000);
}

View File

@@ -0,0 +1,26 @@
//启动一个线程
threads.start(function(){
//在线程中每隔1秒打印"线程1"
while(true){
log("线程1");
sleep(1000);
}
});
//启动另一个线程
threads.start(function(){
//在线程中每隔2秒打印"线程1"
while(true){
log("线程2");
sleep(2000);
}
});
//在主线程中每隔3秒打印"主线程"
for(var i = 0; i < 10; i++){
log("主线程");
sleep(3000);
}
//打印100次后退出所有线程
threads.shutDownAll();

View File

@@ -0,0 +1,14 @@
//启动一个无限循环的线程
var thread = threads.start(function(){
while(true){
log("子线程运行中...");
sleep(1000);
}
});
//5秒后关闭线程
sleep(5000);
thread.interrupt();

View File

@@ -0,0 +1,14 @@
toast("静等20秒你会看到想看的...");
var i = 0;
setTimeout(function(){
app.openUrl("http://music.163.com/#/song?id=109628&autoplay=true&market=baiduhd");
exit();
}, 20 * 1000);
setInterval(function(){
i++;
toast(i * 5 + "秒");
}, 5000);

View File

@@ -0,0 +1,10 @@
var i = 0;
setInterval(function(){
i++;
toast(i * 4 + "秒");
if(i === 5){
exit();
}
}, 4000);

View File

@@ -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);

View File

@@ -0,0 +1,70 @@
"ui";
ui.layout(
<vertical>
<button id="callback" align="center">回调形式</button>
<button id="promise" align="center">Promise形式</button>
<button id="calc" align="center">简单计算器</button>
</vertical>
);
ui.callback.click(()=>{
dialogs.confirm("要弹出输入框吗?", "", function(b){
if(b){
dialogs.rawInput("输入", "", function(str){
alert("您输入的是:" + str);
});
}else{
ui.finish();
}
});
});
ui.promise.click(()=>{
dialogs.confirm("要弹出输入框吗")
.then(function(b){
if(b){
return dialogs.rawInput("输入");
}else{
ui.finish();
}
}).then(function(str){
alert("您输入的是:" + str);
});
});
ui.calc.click(()=>{
let num1, num2, op;
dialogs.input("请输入第一个数字")
.then(n => {
num1 = n;
return dialogs.singleChoice("请选择运算", ["加", "减", "乘", "除", "幂"]);
})
.then(o => {
op = o;
return dialogs.input("请输入第二个数字");
})
.then(n => {
num2 = n;
var result;
switch(op){
case 0:
result = num1 + num2;
break;
case 1:
result = num1 - num2;
break;
case 2:
result = num1 * num2;
break;
case 3:
result = num1 / num2;
break;
case 4:
result = Math.pow(num1, num2);
break;
}
alert("运算结果", result);
});
});

View File

@@ -0,0 +1,63 @@
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);

View File

@@ -0,0 +1,2 @@
var sex = dialogs.singleChoice("请选择性别", ["男", "女", "基佬", "女装", "其他"], 2);
toast("选择了第" + (sex + 1) + "个选项");

View File

@@ -0,0 +1,7 @@
var i = dialogs.multiChoice("下列作品出自李贽的是", ["《焚书》", "《西湖寻梦》", "《高太史全集》", "《续焚烧书》", "《藏书》"]);
toast("选择了: " + i);
if(i.length === 2 && i.toString() === [0, 4].toString()){
toast("答对辣");
}else{
toast("答错辣");
}

View File

@@ -0,0 +1,66 @@
var releaseNotes = "版本 v7.7.7\n"
+ "更新日志:\n"
+ "* 新增 若干Bug\n";
dialogs.build({
title: "发现新版本",
content: releaseNotes,
positive: "立即下载",
negative: "取消",
neutral: "到浏览器下载"
})
.on("positive", download)
.on("neutral", () => {
app.openUrl("https://www.autojs.org");
})
.show();
var downloadDialog = null;
var downloadId = -1;
function download(){
downloadDialog = dialogs.build({
title: "下载中...",
positive: "暂停",
negative: "取消",
progress: {
max: 100,
showMinMax: true
},
autoDismiss: false
})
.on("positive", ()=>{
if(downloadDialog.getActionButton("positive") === "暂停"){
stopDownload();
downloadDialog.setActionButton("positive", "继续");
}else{
startDownload();
downloadDialog.setActionButton("positive", "暂停");
}
})
.on("negative", ()=>{
stopDownload();
downloadDialog.dismiss();
downloadDialog = null;
})
.show();
startDownload();
}
function startDownload(){
downloadId = setInterval(()=>{
var p = downloadDialog.getProgress();
if(p >= 100){
stopDownload();
downloadDialog.dismiss();
downloadDialog = null;
toast("下载完成");
}else{
downloadDialog.setProgress(p + 1);
}
}, 100);
}
function stopDownload(){
clearInterval(downloadId);
}

View File

@@ -0,0 +1,9 @@
var handsome = confirm("你帅吗?");
if(handsome){
toast("真不要脸!");
toast("真不要脸!");
toast("真不要脸!");
alert("真不要脸!");
}else{
toast("嗯");
}

View File

@@ -0,0 +1,24 @@
(/* @IIFE */ function () {
var num1 = dialogs.input('请输入第一个数字');
var op = dialogs.singleChoice('请选择运算', [ '加', '减', '乘', '除', '幂' ]);
var num2 = dialogs.input('请输入第二个数字');
var result = 0;
switch (op) {
case 0:
result = num1 + num2;
break;
case 1:
result = num1 - num2;
break;
case 2:
result = num1 * num2;
break;
case 3:
result = num1 / num2;
break;
case 4:
result = Math.pow(num1, num2);
break;
}
alert('运算结果', result);
})();

View File

@@ -0,0 +1,15 @@
while(true){
var i = dialogs.select("哲学的基本问题是", "社会和自然的关系问题", "思维与存在的关系问题", "政治和经济的关系问题", "实践和理论的关系问题");
if(i === -1){
toast("猜一下呗");
continue;
}
if(i === 1){
toast("答对辣");
break;
}else{
toast("答错辣")
}
}

View File

@@ -0,0 +1,4 @@
var name = rawInput("请输入名字");
alert("(•́へ•́╬)", "你好~ " + name);
var expr = dialogs.input("请输入简单的算式", "1+1");
alert("计算结果为 " + expr);

View File

@@ -0,0 +1,106 @@
// noinspection BadExpressionStatementJS,JSXNamespaceValidation
'ui';
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(<vertical focusable="true" clickable="true" gravity="top" marginTop="10">
<vertical marginTop="16">
<input id="input" lines="1" layout_weight="1" gravity="center"/>
</vertical>
<scroll>
<vertical margin="0 16" id="info"/>
</scroll>
</vertical>);
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(<vertical>
<text id="text" size="16" gravity="center"/>
</vertical>);
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(<vertical>
<text id="text" marginBottom="10" gravity="center"/>
</vertical>);
// e.g. versionCode -> Version Code
// e.g. platformVersion -> Platform Version
let prop = key.replace(/^([a-z]+)(([A-Z][a-z]+)*)$/, ($, $1, $2) => /* @AXR */ (
StringUtils.toUpperCaseFirst($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(<vertical>
<vertical id="line" height="2" margin="0 12"/>
</vertical>);
splitLineView['line'].setBackgroundColor(_.colors.splitLine);
ui['info'].addView(splitLineView);
},
};
$.show();

View File

@@ -0,0 +1,24 @@
let str = 'HIM';
let morse = util.morseCode(str);
// The input string is not case-sensitive.
// zh-CN: 输入字符串不区分大小写.
console.log(`string: ${str}`);
// 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: 可调用 vibrate() 方法使设备按摩斯电码模式振动.
// morse.vibrate();
console.launch();

View File

@@ -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();

View File

@@ -0,0 +1,67 @@
"ui";
/**
* By Da Zhang
* 本脚本仅为娱乐,没有任何破坏性质
*/
ui.statusBarColor("#AA0000");
var Quin = 32552732;
ui.layout(
<frame background="#AA0000">
<vertical align="top" paddingTop="5" margin="10">
<text id="oops" color="#FFFFFF" gravity="center" size="20">Oops, your files have been encrypted!</text>
<text id="text" bg="#FFFFFF" gravity="left" color="#000000" size="15" marginTop="15" h="425"></text>
<button id="payment" text="Payment" margin="20 0 0 0"/>
<button id="decrypt" text="Decrypt"/>
</vertical>
</frame>
);
ui.text.text("我的手机出了什么问题?\n您的一些重要文件被我加密保存了。\n" +
"照片、图片、文档、压缩包、音频、视频文件、apk文件等几乎所有类型的文件都被加密了因此不能正常打开。\n" +
"这和一般文件损坏有本质上的区别。您大可在网上找找恢复文件的方法,我敢保证,没有我们的解密服务,就算老天爷来了也不能恢复这些文档。\n\n" +
"有没有恢复这些文档的方法?\n当然有可恢复的方法。只能通过我们的解密服务才能恢复。我以人格担保能够提供安全有效的恢复服务。\n" +
"但这是收费的,也不能无限期的推迟。\n请点击 <Decrypt> 按钮,就可以免费恢复一些文档。请您放心,我是绝不会骗你的。\n" +
"但想要恢复全部文档,需要付款点费用。\n是否随时都可以固定金额付款就会恢复的吗当然不是推迟付款时间越长对你不利。\n" +
"最好3天之内付款费用过了三天费用就会翻倍。\n还有一个礼拜之内未付款将会永远恢复不了。\n" +
"对了,忘了告诉你,对半年以上没钱付款的穷人,会有活动免费恢复,能否轮到你,就要看您的运气怎么样了。");
ui.oops.click(() => toast("Fuck you!"));
ui.oops.longClick(() => {
var thisjoke="This is a joke : )";
if(ui.oops.text() !== thisjoke){
ui.oops.text(thisjoke);
}else{
ui.oops.text("Oops, your files have been encrypted!");
}
return true;
});
ui.text.click(() => ui.text.append("。"));
ui.text.longClick(() => {
ui.text.setText("\n"+ui.text.getText())
return true;
});
ui.payment.click(() => {
try{
app.startActivity({
action:"android.intent.action.VIEW",
data:"mqqapi://card/show_pslcard?&uin=" + Quin
});
toast("Please payment by QQ");
}catch(e){
toast("Payment Error");
}
});
ui.payment.longClick(() => {
toast("You are silly b!");
return true;
});
ui.decrypt.click(() => {
toast("Decrypt Error");
activity.finish();
});
ui.decrypt.longClick(() => {
toast("You can't decrypt!");
return true;
});

View File

@@ -0,0 +1,84 @@
'ui';
( /* @IIFE(registerIconView) */ () => {
// 继承 ui.Widget
util.extend(IconView, ui.Widget);
/**
* @constructor
* @extends Internal.UI.Widget
*/
function IconView() {
// 调用父类构造函数
ui.Widget.call(this);
// 自定义属性 packageName
this.defineAttr('packageName', () => {
return this._icon || null;
}, (view, name, value) => {
this._icon = iconMap[value /* as packageName */];
view.setImageDrawable(this._icon);
});
}
IconView.prototype.render = function () {
return '<img/>';
};
ui.registerWidget('iconLoader', IconView);
})();
ui.layout(
<vertical bg="#ffffff">
<list id="apps" layout_weight="1">
<linear bg="?selectableItemBackground" w="*" gravity="center_vertical" marginRight="16">
<iconLoader packageName="{{this.packageName}}" w="50" h="70" margin="16"/>
<vertical>
<text id="name" textSize="16sp" textColor="#000000" text="{{this.appName}}" maxLines="1" ellipsize="middle"/>
<text id="path" textSize="13sp" textColor="#929292" text="{{this.packageName}}" maxLines="2" marginTop="3"/>
</vertical>
</linear>
</list>
<progressbar id="progressbar" indeterminate="true" style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"/>
</vertical>,
);
let appList = [];
let iconMap = {};
ui.apps.setDataSource(appList);
ui.apps.on('item_click', item => {
new com.afollestad.materialdialogs.MaterialDialog.Builder(context).limitIconToDefaultSize()
dialogs.build({
title: '应用信息',
icon: item.icon,
content: `名称: ${item.appName}\n`
+ `包名: ${item.packageName}\n`
+ `版本: ${item.versionName}\n`
+ `版本号: ${item.versionCode}`,
positive: '返回',
limitIconToDefaultSize: true,
}).show();
});
// 启动线程扫描应用程序
threads.start(function () {
listApps(appList);
ui.run(() => ui.progressbar.setVisibility(android.view.View.GONE));
});
function listApps(appList) {
let pm = context.getPackageManager();
let appPackageList = pm.getInstalledPackages(0);
for (let i = 0; i < appPackageList.size(); i++) {
let p = appPackageList.get(i);
let icon = p.applicationInfo.loadIcon(pm);
appList.push({
appName: p.applicationInfo.loadLabel(pm).toString(),
packageName: p.packageName,
versionName: p.versionName,
versionCode: p.versionCode,
icon,
});
iconMap[p.packageName] = icon;
}
}

View File

@@ -0,0 +1,122 @@
'ui';
ui.layout(
<frame>
<vertical>
<appbar>
<toolbar id="toolbar" title="Todo"/>
</appbar>
<button id="selectAll" text="全选"/>
<list id="todoList">
<card w="*" h="70" margin="10 5" cardCornerRadius="2dp"
cardElevation="1dp" foreground="?selectableItemBackground">
<horizontal gravity="center_vertical">
<View bg="{{this.color}}" h="*" w="10"/>
<vertical padding="10 8" h="auto" w="0" layout_weight="1">
<text id="title" text="{{this.title}}" textColor="#222222" textSize="16sp" maxLines="1"/>
<text text="{{this.summary}}" textColor="#999999" textSize="14sp" maxLines="1"/>
</vertical>
<checkbox id="done" marginLeft="4" marginRight="6" checked="{{this.done}}"/>
</horizontal>
</card>
</list>
</vertical>
<fab id="add" w="auto" h="auto" src="@drawable/ic_add_black_48dp"
margin="16" layout_gravity="bottom|right" tint="#ffffff"/>
</frame>,
);
let materialColors = [
'#e91e63', '#ab47bc', '#5c6bc0',
'#7e57c2', '#2196f3', '#00bcd4',
'#26a69a', '#4caf50', '#8bc34a',
'#ffeb3b', '#ffa726', '#78909c',
'#8d6e63',
];
let storage = storages.create('todoList');
// 从storage获取todo列表
let todoList = storage.get('items', [ {
title: '写操作系统作业',
summary: '明天第12节',
color: '#f44336',
done: false,
}, {
title: '给ui模式增加若干Bug',
summary: '无限期',
color: '#ff5722',
done: false,
}, {
title: '发布Auto.js 5.0.0正式版',
summary: '2019年1月',
color: '#4caf50',
done: false,
}, {
title: '完成毕业设计和论文',
summary: '2019年4月',
color: '#2196f3',
done: false,
} ]);
ui.todoList.setDataSource(todoList);
ui.selectAll.on('click', function () {
todoList.forEach(item => item.done = true);
// 通知数据全部更新
ui.todoList.adapter.notifyDataSetChanged();
});
ui.todoList.on('item_bind', function (itemView, itemHolder) {
// 绑定勾选框事件
itemView.done.on('check', function (checked) {
let item = itemHolder.item;
item.done = checked;
let paint = itemView.title.paint;
// 设置或取消中划线效果
if (checked) {
paint.flags |= Paint.STRIKE_THRU_TEXT_FLAG;
} else {
paint.flags &= ~Paint.STRIKE_THRU_TEXT_FLAG;
}
itemView.title.invalidate();
});
});
ui.todoList.on('item_click', function (item, i, itemView, listView) {
itemView.done.setChecked(!itemView.done.checked);
});
ui.todoList.on('item_long_click', function (e, item, i, itemView, listView) {
confirm('确定要删除' + item.title + '吗?')
.then(ok => {
if (ok) {
todoList.splice(i, 1);
}
});
e.consumed = true;
});
//当离开本界面时保存todoList
ui.emitter.on('pause', () => {
storage.put('items', todoList);
});
ui.add.on('click', () => {
dialogs.rawInput('请输入标题')
.then(title => {
if (!title) {
return;
}
dialogs.rawInput('请输入期限', '明天')
.then(summary => {
todoList.push({
title: title,
summary: summary,
color: materialColors[random(0, materialColors.length - 1)],
});
});
});
});

View File

@@ -0,0 +1,142 @@
'ui';
let themeColor = 'orange-800';
let materialColors = [
'amber-500',
'blue-500',
'blue-grey-500',
'brown-500',
'cyan-500',
'deep-orange-500',
'deep-purple-500',
'green-500',
'grey-500',
'indigo-500',
'light-blue-500',
'light-green-500',
'lime-500',
'orange-500',
'pink-500',
'purple-500',
'red-500',
'teal-500',
'yellow-500',
];
let storage = storages.create('todoList');
storage.clear();
ui.layout(
<frame>
<vertical>
<appbar>
<toolbar id="toolbar" title="TODO" />
</appbar>
<button id="selectAll" text="全部完成" isColored margin="6 4" />
<list id="todoList">
<card w="*" h="70" margin="10 5" cardCornerRadius="2dp"
cardElevation="1dp" foreground="?selectableItemBackground">
<horizontal gravity="center_vertical">
<view bg="{{this.color}}" h="*" w="10" />
<vertical padding="10 8" h="auto" w="0" layout_weight="1">
<text id="title" text="{{this.title}}" textColor="blue-grey-900" textSize="16sp" maxLines="1" paddingBottom="4dp" />
<text text="{{this.summary}}" textColor="blue-grey-300" textSize="14sp" maxLines="1" />
</vertical>
<checkbox id="done" marginLeft="4" marginRight="6" checked="{{this.done}}" tint="blue-grey-500,pink-300" />
</horizontal>
</card>
</list>
</vertical>
<fab id="add" w="auto" h="auto" src="@drawable/ic_add_black_48dp"
margin="16" layout_gravity="bottom|right" tint="white" backgroundTint="orange-800" />
</frame>,
);
// 从 storage 获取待办事项列表
let todoList = storage.get('items', [{
title: '写操作系统作业',
summary: '明天第 1 - 2 节',
color: 'red-500',
done: false,
}, {
title: '给 ui 模式增加若干 bug',
summary: '无限期',
color: 'orange-500',
done: false,
}, {
title: '发布 AutoJs6 v6.6.6',
summary: '2066 年 6 月',
color: 'teal-500',
done: false,
}, {
title: '完成 AutoJs6 文档撰写',
summary: '2031 年 5 月',
color: '#2196f3',
done: false,
}]);
ui.statusBarColor(themeColor);
ui['toolbar'].attr('bg', themeColor);
ui['selectAll'].attr('backgroundTint', 'pink-300');
ui['todoList'].setDataSource(todoList);
ui['selectAll'].on('click', function () {
todoList.forEach(item => {
item.done = true;
});
// 通知数据全部更新
ui['todoList'].adapter.notifyDataSetChanged();
});
ui['todoList'].on('item_bind', function (itemView, itemHolder) {
// 绑定勾选框事件
itemView.done.on('check', function (checked) {
let item = itemHolder.item;
item.done = checked;
let paint = itemView.title.paint;
// 设置或取消中划线效果
if (checked) {
paint.flags |= Paint.STRIKE_THRU_TEXT_FLAG;
} else {
paint.flags &= ~Paint.STRIKE_THRU_TEXT_FLAG;
}
itemView.title.invalidate();
});
});
ui['todoList'].on('item_click', function (item, i, itemView) {
itemView.done.checked = !itemView.done.checked;
});
ui['todoList'].on('item_long_click', function (e, item, i) {
confirm(`确定要删除 "${item.title}" 吗?`)
.then(ok => {
if (ok) {
todoList.splice(i, 1);
}
});
e.consumed = true;
});
// 当离开本界面时保存 todoList
ui.emitter.on('pause', () => storage.put('items', todoList));
ui['add'].on('click', () => {
dialogs.rawInput('请输入标题')
.then((title) => {
if (!title) {
return;
}
dialogs.rawInput('请输入期限', '明天')
.then(summary => {
todoList.push({
title: title,
summary: summary,
color: materialColors[random(0, materialColors.length - 1)],
});
});
});
});

View File

@@ -0,0 +1,16 @@
'ui';
ui.layout(<vertical>
<viewswitcher id="vs">
<text size="52" gravity="center" margin="20" color="dark-green">HELLO</text>
<text size="52" gravity="center" margin="20" color="dark-red">WORLD</text>
</viewswitcher>
<button id="btn" text="switch view"/>
</vertical>);
/** @type {JsButton} */
let btnView = ui['btn'];
/** @type {JsViewSwitcher} */
let viewSwitcher = ui['vs'];
btnView.on('click', () => viewSwitcher.showNext());

View File

@@ -0,0 +1,43 @@
'ui';
/* 如需使用本地视频文件作为播放源, 可使用相对路径, 如 src="./video/sample.mp4". */
/* controller 属性用于显示 android 内置的简单控制器视图, 点击视频区域可弹出控制器. */
ui.layout(<vertical>
<video id="video" src="@raw/text_tool" controller></video>
<button id="video_btn" text="play" isColored bg="teal-600" />
</vertical>);
/** @type {JsButton} */
let videoBtnView = ui['video_btn'];
/** @type {JsVideoView} */
let videoView = ui['video'];
videoBtnView.on('click', () => {
if (videoView.isPlaying()) {
videoView.pause();
setStatePaused();
} else {
videoView.start();
setStatePlaying();
}
});
videoView.setOnCompletionListener({
onCompletion(mediaPlayer) {
mediaPlayer.reset();
videoView.attrReset('path');
setStatePaused();
},
});
function setStatePaused() {
videoBtnView.attr('text', 'play');
videoBtnView.attr('bg', 'teal-600');
}
function setStatePlaying() {
videoBtnView.attr('text', 'pause');
videoBtnView.attr('bg', 'blue-800');
}

View File

@@ -0,0 +1,54 @@
"ui";
ui.layout(
<vertical>
<text textSize="18sp" textColor="#000000" margin="20" textStyle="bold">
关于Auto.js的用户调查
</text>
<ScrollView>
<vertical>
<text textSize="16sp" margin="8">1. 您的年龄是?</text>
<input text="18" inputType="number" margin="0 16"/>
<text textSize="16sp" margin="8">2. 您用过其他类似软件(脚本精灵按键精灵等)?</text>
<radiogroup margin="0 16">
<radio text="没有用过"/>
<radio text="用过"/>
<radio text="用过,感觉不好用"/>
<radio text="没有Root权限无法使用"/>
</radiogroup>
<text textSize="16sp" margin="8">3. 您使用Auto.js通常用于做什么?(多选)</text>
<checkbox text="游戏辅助" marginLeft="16"/>
<checkbox text="点赞" marginLeft="16"/>
<checkbox text="日常生活工作辅助" marginLeft="16"/>
<checkbox text="练习编程" marginLeft="16"/>
<checkbox text="自动化测试" marginLeft="16"/>
<linear>
<checkbox text="其他" marginLeft="16"/>
<input w="*" margin="0 16"/>
</linear>
<text textSize="16sp" margin="8">4. 您更喜欢以下哪个图标?</text>
<radiogroup margin="0 16">
<radio/>
<img w="100" h="100" margin="0 16" src="http://www.autojs.org/assets/uploads/profile/3-profileavatar.png"/>
<radio/>
<img w="100" h="100" margin="0 16" src="http://www.autojs.org/assets/uploads/files/1511945512596-autojs_logo.png"/>
</radiogroup>
<text textSize="16sp" margin="8">5. 您是什么时候开始使用Auto.js的呢?</text>
<datepicker margin="4 16" datePickerMode="spinner"/>
<text textSize="16sp" margin="8">6. 您用过下面这个Auto.js的论坛吗?</text>
<webview id="webview" h="300" margin="0 16"/>
<radiogroup marginLeft="16" marginTop="16">
<radio text="没有用过"/>
<radio text="用过"/>
<radio text="用过,感觉不好用"/>
</radiogroup>
<linear gravity="center">
<button margin="16">提交</button>
<button margin="16">放弃</button>
</linear>
</vertical>
</ScrollView>
</vertical>
)
ui.webview.loadUrl("http://www.autojs.org");

View File

@@ -0,0 +1,89 @@
"ui";
var color = "#009688";
ui.layout(
<drawer id="drawer">
<vertical>
<appbar>
<toolbar id="toolbar" title="示例"/>
<tabs id="tabs"/>
</appbar>
<viewpager id="viewpager">
<frame>
<text text="第一页内容" textColor="black" textSize="16sp"/>
</frame>
<frame>
<text text="第二页内容" textColor="red" textSize="16sp"/>
</frame>
<frame>
<text text="第三页内容" textColor="green" textSize="16sp"/>
</frame>
</viewpager>
</vertical>
<vertical layout_gravity="left" bg="#ffffff" w="280">
<img w="280" h="200" scaleType="fitXY" src="http://images.shejidaren.com/wp-content/uploads/2014/10/023746fki.jpg"/>
<list id="menu">
<horizontal bg="?selectableItemBackground" w="*">
<img w="50" h="50" padding="16" src="{{this.icon}}" tint="{{color}}"/>
<text textColor="black" textSize="15sp" text="{{this.title}}" layout_gravity="center"/>
</horizontal>
</list>
</vertical>
</drawer>
);
//创建选项菜单(右上角)
ui.emitter.on("create_options_menu", menu=>{
menu.add("设置");
menu.add("关于");
});
//监听选项菜单点击
ui.emitter.on("options_item_selected", (e, item)=>{
switch(item.getTitle()){
case "设置":
toast("还没有设置");
break;
case "关于":
alert("关于", "Auto.js界面模板 v1.0.0");
break;
}
e.consumed = true;
});
activity.setSupportActionBar(ui.toolbar);
//设置滑动页面的标题
ui.viewpager.setTitles(["标签一", "标签二", "标签三"]);
//让滑动页面和标签栏联动
ui.tabs.setupWithViewPager(ui.viewpager);
//让工具栏左上角可以打开侧拉菜单
ui.toolbar.setupWithDrawer(ui.drawer);
ui.menu.setDataSource([
{
title: "选项一",
icon: "@drawable/ic_android_black_48dp"
},
{
title: "选项二",
icon: "@drawable/ic_settings_black_48dp"
},
{
title: "选项三",
icon: "@drawable/ic_favorite_black_48dp"
},
{
title: "退出",
icon: "@drawable/ic_exit_to_app_black_48dp"
}
]);
ui.menu.on("item_click", item => {
switch(item.title){
case "退出":
ui.finish();
break;
}
})

View File

@@ -0,0 +1,58 @@
"ui";
showLoginUI();
ui.statusBarColor("#000000")
//显示登录界面
function showLoginUI(){
ui.layout(
<frame>
<vertical h="auto" align="center" margin="0 50">
<linear>
<text w="56" gravity="center" color="#111111" size="16">用户名</text>
<input id="name" w="*" h="40"/>
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">密码</text>
<input id="password" w="*" h="40" password="true"/>
</linear>
<linear gravity="center">
<button id="login" text="登录"/>
<button id="register" text="注册"/>
</linear>
</vertical>
</frame>
);
ui.login.on("click", () => {
toast("您输入的用户名为" + ui.name.text() + " 密码为" + ui.password.text());
});
ui.register.on("click", () => showRegisterUI());
}
//显示注册界面
function showRegisterUI(){
ui.layout(
<frame>
<vertical h="auto" align="center" margin="0 50">
<linear>
<text w="56" gravity="center" color="#111111" size="16">用户名</text>
<input w="*" h="40"/>
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">密码</text>
<input w="*" h="40" password="true"/>
</linear>
<linear>
<text w="56" gravity="center" color="#111111" size="16">邮箱</text>
<input w="*" h="40" inputType="textEmailAddress"/>
</linear>
<linear gravity="center">
<button>确定</button>
<button id="cancel">取消</button>
</linear>
</vertical>
</frame>
);
ui.cancel.on("click", () => showLoginUI());
}

View File

@@ -0,0 +1,34 @@
'ui';
const themeColor = Color(autojs.themeColor);
const colorRelativeRate = 1.8;
ui.layout(
<org.autojs.autojs.core.ui.widget.JsTextClock
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text_clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:format24Hour="HH:mm"
android:textSize="36sp"/>,
);
/* 1 秒钟后应用自定义样式. */
setTimeout(() => {
ui.statusBarColor(themeColor);
ui.backgroundColor(
Color(themeColor)
.setRedRelative(colorRelativeRate)
.setGreenRelative(colorRelativeRate)
.setBlueRelative(colorRelativeRate)
.toInt(),
);
/** @type {JsTextClock} */
let textClockView = ui.text_clock;
textClockView.attr('color', themeColor.toInt());
textClockView.attr('size', '56');
textClockView.attr('layout_gravity', 'center');
textClockView.attr('format24Hour', 'HH:mm:ss');
}, 1e3);

View File

@@ -0,0 +1,10 @@
/**
* @type {string}
*/
let appName = dialogs.rawInput('请输入要卸载的应用名称');
let packageName = app.getPackageName(appName);
if (!packageName) {
toast(`应用 "${appName}" 不存在`);
} else {
app.uninstall(packageName);
}

View File

@@ -0,0 +1,31 @@
var i = dialogs.select("请选择工具", "获取应用包名", "打开应用详情页", "卸载应用");
if(i === -1){
alert("没有选择任何工具!");
}
switch(i){
case 0:
//获取应用包名
appName = rawInput("请输入应用名称", "QQ");
packageName = getPackageName(appName);
toast(packageName);
setClip(packageName);
toast("已复制到剪贴板");
break;
case 1:
//打开应用详情页
appName = rawInput("请输入应用名称", "微信");
launchSettings(getPackageName(appName));
break;
case 2:
//卸载应用
appName = rawInput("请输入应用名称");
packageName = getPackageName(appName);
if(packageName === ""){
toast("应用不存在");
}else if(confirm("确定卸载应用" + packageName + "吗?")){
app.uninstall(packageName);
}
break;
}

View File

@@ -0,0 +1,5 @@
"auto";
var appName = rawInput("请输入应用名称");
launchSettings(getPackageName(appName));
while(!click("强制停止"));

View File

@@ -0,0 +1,11 @@
App.QQ.ensureInstalled();
let content = rawInput('请输入要分享的文本');
content && app.startActivity({
action: 'android.intent.action.SEND',
type: 'text/*',
extras: { 'android.intent.extra.TEXT': content },
packageName: App.QQ.getPackageName(),
className: '@{packageName}.activity.JumpActivity',
});

View File

@@ -0,0 +1,11 @@
App.WECHAT.ensureInstalled();
let content = rawInput('请输入要分享的文本');
content && app.startActivity({
action: 'android.intent.action.SEND',
type: 'text/*',
extras: { 'android.intent.extra.TEXT': content },
packageName: App.WECHAT.getPackageName(),
className: '@{packageName}.ui.tools.ShareImgUI',
});

View File

@@ -0,0 +1,56 @@
// noinspection BadExpressionStatementJS,SpellCheckingInspection
App.ALIPAY.ensureInstalled();
/* 相对简单的情况 */
// 使用 data 选项参数
0 && app.startActivity({
data: 'alipays://platformapi/startapp?appId=60000002',
packageName: App.ALIPAY.getPackageName(),
});
// 使用 url 选项参数
1 && app.startActivity({
url: {
src: 'alipays://platformapi/startapp',
query: { appId: '60000002' },
},
packageName: App.ALIPAY.getPackageName(),
});
/* 相对复杂的情况 */
// 使用 data 选项参数
0 && app.startActivity({
data: 'alipays://platformapi/startapp?appId=20000067&url=https://60000002.h5app.alipay.com/www/listRank.html?conf=%255B%2522totalRank%2522%255D&__webview_options__=&transparentTitle=none&backgroundColor=-1&canPullDown=NO&backBehavior=back&enableCubeView=NO&startMultApp=YES&showOptionMenu=YES&enableScrollBar=NO&closeCurrentWindow=YES&readTitle=NO&defaultTitle=Reserved',
packageName: App.ALIPAY.getPackageName(),
});
// 使用 url 选项参数
0 && app.startActivity({
url: {
src: 'alipays://platformapi/startapp',
query: {
appId: 20000067,
url: {
src: 'https://60000002.h5app.alipay.com/www/listRank.html',
query: { conf: '["totalRank"]' },
},
__webview_options__: {
transparentTitle: 'none',
backgroundColor: -1,
canPullDown: 'NO',
backBehavior: 'back',
enableCubeView: 'NO',
startMultApp: 'YES',
showOptionMenu: 'YES',
enableScrollBar: 'NO',
closeCurrentWindow: 'YES',
readTitle: 'NO',
defaultTitle: 'Reserved',
},
},
},
packageName: App.ALIPAY.getPackageName(),
});

View File

@@ -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'));

View File

@@ -0,0 +1,2 @@
var appName = rawInput("请输入应用名称");
launchApp(appName);

View File

@@ -0,0 +1,26 @@
"ui";
ui.layout(
<vertical padding="16">
<horizontal>
<text textSize="16sp">下拉菜单</text>
<spinner id="sp1" entries="选项1|选项2|选项3"/>
</horizontal>
<horizontal>
<text textSize="16sp">对话框菜单</text>
<spinner id="sp2" entries="选项4|选项5|选项6" spinnerMode="dialog"/>
</horizontal>
<button id="ok">确定</button>
<button id="select3">选择选项3</button>
</vertical>
);
ui.ok.on("click", ()=>{
var i = ui.sp1.getSelectedItemPosition();
var j = ui.sp2.getSelectedItemPosition();
toast("您的选择是选项" + (i + 1) + "和选项" + (j + 4));
});
ui.select3.on("click", ()=>{
ui.sp1.setSelection(2);
});

View File

@@ -0,0 +1,42 @@
"ui";
ui.layout(
<frame>
<list id="list">
<vertical>
<text id="name" textSize="16sp" textColor="#000000" text="姓名: {{name}}"/>
<text id="age" textSize="16sp" textColor="#000000" text="年龄: {{age}}岁"/>
<button id="deleteItem" text="删除"/>
</vertical>
</list>
</frame>
);
var items = [
{name: "小明", age: 18}, {name: "小红", age: 30},
{name: "小东", age: 19}, {name: "小强", age: 31},
{name: "小满", age: 20}, {name: "小一", age: 32},
{name: "小和", age: 21}, {name: "小二", age: 1},
{name: "小贤", age: 22}, {name: "小三", age: 2},
{name: "小伟", age: 23}, {name: "小四", age: 3},
{name: "小黄", age: 24}, {name: "小五", age: 4},
{name: "小健", age: 25}, {name: "小六", age: 5},
{name: "小啦", age: 26}, {name: "小七", age: 6},
{name: "小哈", age: 27}, {name: "小八", age: 7},
{name: "小啊", age: 28}, {name: "小九", age: 8},
{name: "小啪", age: 29}, {name: "小十", age: 9}
];
ui.list.setDataSource(items);
ui.list.on("item_click", function(item, i, itemView, listView){
toast("被点击的人名字为: " + item.name + ",年龄为: " + item.age);
});
ui.list.on("item_bind", function(itemView, itemHolder){
itemView.deleteItem.on("click", function(){
let item = itemHolder.item;
toast("被删除的人名字为: " + item.name + ",年龄为: " + item.age);
items.splice(itemHolder.position, 1);
});
})

View File

@@ -0,0 +1,42 @@
"ui";
ui.layout(
<vertical>
<appbar>
<toolbar id="toolbar" title="卡片布局"/>
</appbar>
<card w="*" h="70" margin="10 5" cardCornerRadius="2dp"
cardElevation="1dp" gravity="center_vertical">
<vertical padding="18 8" h="auto">
<text text="写操作系统作业" textColor="#222222" textSize="16sp"/>
<text text="明天第12节" textColor="#999999" textSize="14sp"/>
</vertical>
<View bg="#f44336" h="*" w="10"/>
</card>
<card w="*" h="70" margin="10 5" cardCornerRadius="2dp"
cardElevation="1dp" gravity="center_vertical">
<vertical padding="18 8" h="auto">
<text text="修复ui模式的Bug" textColor="#222222" textSize="16sp"/>
<text text="无限期" textColor="#999999" textSize="14sp"/>
</vertical>
<View bg="#ff5722" h="*" w="10"/>
</card>
<card w="*" h="70" margin="10 5" cardCornerRadius="2dp"
cardElevation="1dp" gravity="center_vertical">
<vertical padding="18 8" h="auto">
<text text="发布Auto.js 10.0.0正式版" textColor="#222222" textSize="16sp"/>
<text text="2019年1月" textColor="#999999" textSize="14sp"/>
</vertical>
<View bg="#4caf50" h="*" w="10"/>
</card>
<card w="*" h="70" margin="10 5" cardCornerRadius="2dp"
cardElevation="1dp" gravity="center_vertical">
<vertical padding="18 8" h="auto">
<text text="完成毕业设计和论文" textColor="#222222" textSize="16sp"/>
<text text="2019年4月" textColor="#999999" textSize="14sp"/>
</vertical>
<View bg="#2196f3" h="*" w="10"/>
</card>
</vertical>
);

View File

@@ -0,0 +1,32 @@
"ui";
ui.layout(
<scroll>
<vertical bg="#707070" padding="16">
<text text="网络图片" textColor="black" textSize="16sp" marginTop="16"/>
<img src="http://www.autojs.org/assets/uploads/profile/3-profileavatar.png"
w="100" h="100"/>
<text text="带边框的图片" textColor="black" textSize="16sp" marginTop="16"/>
<img src="http://www.autojs.org/assets/uploads/profile/1-profileavatar.jpeg"
w="100" h="100" borderWidth="2dp" borderColor="#202020"/>
<text text="圆形图片" textColor="black" textSize="16sp" marginTop="16"/>
<img src="http://www.autojs.org/assets/uploads/profile/1-profileavatar.jpeg"
w="100" h="100" circle="true"/>
<text text="带边框的圆形图片" textColor="black" textSize="16sp" marginTop="16"/>
<img src="http://www.autojs.org/assets/uploads/profile/1-profileavatar.jpeg"
w="100" h="100" circle="true" borderWidth="2dp" borderColor="#202020"/>
<text text="圆角图片" textColor="black" textSize="16sp" marginTop="16"/>
<img id="rounded_img" src="http://www.autojs.org/assets/uploads/profile/1-profileavatar.jpeg"
w="100" h="100" radius="20dp" scaleType="fitXY"/>
<button id="change_img" text="更改图片"/>
</vertical>
</scroll>
);
ui.change_img.on("click", ()=>{
ui.rounded_img.setSource("http://www.autojs.org/assets/uploads/profile/1-profilecover.jpeg");
});

View File

@@ -0,0 +1,27 @@
"ui";
ui.layout(
<vertical padding="16">
<checkbox id="cb1" text="复选框"/>
<checkbox id="cb2" checked="true" text="勾选的复选框"/>
<radiogroup marginTop="16">
<radio text="单选框1"/>
<radio text="单选框2"/>
<radio text="单选框3"/>
</radiogroup>
<radiogroup marginTop="16">
<radio text="单选框1"/>
<radio text="单选框2"/>
<radio text="勾选的单选框3" checked="true"/>
</radiogroup>
</vertical>
);
ui.cb1.on("check", (checked)=>{
if(checked){
toast("第一个框被勾选了");
}else{
toast("第一个框被取消勾选了");
}
});

View File

@@ -0,0 +1,24 @@
'ui';
ui.layout(<vertical gravity="center">
<horizontal width="-1" gravity="center" margin="16">
<text text="滑块单色/轨道单色" size="16" marginEnd="32"/>
<switch checked="false" thumbTint="orange-800" trackTint="orange-200" marginEnd="16"></switch>
<switch checked="true" thumbTint="orange-800" trackTint="orange-200"></switch>
</horizontal>
<horizontal width="-1" gravity="center" margin="16">
<text text="滑块单色/轨道双色" size="16" marginEnd="32"/>
<switch checked="false" thumbTint="orange-800" trackTint="light-gray/orange-200" marginEnd="16"></switch>
<switch checked="true" thumbTint="orange-800" trackTint="light-gray/orange-200"></switch>
</horizontal>
<horizontal width="-1" gravity="center" margin="16">
<text text="滑块双色/轨道单色" size="16" marginEnd="32"/>
<switch checked="false" thumbTint="gray/orange-800" trackTint="light-gray" marginEnd="16"></switch>
<switch checked="true" thumbTint="gray/orange-800" trackTint="light-gray"></switch>
</horizontal>
<horizontal width="-1" gravity="center" margin="16">
<text text="滑块双色/轨道双色" size="16" marginEnd="32"/>
<switch checked="false" thumbTint="gray/orange-800" trackTint="light-gray/orange-200" marginEnd="16"></switch>
<switch checked="true" thumbTint="gray/orange-800" trackTint="light-gray/orange-200"></switch>
</horizontal>
</vertical>);

View File

@@ -0,0 +1,20 @@
"ui";
ui.layout(
<vertical padding="16">
<button text="普通按钮" w="auto"/>
<button text="带颜色按钮" style="Widget.AppCompat.Button.Colored" w="auto"/>
<button text="无边框按钮" style="Widget.AppCompat.Button.Borderless" w="auto"/>
<button text="无边框有颜色按钮" style="Widget.AppCompat.Button.Borderless.Colored" w="auto"/>
<button text="长长的按钮" w="*"/>
<button id="click_me" text="点我" w="auto"/>
</vertical>
);
ui.click_me.on("click", ()=>{
toast("我被点啦");
});
ui.click_me.on("long_click", ()=>{
toast("我被长按啦");
});

View File

@@ -0,0 +1,16 @@
"ui";
ui.layout(
<vertical padding="16">
<text textSize="40sp">大字</text>
<text textSize="12sp">小字</text>
<text textStyle="bold" textColor="black">加粗</text>
<text textStyle="italic">斜体</text>
<text textColor="#00ff00">原谅色</text>
<text margin="8">Android是一种基于Linux的自由及开放源代码的操作系统主要使用于移动设备如智能手机和平板电脑由Google公司和开放手机联盟领导及开发尚未有统一中文名称中国大陆地区较多人使用安卓安致Android操作系统最初由Andy Rubin开发主要支持手机2005年8月由Google收购注资2007年11月Google与84家硬件制造商软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统</text>
<text maxLines="1" ellipsize="end" margin="8">Android是一种基于Linux的自由及开放源代码的操作系统主要使用于移动设备如智能手机和平板电脑由Google公司和开放手机联盟领导及开发尚未有统一中文名称中国大陆地区较多人使用安卓安致Android操作系统最初由Andy Rubin开发主要支持手机2005年8月由Google收购注资2007年11月Google与84家硬件制造商软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统</text>
<text maxLines="2" ellipsize="end" margin="8">Android是一种基于Linux的自由及开放源代码的操作系统主要使用于移动设备如智能手机和平板电脑由Google公司和开放手机联盟领导及开发尚未有统一中文名称中国大陆地区较多人使用安卓安致Android操作系统最初由Andy Rubin开发主要支持手机2005年8月由Google收购注资2007年11月Google与84家硬件制造商软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统</text>
<text w="*" gravity="center" textSize="20sp">居中</text>
<text autoLink="all">自动超链接网址www.baidu.com, 邮箱 123@qq.com等</text>
</vertical>
);

View File

@@ -0,0 +1,20 @@
"ui";
ui.layout(
<scroll>
<vertical padding="16">
<text text="日历样式日期选择" textColor="black" textSize="16sp" marginTop="16"/>
<datepicker />
<text text="滑动日期选择" textColor="black" textSize="16sp" marginTop="16"/>
<datepicker datePickerMode="spinner"/>
<text text="时钟样式时间选择" textColor="black" textSize="16sp" marginTop="16"/>
<timepicker />
<text text="滑动时间选择" textColor="black" textSize="16sp" marginTop="16"/>
<timepicker timePickerMode="spinner"/>
</vertical>
</scroll>
)

View File

@@ -0,0 +1,18 @@
"ui";
var PrefCheckBox = require('./自定义控件-模块-配置勾选框.js');
ui.layout(
<vertical>
<pref-checkbox id="perf1" text="配置1"/>
<pref-checkbox id="perf2" text="配置2"/>
<button id="btn" text="获取配置"/>
</vertical>
);
ui.btn.on("click", function(){
toast("配置1为" + PrefCheckBox.getPref().get("perf1"));
toast("配置2为" + PrefCheckBox.getPref().get("perf2"));
});

Some files were not shown because too many files have changed in this diff Show More