02_auto.jsの基本操作 3/4
コンソール
ログを保存する
console. setGlobalLogConfig ( {
file : "/sdcard/log.txt"
} ) ;
console. log ( 1 ) ;
console. log ( 2 ) ;
console. error ( 3 ) ;
app. viewFile ( "/sdcard/log.txt" ) ;
乱数を生成する
console. show ( ) ;
log ( "将产生5个1到100的随机数" ) ;
for ( let i = 0 ; i < 5 ; i++ ) {
print ( random ( 1 , 100 ) ) ;
print ( " " ) ;
sleep ( 400 ) ;
}
print ( "\n" ) ;
log ( "将产生10个1到20的不重复随机数" ) ;
var exists = {
} ;
for ( let i = 0 ; i < 10 ; i++ ) {
var r;
do {
r = random ( 1 , 20 ) ;
} while ( exists[ r] ) ;
exists[ r] = true ;
print ( r + " " ) ;
sleep ( 400 ) ;
}
コンソールのサイズと位置を調整する
console. show ( true ) ;
console. log ( "运行结束自动关闭" ) ;
console. log ( "调整大小..." ) ;
console. setSize ( 1000 , 1000 ) ;
sleep ( 2000 ) ;
console. log ( "调整位置..." ) ;
console. setPosition ( 0 , 500 ) ;
sleep ( 2000 ) ;
フォーマットされた出力
console. show ( ) ;
var i = {
name : "小明" ,
age : 18 ,
height : 1.72
} ;
console. log ( "大家好, 我叫%s, 今年%d岁, 身高%d米" , i. name, i. age, i. height) ;
console. log ( "实际上我是一个对象啦,长这样子: %j" , i) ;
コンソールの例
console. show ( ) ;
console. verbose ( "这是灰色" ) ;
console. log ( "这是黑色" ) ;
console. info ( "这是红色" ) ;
console. warn ( "这是蓝色" ) ;
console. error ( "这是绿色=_=" ) ;
hey ( ) ;
function hey ( ) {
console. trace ( "打印日志行数" ) ;
}
ログに表示される最大行数を設定します。
console. show ( false ) ;
console. setMaxLines ( 10 ) ;
var i= 0 ;
while ( true ) {
console. log ( i)
i++ ;
sleep ( 500 ) ;
}
コンソールインターフェースを変更する
function myrandom ( min, max ) {
return Math. floor ( Math. random ( ) * ( max - min + 1 ) ) + min;
}
threads. start ( function ( ) {
console. show ( ) ;
console. setTitle ( "中文" , "#ff11ee00" , 30 ) ;
console. setCanInput ( false ) ;
var i= 0 ;
do {
console. setLogSize ( myrandom ( 4 , 20 ) ) ;
console. setBackgroud ( "#33ef0000" ) ;
console. setCanInput ( i% 2 == 0 ) ;
i++ ;
console. log ( "i----->" + i) ;
sleep ( 3000 ) ;
} while ( true ) ;
} ) ;
ターミナルエミュレータ
var sh = new Shell ( ) ;
sh. setCallback ( {
onOutput : function ( str ) {
print ( str) ;
}
} )
console. show ( ) ;
do {
var cmd = console. rawInput ( ) ;
sh. exec ( cmd) ;
} while ( cmd != "exit" ) ;
sh. exit ( ) ;
設備・機器情報
デバイスの明るさを調整する
"ui" ;
ui. layout (
< vertical padding= "16" >
< checkbox id= "auto" text= "自动亮度" / >
< text textColor= "black" textSize= "16sp" margin= "8" > 亮度< / text>
< seekbar id= "brightness" max= "100" / >
< / vertical>
) ;
ui. auto. setChecked ( device. getBrightnessMode ( ) == 1 ) ;
ui. auto. setOnCheckedChangeListener ( function ( v, checked ) {
device. setBrightnessMode ( checked ? 1 : 0 ) ;
} ) ;
ui. brightness. setProgress ( device. getBrightness ( ) ) ;
ui. brightness. setOnSeekBarChangeListener ( {
onProgressChanged : function ( seekbar, p, fromUser ) {
if ( fromUser) {
device. setBrightness ( p) ;
}
}
} ) ;
デバイスの音量を調整する
"ui" ;
ui. layout (
< vertical padding= "16" >
< text textColor= "black" textSize= "16sp" > 媒体音量< / text>
< seekbar id= "music" / >
< text textColor= "black" textSize= "16sp" > 通知音量< / text>
< seekbar id= "notification" / >
< text textColor= "black" textSize= "16sp" > 闹钟音量< / text>
< seekbar id= "alarm" / >
< / vertical>
) ;
ui. music. setMax ( device. getMusicMaxVolume ( ) ) ;
ui. music. setProgress ( device. getMusicVolume ( ) ) ;
ui. music. setOnSeekBarChangeListener ( {
onProgressChanged : function ( seekbar, p, fromUser ) {
if ( fromUser) {
device. setMusicVolume ( p) ;
}
}
} ) ;
ui. notification. setMax ( device. getNotificationMaxVolume ( ) ) ;
ui. notification. setProgress ( device. getAlarmVolume ( ) ) ;
ui. notification. setOnSeekBarChangeListener ( {
onProgressChanged : function ( seekbar, p, fromUser ) {
if ( fromUser) {
device. setNotificationVolume ( p) ;
}
}
} ) ;
ui. alarm. setMax ( device. getAlarmMaxVolume ( ) ) ;
ui. alarm. setProgress ( device. getAlarmVolume ( ) ) ;
ui. alarm. setOnSeekBarChangeListener ( {
onProgressChanged : function ( seekbar, p, fromUser ) {
if ( fromUser) {
device. setAlarmVolume ( p) ;
}
}
} ) ;
デバイス情報を取得する
console. show ( ) ;
var str = "" ;
str += "屏幕宽度:" + device. width;
str += "\n屏幕高度:" + device. height;
str += "\nbuildId:" + device. buildId;
str += "\n主板:" + device. board;
str += "\n制造商:" + device. brand;
str += "\n型号:" + device. model;
str += "\n产品名称:" + device. product;
str += "\nbootloader版本:" + device. bootloader;
str += "\n硬件名称:" + device. hardware;
str += "\n唯一标识码:" + device. fingerprint;
str += "\nIMEI: " + device. getIMEI ( ) ;
str += "\nAndroidId: " + device. getAndroidId ( ) ;
str += "\nMac: " + device. getMacAddress ( ) ;
str += "\nAPI: " + device. sdkInt;
str += "\n电量: " + device. getBattery ( ) ;
str += "\n是否有虚拟导航: " + device. checkDeviceHasNavigationBar ( ) ;
str += "\n虚拟导航高度: " + device. getVirtualBarHeigh ( ) ;
log ( str) ;
時間とキー、タッチモニタリング
ボタン監視
"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;
}
タッチモニタリング
events. observeTouch ( ) ;
events. setTouchEventTimeout ( 30 ) ;
toast ( "请在日志中查看触摸的点的坐标" ) ;
events. on ( "touch" , function ( point ) {
log ( point) ;
} ) ;
loop ( ) ;
通知のリスニング
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) ;
}
ボリュームコントロールプログラム
"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) ;
}
長押しして戻ると現在のプログラムを終了します
"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 ) ;
}
}
トーストモニタリング
auto ( ) ;
events. observeToast ( ) ;
events. onToast ( function ( toast ) {
var pkg = toast. getPackageName ( ) ;
log ( "Toast内容: " + toast. getText ( ) +
" 来自: " + getAppName ( pkg) +
" 包名: " + pkg) ;
} ) ;
toast ( "监听中,请在日志中查看记录的Toast及其内容" ) ;
画像と色の処理
写真を探す
var superMario = images. read ( "./super_mario.jpg" ) ;
var mario = images. read ( "./mario.png" ) ;
var point = findImage ( superMario, mario) ;
toastLog ( point) ;
superMario. recycle ( ) ;
mario. recycle ( ) ;
すべての写真を検索
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 ( ) ;
絵を見つけて場所を描きます
var superMario = images. read ( "./super_mario.jpg" ) ;
var block = images. read ( "./block.png" ) ;
var points = images. matchTemplate ( superMario, block, {
threshold : 0.8
} ) . points;
toastLog ( points) ;
var canvas = new Canvas ( superMario) ;
var paint = new Paint ( ) ;
paint. setColor ( colors. parseColor ( "#2196F3" ) ) ;
points. forEach ( point => {
canvas. drawRect ( point. x, point. y, point. x + block. width, point. y + block. height, paint) ;
} ) ;
var image = canvas. toImage ( ) ;
images. save ( image, "/sdcard/tmp.png" ) ;
app. viewFile ( "/sdcard/tmp.png" ) ;
superMario. recycle ( ) ;
block. recycle ( ) ;
image. recycle ( ) ;
Web から画像を取得して保存する
var url = "https://www.autojs.org/assets/uploads/profile/3-profileavatar.png" ;
var logo = images. load ( url) ;
images. save ( logo, "/sdcard/auto.js.png" ) ;
スクリーンショットを撮って保存する
if ( ! requestScreenCapture ( ) ) {
toast ( "请求截图失败" ) ;
exit ( ) ;
}
var img = captureScreen ( ) ;
images. saveImage ( img, "/sdcard/1.png" ) ;
色を正確に見つける
if ( ! requestScreenCapture ( ) ) {
toast ( "请求截图失败" ) ;
exit ( ) ;
}
var img = captureScreen ( ) ;
toastLog ( "开始找色" ) ;
var point = findColor ( img, 0x9966ff ) ;
if ( point) {
toastLog ( "x = " + point. x + ", y = " + point. y) ;
} else {
toastLog ( "没有找到" ) ;
}
あいまいな色検索
if ( ! requestScreenCapture ( ) ) {
toast ( "请求截图失败" ) ;
exit ( ) ;
}
var img = captureScreen ( ) ;
toastLog ( "开始找色" ) ;
var point = findColor ( img, 0x9966ff ) ;
if ( point) {
toastLog ( "x = " + point. x + ", y = " + point. y) ;
} else {
toastLog ( "没有找到" ) ;
}
エリアカラー検索1
if ( ! requestScreenCapture ( ) ) {
toast ( "请求截图失败" ) ;
exit ( ) ;
}
var img = captureScreen ( ) ;
toastLog ( "开始找色" ) ;
var point = findColorInRegion ( img, "#75438a" , 90 , 220 , 900 , 1000 ) ;
if ( point) {
toastLog ( "x = " + point. x + ", y = " + point. y) ;
} else {
toastLog ( "没有找到" ) ;
}
エリアカラー検索2
if ( ! requestScreenCapture ( ) ) {
toast ( "请求截图失败" ) ;
exit ( ) ;
}
var img = captureScreen ( ) ;
toastLog ( "开始找色" ) ;
var point = findColor ( img, "#ff00cc" , {
region : [ 90 , 220 , 900 , 1000 ] ,
threads : 8
} ) ;
if ( point) {
toastLog ( "x = " + point. x + ", y = " + point. y) ;
} else {
toastLog ( "没有找到" ) ;
}
タッチポイントの色をリアルタイムに表示
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) ;
} ) ;
画像処理
"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 != null ) {
logo. recycle ( ) ;
}
if ( currentImg != null ) {
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;
ui. post ( ( ) => {
if ( oldImg != null ) {
oldImg. recycle ( ) ;
}
} ) ;
currentImg = img;
} ) ;
}
var imgProcess = threads. start ( function ( ) {
setInterval ( ( ) => {
} , 1000 ) ;
} ) ;
function processImg ( process ) {
imgProcess. setTimeout ( ( ) => {
if ( logo == null ) {
logo = images. load ( url) ;
}
var result = process ( logo) ;
setImage ( result) ;
} , 0 ) ;
}
var degress = 0 ;
ui. rotate. on ( "click" , ( ) => {
processImg ( img => {
degress += 90 ;
return images. rotate ( img, degress) ;
} ) ;
} ) ;
ui. concat. on ( "click" , ( ) => {
processImg ( img => {
if ( currentImg == null ) {
toast ( "请先点击其他按钮,再点击本按钮" ) ;
return img. clone ( ) ;
}
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) ;
var result = images. threshold ( g, 100 , 200 ) ;
g. recycle ( ) ;
return result;
} ) ;
} ) ;
ui. adaptiveBinary. on ( "click" , ( ) => {
processImg ( img => {
var g = images. grayscale ( img) ;
var result = images. adaptiveThreshold ( g, 200 , "MEAN_C" , "BINARY" , 25 , 10 ) ;
g. recycle ( ) ;
return result;
} ) ;
} ) ;
ui. hsv. on ( "click" , ( ) => {
processImg ( img => {
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 ] ) ;
} ) ;
} ) ;
色の取得と検出
if ( ! requestScreenCapture ( ) ) {
toast ( "请求截图失败" ) ;
exit
}
sleep ( 2000 ) ;
var x = 760 ;
var y = 180 ;
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) ;
var isDetected = images. detectsColor ( captureScreen ( ) , "#73bdb6" , x, y) ;
msg += "\n该位置是否匹配到颜色#73bdb6: " + isDetected;
alert ( msg) ;
QQ の赤い点の場所を見つける
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 ( "没有找到" ) ;
}
ファイルの読み書き
テキストファイルを読む
var path = "/sdcard/1.txt" ;
var file = open ( path) ;
var text = file. read ( ) ;
print ( text) ;
file. close ( ) ;
console. show ( ) ;
テキスト ファイルの読み取りと書き込み
var file = open ( "/sdcard/1.txt" , "w" )
file. write ( "aaaa" ) ;
file. writeline ( "bbbbb" ) ;
file. writelines ( [ "ccc" , "ddd" ] ) ;
file. close ( ) ;
file = open ( "/sdcard/1.txt" , "a" ) ;
file. writeline ( "啦啦啦啦" ) ;
file. writeline ( "哈哈哈哈" ) ;
file. writelines ( [ "ccc" , "ddd" ] ) ;
file. flush ( ) ;
file. close ( ) ;
file = open ( "/sdcard/test.txt" , "r" )
print ( file. readline ( ) ) ;
for each ( line in file. readlines ( ) ) {
print ( line)
}
file. close ( )
console. show ( )
空のフォルダーをすべて削除する
if ( confirm ( "该操作会删除SD卡目录及其子目录下所有空文件夹,是否继续?" ) ) {
toast ( "请点击右上角打开日志" ) ;
deleteAllEmptyDirs ( files. getSdcardPath ( ) ) ;
toast ( "全部完成!" ) ;
}
function deleteAllEmptyDirs ( dir ) {
var list = files. listDir ( dir) ;
var len = list. length;
if ( len == 0 ) {
log ( "删除目录 " + dir + " " + ( files. remove ( dir) ? "成功" : "失败" ) ) ;
return ;
}
for ( let i = 0 ; i < len; i++ ) {
var child = files. join ( dir, list[ i] ) ;
if ( files. isDir ( child) ) {
deleteAllEmptyDirs ( child) ;
}
}
}
ファイルエンコード変換
var f = open ( "/sdcard/1.txt" , "r" , "utf-8" ) ;
var text = f. read ( ) ;
f. close ( ) ;
var out = open ( "/sdcard/2.txt" , "w" , "gbk" ) ;
out. write ( text) ;
out. close ( ) ;
ファイルエンコード変換(上級)
convert ( "/sdcard/1.txt" , "utf-8" , "/sdcard/2.txt" , "gbk" ) ;
function convert ( fromFile, fromEncoding, toFile, toEncoding ) {
fromFile = open ( fromFile, "r" , fromEncoding) ;
toFile = open ( toFile, "w" , toEncoding) ;
while ( true ) {
var line = fromFile. readline ( ) ;
if ( ! line)
break ;
toFile. writeline ( line) ;
}
}
テキストファイルに書き込む
var path = "/sdcard/1.txt" ;
var text = "Hello, AutoJs" ;
var file = open ( path, "w" ) ;
file. write ( text) ;
file. close ( ) ;
メッセージ処理 (暗号化、ダイジェスト、エンコード)
暗号化とデコード
let message = "未加密字符串" ;
log ( "明文: " , message) ;
let key = new $crypto. Key ( "password12345678" ) ;
log ( "密钥: " , key) ;
let aes = $crypto. encrypt ( message, key, "AES/ECB/PKCS5padding" ) ;
log ( "AES加密后二进制数据: " , aes) ;
log ( "AES解密: " , $crypto. decrypt ( aes, key, "AES/ECB/PKCS5padding" , {
output : 'string' } ) ) ;
let keyPair = $crypto. generateKeyPair ( "RSA" ) ;
log ( "密钥对: " , keyPair) ;
let rsa = $crypto. encrypt ( message, keyPair. privateKey, "RSA/ECB/PKCS1padding" ) ;
log ( "RSA私钥加密后二进制数据: " , rsa) ;
log ( "RSA公钥解密: " , $crypto. decrypt ( rsa, keyPair. publicKey, "RSA/ECB/PKCS1padding" , {
output : 'string' } ) ) ;
メッセージダイジェスト (MD5、SHA)
let message = "Hello, Autox.js" ;
log ( "字符串: " , message) ;
log ( "MD5: " , $crypto. digest ( message, "MD5" ) ) ;
log ( "SHA1: " , $crypto. digest ( message, "SHA-1" ) ) ;
log ( "SHA256: " , $crypto. digest ( message, "SHA-256" ) ) ;
log ( "MD5 [base64]: " , $crypto. digest ( message, "MD5" , {
output : 'base64' } ) ) ;
log ( "SHA1 [base64]: " , $crypto. digest ( message, "SHA-1" , {
output : 'base64' } ) ) ;
log ( "SHA256 [base64]: " , $crypto. digest ( message, "SHA-256" , {
output : 'base64' } ) ) ;
let file = "/sdcard/脚本/_test_for_message_digest.js"
$files. write ( file, "Test!" ) ;
log ( "文件: " , file) ;
log ( "MD5: " , $crypto. digest ( file, "MD5" , {
input : 'file' } ) ) ;
log ( "SHA1: " , $crypto. digest ( file, "SHA-1" , {
input : 'file' } ) ) ;
log ( "SHA256: " , $crypto. digest ( file, "SHA-256" , {
input : 'file' } ) ) ;
Base64エンコーディング
let message = "autox.js" ;
log ( "明文: " , message) ;
let base64encode = $base64. encode ( message) ;
log ( "Base64编码: " , base64encode) ;
let message2 = "YXV0b3guanM=" ;
log ( "明文2: " , message2) ;
let base64decode = $base64. decode ( message2) ;
log ( "Base64解码: " , base64decode) ;
コルーチン
シエチェン HelloWorld
function delay ( millis ) {
var cont = continuation. create ( ) ;
setTimeout ( ( ) => {
cont. resume ( ) ;
} , millis) ;
cont. await ( ) ;
}
function read ( path ) {
var cont = continuation. create ( ) ;
threads. start ( function ( ) {
try {
cont. resume ( files. read ( path) ) ;
} catch ( err) {
cont. resumeError ( err) ;
}
} ) ;
return cont. await ( ) ;
}
function add ( a, b ) {
return new Promise ( function ( resolve, reject ) {
var sum = a + b;
resolve ( sum) ;
} ) ;
}
toastLog ( "Hello, Continuation!" ) ;
setTimeout ( ( ) => {
toastLog ( "3秒后...." ) ;
} , 3000 ) ;
delay ( 6000 ) ;
toastLog ( "6秒后..." ) ;
try {
toastLog ( "读取文件hello.txt: " + read ( "./hello.txt" ) ) ;
} catch ( err) {
console. error ( err) ;
}
var sum = add ( 1 , 2 ) . await ( ) ;
toastLog ( "1 + 2 = " + sum) ;
{
"name" : "协程HelloWorld" ,
"main" : "main.js" ,
"ignore" : [
"build"
] ,
"packageName" : "com.example.cont.helloworld" ,
"versionName" : "1.0.0" ,
"versionCode" : 1 ,
"useFeatures" : [ "continuation" ]
}
UI で相乗効果を使用する
"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 ( ) ;
}
} ) ;
{
"name" : "协程UI示例" ,
"main" : "main.js" ,
"ignore" : [
"build"
] ,
"packageName" : "com.example.cont.ui" ,
"versionName" : "1.0.0" ,
"versionCode" : 1 ,
"useFeatures" : [ "continuation" ]
}
フローティングウィンドウ
動的なフローティングテキスト
var window = floaty. window (
< frame gravity= "center" >
< text id= "text" textSize= "16sp" textColor= "#f44336" / >
< / frame>
) ;
window. exitOnClose ( ) ;
window. text. click ( ( ) => {
window. setAdjustEnabled ( ! window. isAdjustEnabled ( ) ) ;
} ) ;
setInterval ( ( ) => {
ui. run ( function ( ) {
window. text. setText ( dynamicText ( ) ) ;
} ) ;
} , 1000 ) ;
function dynamicText ( ) {
var date = new Date ( ) ;
var str = util. format ( "时间: %d:%d:%d\n" , date. getHours ( ) , date. getMinutes ( ) , date. getSeconds ( ) ) ;
str += util. format ( "内存使用量: %d%%\n" , getMemoryUsage ( ) ) ;
str += "当前活动: " + currentActivity ( ) + "\n" ;
str += "当前包名: " + currentPackage ( ) ;
return str;
}
function getMemoryUsage ( ) {
var usage = ( 100 * device. getAvailMem ( ) / device. getTotalMem ( ) ) ;
return Math. round ( usage * 10 ) / 10 ;
}
目の保護モード
var w = floaty. rawWindow (
< frame gravity= "center" bg= "#44ffcc00" / >
) ;
w. setSize ( - 1 , - 1 ) ;
w. setTouchable ( false ) ;
setTimeout ( ( ) => {
w. close ( ) ;
} , 60000 ) ;
フローティングウィンドウ入力ボックス
var window = floaty. window (
< vertical>
< input id= "input" text= "请输入你的名字" textSize= "16sp" focusable= "true" / >
< button id= "ok" text= "确定" / >
< / vertical>
) ;
window. exitOnClose ( ) ;
toast ( "长按确定键可调整位置" ) ;
window. input. on ( "key" , function ( keyCode, event ) {
if ( event. getAction ( ) == event. ACTION_DOWN && keyCode == keys. back) {
window. disableFocus ( ) ;
event. consumed = true ;
}
} ) ;
window. input. on ( "touch_down" , ( ) => {
window. requestFocus ( ) ;
window. input. requestFocus ( ) ;
} ) ;
window. ok. on ( "click" , ( ) => {
toast ( "傻瓜! " + window. input. text ( ) ) ;
window. disableFocus ( ) ;
} ) ;
window. ok. on ( "long_click" , ( ) => {
window. setAdjustEnabled ( ! window. isAdjustEnabled ( ) ) ;
} ) ;
setInterval ( ( ) => {
} , 1000 ) ;
フローティング ウィンドウ実行スクリプト ボタンの簡易バージョン
var path = "/sdcard/脚本/test.js" ;
if ( ! files. exists ( path) ) {
toast ( "脚本文件不存在: " + path) ;
exit ( ) ;
}
var window = floaty. window (
< frame>
< button id= "action" text= "开始运行" w= "90" h= "40" bg= "#77ffffff" / >
< / frame>
) ;
window. exitOnClose ( ) ;
var execution = null ;
window. action. click ( ( ) => {
if ( window. action. getText ( ) == '开始运行' ) {
execution = engines. execScriptFile ( path) ;
window. action. setText ( '停止运行' ) ;
} else {
if ( execution) {
execution. getEngine ( ) . forceStop ( ) ;
}
window. action. setText ( '开始运行' ) ;
}
} ) ;
window. action. longClick ( ( ) => {
window. setAdjustEnabled ( ! window. isAdjustEnabled ( ) ) ;
return true ;
} ) ;
setInterval ( ( ) => {
} , 1000 ) ;
フローティングテキスト
var window = floaty. window (
< frame gravity= "center" >
< text id= "text" text= "点击可调整位置" textSize= "16sp" / >
< / frame>
) ;
window. exitOnClose ( ) ;
window. text. click ( ( ) => {
window. setAdjustEnabled ( ! window. isAdjustEnabled ( ) ) ;
} ) ;
setInterval ( ( ) => {
} , 1000 ) ;
フローティング実行スクリプトボタン
var path = "/sdcard/脚本/test.js" ;
if ( ! files. exists ( path) ) {
toast ( "脚本文件不存在: " + path) ;
exit ( ) ;
}
var window = floaty. window (
< frame>
< button id= "action" text= "开始运行" w= "90" h= "40" bg= "#77ffffff" / >
< / frame>
) ;
setInterval ( ( ) => {
} , 1000 ) ;
var execution = null ;
var x = 0 , y = 0 ;
var windowX, windowY;
var downTime;
window. action. setOnTouchListener ( function ( view, event ) {
switch ( event. getAction ( ) ) {
case event. ACTION_DOWN :
x = event. getRawX ( ) ;
y = event. getRawY ( ) ;
windowX = window. getX ( ) ;
windowY = window. getY ( ) ;
downTime = new Date ( ) . getTime ( ) ;
return true ;
case event. ACTION_MOVE :
window. setPosition ( windowX + ( event. getRawX ( ) - x) ,
windowY + ( event. getRawY ( ) - y) ) ;
if ( new Date ( ) . getTime ( ) - downTime > 1500 ) {
exit ( ) ;
}
return true ;
case event. ACTION_UP :
if ( Math. abs ( event. getRawY ( ) - y) < 5 && Math. abs ( event. getRawX ( ) - x) < 5 ) {
onClick ( ) ;
}
return true ;
}
return true ;
} ) ;
function onClick ( ) {
if ( window. action. getText ( ) == '开始运行' ) {
execution = engines. execScriptFile ( path) ;
window. action. setText ( '停止运行' ) ;
} else {
if ( execution) {
execution. getEngine ( ) . forceStop ( ) ;
}
window. action. setText ( '开始运行' ) ;
}
}