Autojs简单案例&常用控件汇总

一、介绍:

1.Auto.js是一款安卓应用,针对安卓7.0以上机型,它可以无需root执行脚本。主要是运用系统自带的“无障碍服务”来获取页面的,这是个亮点,但有个缺陷就是每次关闭 Auto.js 这个app后都要重新开启“无障碍服务”,颇为繁琐。

2.Auto.js可以打包成apk直接装到手机

3.Auto.js可以查看页面布局,需要打开悬浮窗权限

备注:部分功能需要pro版才能用

 

 

二、简单案例:

1.快手刷金币

auto(); //确保无障碍服务已经启用
//判断当前页面是否有指定text
if (text("发现").exists() || text("同城").exists()){
    log('在设置页面—记录log')//可在手机的log中打印
    sleep(500);
    swipe(500,1800,500,300,200);//上滑屏幕
}
else{
toast('不在刷视频页面_刷不到金币');
}

 

2.华为辅助安装处理&oppo手机安装处理

////____________________________华为手机安装处理_______________________________
auto();//确保无障碍服务已经启用
var i=0
if(text("继续安装").exists()){
    log('111111111111111')
    sleep(2000)
    click(760,1650);//坐标点击
    sleep(6000)
    if (text("去华为应用市场查找").exists()){
        sleep(2000)
        click(530,1567);//坐标点击
        sleep(4000)
    }
    if(text("安装成功").exists()){
        toast('安装成功');
        click(788,1730);//坐标点击   
    }
}
else{
    log('没有应用安装弹框');
}


////_____________________________oppo手机安装处理_______________________________
"auto"; //确保无障碍服务已经启用
if(text("继续安装").exists()){
  log('111111111111111');
  setText("123456");
  textContains("确定").find().click();
  sleep(5000);
  if (text("安装").exists()){
      sleep(2000)
      textContains("安装").find().click();
      sleep(4000)
      textContains("完成").find().click();
  }
}
else{
  console.error('没有应用安装弹框_安装出错');
}

 

3.元素判断&js循环语法

/////================================================================判断页面元素===================================================================

////------------------查询方式一(需求完全匹配)-----------------------------------------
if (text("忘记").exists()){
    log('在设置页面—记录log')//可在手机的log中打印
    toast('显示弹框');
}

//--------------------查询方式二--------------------------------------
var btnClose = className("android.widget.TextView").text("小红绳").findOne(500);//findOne(500)查找500毫秒超时
if (btnClose){
    toast('1111111111111111111111');
}

////--------------------查询方式三--------------------------------------
if(desc("连信").exists()){
    toast('显示弹框');
}
else{
    toast('没有连信');
}


//---------------当前页面不包含'小红',执行循环体--------------------------
if (!textEndsWith("小红").exists()){
    toast('显示弹框');
}

////-----------------------------正则匹配--------------------------------
//匹配以‘同意’开头的字符串,若3秒内没有查询到则失败。
if (textStartsWith("同意").findOne(3000)){
    // 匹配以手机结尾的元素textEndsWith("手机")
    //匹配页面包含手机的元素textContains("手机")
    toastLog('匹配成功');
    sleep(2000)
  }
  else{
    toastLog('没有找到');
  }
  

////-----------判断当前页面是否包含连信,有就启动---------------------------
if(desc("连信").exists()){
    toast('显示弹框');
    app.launchApp("连信");
    sleep(3000);
}
else{
    toast('没有连信');
}


////_______________________________________两个字符串比较______________________________
function judge_include_str(str, sub_str) {
  //判断两个字符串是否相等,相等为0,不相等为-1
  if (("".equals(str)) || ("".equals(sub_str))) {
    return true;
  }
  else {
    var ret = str.indexOf(sub_str, false)
    return ret;
  }
}
aa=judge_include_str('chenwei', 'chenwei');
log(aa);


////_______________________在指定时间内查询元素,超时就失败_______________________________________ if (text("帐号登录").findOne(5000)){ log('找到元素—记录log')//可在手机的log中打印 toast('显示弹框'); } else{ log('没有找到元素') } ////_______________________________________获取元素的内容________________________________ function screen_content(){ var fas = ""; //按元素id查找,,可以为className、desc等 var fsfan = id("phone_number_edit").find(); for(var i = 0; i < fsfan.length; i++){ var ftxt = fsfan[i].text(); if(ftxt != ""){ toast('符合条件'); if(fas == ""){ fas = ftxt; console.log(fas) }else{ fas = fas +"_-_"+ ftxt; console.log(fas) } } } } screen_content(); /////======================================================循环============================================================================= ////-----------------------------------------for循环---------------------------------------- for(var i=1;i<4;i++){ sleep(3000) toast('toast弹框信息'); } ////-------------------------------------------while循环------------------------------------ var num = 1;//1、声明循环变量 while (num<=10){//2、判断循环条件; document.write(num+"<br />");//3、执行循环体操作; num++;//4、更新循环变量; } ////------------------------------------------for和if---------------------------------------- for(var i = 1; i < 10; i++){ if(i == 4){
//退出循环(break结束整个循环体,continue跳出当前循环 )
break; } console.log(i);//1 2 3 }

 

4.app应用名和包名

// 使用 应用名称,获取应用的包名.
 
var PackageName; //声明变量
 
PackageName=getPackageName("QQ");
 
log(PackageName);



//使用 包名,获取 应用名称.
 
var AppName;
 
AppName = getAppName("com.tencent.mobileqq");
 
log(AppName);

 

5.设备截图

////______________________设备截图_______________________________________________
////设置无障碍模式 fast为启用缓存
auto();

////方式一
test_img();
 function test_img(){
     // 1、开启线程(因为线程是异步的)自动点击 立即开始,并且触发事件(只需要执行一次就可以)
    threads.start(function () {
        var beginBtn;
        if (beginBtn = classNameContains("Button").textContains("立即开始").findOne(2000)) {
            beginBtn.click();
        }
    });      
    // 2、请求截图权限(弹框出现,可以省略第一步但需要手动点击“立即开始”)
    if(!requestScreenCapture()){
        toast("请求截图失败");
        exit();
    }
    //3、进行截图
    sleep(1700);//等待一会保证弹框关闭了
    captureScreen("/sdcard/img.png");
 }



////方式二
 //1.请求截图权限
if(!requestScreenCapture()){
    toast("请求截图失败");
    exit();
}
//2、进行截图
captureScreen("/sdcard/img.png");
 


////方式三:
requestScreenCapture(false);//请求截图
var im = captureScreen();//截图
var path = "/sdcard/screenshot.png";
//保存图片
im.saveTo(path);
toast("保存图片");//tosat提示
//把图片加入相册中
app.sendBroadcast(

    new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, android.net.Uri.fromFile(new java.io.File(path)))  
);

//方式一可以全部自动截图,, 方式二需要先记住勾选,如果autojs清除缓存了就需要重新勾选了,,方式三全自动截图切复制到相册中

 

6.获取设备信息&设备操作

////______________________设备获取&设备操作_______________________________________________
////设置无障碍模式 fast为启用缓存
auto();

a = device.height; //高度
b = device.width; //宽度
console.log('设备分辨率:'+b+'*'+a);

brand = device.brand;  //品牌厂商
console.log(brand);

model = device.model; // 设备型号
console.log(model);

product = device.product; // 手机型号名称
console.log(product);

//硬件序列号
serial = device.serial; // c3ba6d87a0d71433
console.log(serial);

//安卓系统API版本
sdkint = device.sdkInt; //API版本:25
console.log('API'+sdkint);

//系统版本号
release = device.release; //7.1.2
console.log(release);

//安卓id
getandroidid = device.getAndroidId(); //71433c3ba6d87a0d
console.log(getandroidid);

//MAC地址 需要联网才能获取
getmacaddress = device.getMacAddress(); //B0:FC:36:12:C9:EF
console.log(getmacaddress);

//获取媒体音量
getmusicvolume = device.getMusicVolume(); 
console.log('音量'+getmusicvolume); //音量:大小

//获取电量百分比
getbattery = device.getBattery(); //87
console.log(getbattery);

//确认设备是否在充电
ischarging = device.isCharging();
console.log(ischarging); //flase 没有在充电

//获取设备运行内存容量(占用的内存)
gettotalmem = device.getTotalMem();
console.log(gettotalmem); //3186032640 单位(字节),可以自己转换

//获取设备当前可用内存
getavailmem = device.getAvailMem();
console.log(getavailmem);  //2386280448(字节),可以自己转换

//查看屏幕是否亮着
isscreenon = device.isScreenOn();
console.log(isscreenon); //true

//唤醒设备 (如果息屏可以点亮屏幕,亮屏就依然亮屏)
device.wakeUp();

//保持点亮屏幕(设置时间)
device.keepScreenOn(30000); //不加参数常亮,  手机亮屏时间以device.keepScreenOn为准,之前系统设置的时间作废

//保持屏幕常亮 可调节省电模式
device.keepScreenDim(timeout);

//取消设备保持唤醒状态 用来取消屏幕的唤醒状态
device.cancelKeepingAwake();

////使设备震动一段时间
device.vibrate(300);  //单位毫秒

//取消震动
device.cancelVibration();

 

7.模拟按键

////______________________按键模拟_物理按键的全局函数_______________________________________________
////设置无障碍模式 fast为启用缓存
auto();

//以上函数都可以放在toast()或log()里, 例如:toast(notifications());
back();//返回,返回是否执行成功
home();//回到桌面,返回是否执行成功
powerDialog();//弹出电源键菜单。返回是否执行成功
notifications();//拉出通知栏。返回是否执行成功
quickSettings()//下拉通知栏到底。返回是否执行成功
recents();//显示最近任务。返回是否执行成功

 

8.多线程

////__________________________________多线程_____________________________________
//定义子线程
var thread = threads.start(function(){
    while(true){
        sleep(200);
        log("子线程");
    }
});

//这里是主线程
sleep(2000);
log('准备停止主线程了')
if (20>10){
    sleep(1000);
    //停止线程执行
    thread.interrupt();
}



////_________________________子线程主动退出____________________________________________
var thread = threads.start(function(){
    var i=0
    while(i<10){
        sleep(200);
        log("子线程");
        if (i>5){
            log("子线程i>5");
            threads.shutDownAll()
        }
        i=i+1

    }
});

//这里是主线程
sleep(2000);
log('准备停止主线程了')
if (20>10){
    sleep(1000);
    log('主线程.....')
}
log('主线程...end')



////______________________________堵塞主线程、等待子线程完成____________________________________
var sum = 0;
//启动子线程计算1加到10000
var thread = threads.start(function(){
    log('子线程开始')
    for(var i = 0; i < 10000; i++){
        sum += i;
    }
});


log('主线程开始')
//等待子线程完成(堵塞)
thread.join();
toast("sum = " + sum);




//_______________________________线程定时任务执行____________________________________
threads.start(function(){
    setInterval(function(){
        log("定时循环函数,2000表示毫秒");
    }, 2000);
});



//________________________________线程通讯________________________________________
/**
 * 线程你们的数据是不能直接在线程以外直接调用,而业务逻辑需要调用线程的业务数据
 * 需要用到线程通讯
*/
 
var sum = threads.disposable();//声明一个变量来接受 线程通讯返回的数据

//用线程实现1到100累加
threads.start(function(){
    var s = 0;
    //用for循环做1-100的阶加
    for(var i = 1; i <= 100; i++){
        s += i;
    }
    //将计算好的结果通知主线程接收结果
    sum.setAndNotify(s);
});

//blockedGet()用于等待结果
log("结果= " + sum.blockedGet());

 

 9.获取包名

//_____________________________shell封装_获取手机包名、并转成list___________________________________
auto();
function get_package() {
    log('开始启动了');
    var result = shell("pm list package -3");
    //log(result);//原始第三方包
    var str = JSON.stringify(result);//数据类型转换
    var str1 = str.match(/package:(\S*)package/)[1];//正则匹配
    str_chen = str1.replace(/\\n/g, ",");//替换\n为逗号
    basic = str_chen.substr(0, str_chen.length - 1);  //删除字符串最后一位
    str_page = basic.replace(/package:/g, "");//替换\n为逗号
    var page_list = str_page.split(',');//字符串转list(以逗号分割)
    log(page_list);
}

// get_package()



//________________________shell常用操作(可以封装成函数)_____________________________________________________________
//获取包名
var result = shell("pm list package -3");
console.log('第三方包名:'+result);
//获取品牌
var brand = shell("getprop ro.product.brand");
console.log('查看手机品牌:'+brand);
//清空应用数据
var data_clean = shell("pm clear 包名");
console.log('清空应用数据:'+data_clean);
//删除文件
var chen=shell("rm -rf ./sdcard/.dalan");
log(chen)
//文件复制粘贴
var chen=shell("cp /sdcard/2.png /sdcard/test/2.png");
//停止app
shell('am force-stop ' +包名 , true);




////_____________________________js补充知识__________________________________________________
//获取字符串1与字符串2之间的内容
var str = "aaabbbcccdddeeefff";
log(typeof (str));//获取数据类型
str = str.match(/aaa(\S*)fff/)[1];
log(str)


//join()数组转字符串
let chen = ['ch', '22', 'wei'];
text = chen.join(',');
log('转换后的字符串:', text);


//split()字符串转数组
let wei = 'chen,keke,233,你好';
text = wei.split(',');
log('转换后的list:', text);


//replace()字符串替换
var chen = 'dalan_test123_is_notdalan123'
str_page = chen.replace(/dalan/g, "word");//替换\n为逗号
console.log(str_page)

 

10.定时器

////___________________每5秒钟执行一次,执行1分钟_______________________
//每5秒就发出一次hello
var id = setInterval(function(){
    log("hello");
}, 5000);

//1分钟后取消循环
setTimeout(function(){
    clearInterval(id);
}, 60 * 1000);


////______________________5秒后执行一次___________________________
setTimeout(function(){
    toast("hello")
}, 5000);


////________________________死循环5秒钟执行一次___________________
while (true) {
    toast("Test");
    sleep(5000);
}



////______________________________________自动结束的计时器_____________________________________
var timesRun = 0;

//2秒执行一次,当timesRun等于60就结束循环
var interval = setInterval(function(){
    timesRun += 1;
    if(timesRun === 60){
        clearInterval(interval);
    }
}, 2000);



https://www.cnblogs.com/DSC1991/p/8665891.html ....................setInterval与setTimeout的区别
https://blog.csdn.net/chelen_jak/article/details/82899153 .........setInterval设置停止和循环 (实用)
setInterval()会不停的调用函数,直到clearInterval()被调用或者窗口被关闭,由 setInterval()返回的ID值可用作clearInterval()方法的参数。
setTimeout()只执行函数一次,如果需要多次调用可以使用setInterval(),或者在函数体内再次调用setTimeout()

 

 

 11.图片相似度

////_________________________________查找图片红色部分并显示坐标____________________________________
path = "/sdcard/1.png"
var img = images.read(path);
log("读取图片")

//循环找色,找到红色时停止并报告坐标
while (true) {
    var point = findColor(img, "#1b8374", { threshold: 120 });
    if (point) {
        toastLog("找到红色#fd1111,坐标为(" + point.x + ", " + point.y + ")");
        break
    }
}
exit()



////______________________________________判断判断图片相似度___________________________________________
////先读取文件 
var img1 = images.read("/sdcard/1.png");//大图
var img2 = images.read("/sdcard/2.png");//小图
  // 语法糖 findImage(img, template, options)
  // template 要找的图片
  // options 对象 {threshold ,region, level}  
  // threshold: 0.9, 默认0.9 范围(1-9) 相似度
  // region: [x, y] 找图的区域
  
// 图片比对
var result = findImage(img1, img2,{region: [0, 10], threshold: 0.8 }); // 找到返回true, 失败返回false
if(result){
    toast("找到啦:" + result);
}else{
    toast("没找到");
}




////______________________________________判断图片相似度(可以两张一样的图片)_____________________________________

//大图
let max = images.read("/sdcard/1.png"); 
//小图
let min = images.read("/sdcard/2.png");

//对比相似对(threshold是阈值)
let p = findImage(max, min,{threshold:0.85 });//// 找到返回true, 失败返回false

if (p) {
    log("找到啦:" + "每日空投");
    let xx = random(p.x, p.x + min.getWidth());//小图的x坐标
    let yy = random(p.y, p.y + min.getWidth());//小图的y坐标
    click(xx, yy)
    log("点击按钮-每日空投");
    sleep(1000)
} else {
    log("没找到" + "每日空投");
}

 

 12.下载文件

log('开始请求接口');
var url="http://106.55.29.87:8000/download?filename=d91f77f99ba796397c7df4f5b97726fb.png&path=upload";
var res = http.get(url);
//判断状态码
if(res.statusCode >= 200 && res.statusCode < 300){
    toast("页面获取成功!");
    //获取文件并保存
    files.writeBytes('/sdcard/3.png',res.body.bytes());
    //打开文件
    app.viewFile('/sdcard/3.png');
    log('下载成功')
}else if(res.statusCode == 404){
    toast("页面没找到哦...");
}else{
    toast("未知错误");
}

 

 13.元素定位

///////==========================================================元素定位===================================================================
说明:
1.findOne()根据选择器selector在该控件的子控件、孙控件...中搜索符合该选择器条件的控件,并返回找到的第一个控件;如果没有找到符合条件的控件则返回null。
2.find()根据选择器selector在该控件的子控件、孙控件...中搜索符合该选择器条件的控件,并返回它们组合的集合。
3.parent()返回该控件的父控件。如果该控件没有父控件,返回null。


//------------------------用auto.js查找界面元素-----------------------------
text("18520103625").find();//按控件文本查找,,也可使用findOne()
desc("xxxx").find();//按描述信息查找
id("xxxx").find();//按元素id查找
className("xxxx").find();//按元素类型查找

text("属性值").findOne().parent().click(); //parent通过子控件查找父控件,常用于子控件不能点击,而通过子控件查找到父控件完成点击
text("属性值").findOne().childCount(); //获取控件中子控件的数量
text("进入游戏").find().click(); //点击进入游戏(先查找再点击)
text("进入游戏").findOne(3000).click(); //点击进入游戏___查询超时就报错,,(text()是完全匹配)

textContains("手机").find().click(); //匹配页面包含手机的元素
textStartsWith("手机").find().click(); //匹配以"手机"开头的元素
textEndsWith("手机").find().click(); //匹配以"手机"结尾的元素
text("xxxx").find(); //按控件文本查找,,  也可使用findOne()
desc("xxxx").find(); //按描述信息查找
id("xxxx").find(); //按元素id查找元素
className("xxxx").find(); //按元素类型查找
atextMatches("\\d+"); //以正则匹配

//________________判断当前是否包含xx元素__________________________ if (text("xx").exists()){ log('在设置页面—记录log')//可在手机的log中打印 toast('显示弹框'); } //_______________________________________获取元素的内容________________________________ function screen_content(){ var fas = ""; //按元素id查找,,可以为className、desc等 var fsfan = id("phone_number_edit").find(); for(var i = 0; i < fsfan.length; i++){ var ftxt = fsfan[i].text(); if(ftxt != ""){ toast('符合条件'); if(fas == ""){ fas = ftxt; console.log('当前控件元素为:',fas) }else{ fas = fas +"_-_"+ ftxt; console.log(fas) } } } } screen_content(); ////___________________________函数封装定位元素、点击_______________________________________ function clickText(test){ //2秒内找到元素,超时失败 if(text(test).findOne(2000)){ log('找到了'+test); click(test);//点击元素 log('点击了'+test); }else{ log('没找到'+test); } } clickText('登录') ////_____________________________获取文本的坐标位置__________________________________________ var str = "18520103625"; var x = text(str).findOne().bounds().left;// 首次出现的x坐标 var y = text(str).findOne().bounds().top;// 首次出现的y坐标 console.log(x,y);

 

 

三、语法案例

1.通过函数模式操作

//____________________________通过函数打开url&搜索&断言__________________________________________
home();//回到桌面
sleep(2000);//等待2秒
auto();
test_url();//函数声明

function test_url(){
    var url="https://www.baidu.com/";
    app.openUrl(url);//打开网页
    sleep(5000);
    if(text("百度一下").exists()){
        log("已在百度首页");
        id("su").find();//定位到搜索框
        sleep(1000);
        setText("城南花已开");//输入文字
        sleep(1000);
        desc("百度一下").click();
        sleep(4000);
        //匹配当前页面是否存在“城南花已开 - 百度百科,,可借助auto.js的布局范围分析查看控件”
        if((className("android.widget.Button").desc("城南花已开 - 百度百科")).exists()){
            toastLog('true-已匹配到相关内容')
        }
        else{
            toastLog('false-未匹配到相关内容')
        }
    }
}




//_____________________通过函数判断是否包含"备忘录"或蓝牙_________________________
main();//声明主函数

function chen_test(){
    //判断当前页面是否有备忘录或蓝牙
    if (text("备忘录").exists() || text("蓝牙").exists())  {
        toast("找到相关内容");   //toast提示
        log('在auto.js的日志中打印信息')//可在手机的log中打印
        sleep(4000);//等待时间
        toast('欢迎进入-设置页面');//toast提示
    }
    else {
        toast("当前没有找到_任何相关内容");   //悬浮框,toast提示
    }
}


//定义主函数main,需要在顶部先声明不然调用不生效
function main(){
    chen_test();//调用函数
    exit();//退出,可写或不写
}

 

2.监听toast&包名&网络请求&文件上传

////__________________________监听toast和包名(可监听手机一切toast、通知等信息很强大)___________________________________________

auto();
events.observeToast();
events.onToast(function(toast){
    // log(toast.texts)
    log("Toast内容:" + toast.getText() +'\n'+"包名:" + toast.getPackageName())
});



////_________________________通过包名、应用名启动应用_____________________________________
////如果对应的应用不存在,则返回false; 否则返回true

var packageName="com.tencent.mobileqq";
var appname="备忘录";
////通过包名判断
if(app.launch(packageName)){
    sleep(2000);
    log('找到包名:'+packageName);
}
////通过应用名判断
else if (app.launchApp(appname))
{
    sleep(2000);
    log('找到应用名:'+appname)
}
else{

    log('没有找到应用')
}



////_________________________通过应用名获取包名——————————————————————————————————————————
var name_pa = getPackageName("备忘录"); //获取应用对应的包名
log(name_pa)



////__________________________打开一个网址 并判断是否成功__________________________________
home();//回到桌面
sleep(2000);//等待2秒
auto();
test_url();//函数声明
function test_url(){
    var url="https://www.baidu.com/";
    app.openUrl(url);//打开网页
    sleep(3000);
    if(text("百度一下").exists()){
        log("断言成功")
    }
}



////___________________请求GET__________________________________________________________
var url="http://192.168.10.32:8000/subcontract"
var res = http.get(url);
//判断状态码
if(res.statusCode >= 200 && res.statusCode < 300){
    toast("页面获取成功!");
}else if(res.statusCode == 404){
    toast("页面没找到哦...");
}else{
    toast("错误: " + res.statusCode + " " + res.statusMessage);
}

log('获取头信息:\n',res.headers);
// log('获取响应的内容:\n',res.body.string());//以字符串形式返回响应内容
// log('获取响应的内容:\n',res.body.json());//以json形式返回响应内容
// log('获取响应的内容:\n',res.body.bytes());//以字节数组形式返回响应内容
log('当前请求地址及方式\n',res.request)
log('当前请求url\n',res.url)
log('当前请求的方法\n',res.method)
log('响应状态码:',res.statusCode)
log('响应的HTTP状态信息:',res.statusMessage)



////带headers的get请求
var url = "http://192.168.10.32:8000/subcontract";
var res = http.get(url,{
    headers: {
        'Accept-Language': 'zh-cn,zh;q=0.5',
        'User-Agent': 'Mozilla/5.0(Macintosh;IntelMacOSX10_7_0)AppleWebKit/535.11(KHTML,likeGecko)Chrome/17.0.963.56Safari/535.11'
    }
});

if(res.statusCode >= 200 && res.statusCode < 300){
    toast("页面获取成功!");
}else if(res.statusCode == 404){
    toast("页面没找到哦...");
}else{
    toast("错误: " + res.statusCode + " " + res.statusMessage);
}
////获取返回信息
var html = res.body.string();
log(html)




////_____________________请求post________________________________________________________
////post请求方式一:
var url = "http://192.168.10.32:8000/subcontract";
var res = http.post(url,{
"game_id":"200003306",
"name":"dalan_test"
});
//获取返回信息
var html = res.body.string();
log(html)

//通过状态码判断
if(res.statusCode >= 200 && res.statusCode < 300){
    toast("页面获取成功!");
}else if(res.statusCode == 404){
    toast("页面没找到哦...");
}else{
    toast("错误: " + res.statusCode + " " + res.statusMessage);
}

//通过字符串匹配来判断(&&表示且,||表示或)
if(html.match('status') && html.match('POST')){
    log('已经包含')      
}
else{
    log('没有包含')
}



////post请求二:
//例如接口响应为:{ code: 200, method: 'POST', msg: '渠道包上传成功!', status: true }
let url = "http://192.168.10.32:8000/subcontract";
let res = http.post(url, {
    "service": "App.Zllgcimei.Imei",
    "game_id": "200003306"
});

let appName;//声明变量
let html = res.body.string();  //取页面html源码
log(html)

//JSON.parse() 将数据转换为 JavaScript 对象。
let json = JSON.parse(html);
//log(json)
if (json.code == "200") {
    log("符合条件")
    appName = json.msg
} else {
    log("请求失败!")
}

log(appName)



//postJson方式(相当于post的json请求)
let url = "http://192.168.10.32:8000/subcontract";
r = http.postJson(url, {
    "service": "App.Zllgcimei.Imei",
    "game_id": "200003306"
});

let text=r.body.string();//获取响应
//同时弹起toast和记录日志
toastLog(text);



////____________________文件上传__________________________________________________
var url="http://106.55.29.87:8000/upload"
var res = http.postMultipart(url, {
    file: open("/sdcard/test/chen.jpg")
});
let html=res.body.string();//打印原始数据
let json = JSON.parse(html);//将数据转换为 JavaScript 对象。
log(json)
if (json.msg == "success") {
    log('上传文件成功')
}

 

 

 3.autojs模块调用:

方法一:

  放到同一个目录下运行,必须是手机上的目录,不能pc F5,因为require的文件在pc上没有在手机上。

  main.js模块为主调用方:

log("开始测试");
//导入模块
var common= require('common.js');

//调用函数
log("两数相乘%d", common.chen());
console.log("%d+%d=%d", 3,4,common.chen_age(3,4));//console.log或log功能都一样
log(common.chen_sum(5));

 

 common.js模块为被方:

//声明common,必须的
var common= {};


//定义函数,没有参数
common.chen = function(){
  let pp=50;
  //求乘法
  return  pp * 10;
};


//定义函数,带参数(a,b)
common.chen_age=function(a,b){
log(a,b);
//求平均数 return (a+b)/2; }; //定义带有默认值的函数 common.chen_sum=function(){ var a = arguments[0] ? arguments[0] : 200; var b = arguments[1] ? arguments[1] : 150; //求和 return a+b; }; ////调用方式 // alert( simue() ); //输出350 // alert( simue(10) ); //输出160 // alert( simue(10,20) ); //输出30 //对象引用,必须的 module.exports = common;

方法二:

//m2.js
module.exports={
    //变量a
    a:1,

    //带两个形参的函数
    b:(str1,str2)=>{
        return str1+","+str2
    }
}



//main.js
var m2=require("m2.js")
toast(m2.a) //调用变量a
toast(m2.b("hello","world")) //调用函数传两个参数

 

 4.判断手机横竖屏

////_________________________判断手机横竖屏_______________________________
chen();
// 函数在function后,可以在前面或后面调用
function chen() {
  var a = (context.resources.configuration.orientation);
  if (a === 1) {
    toastLog("这是竖屏!!");
    return '竖屏'
  }
  else {
    toastLog("这是横屏!!");}
    return '横屏'
}

// chen();



// 函数在function前, 只能在后面调用
chen=function() {
  var a = (context.resources.configuration.orientation);
  if (a === 1) {
    toastLog("这是竖屏!!");
    return '竖屏'
  }
  else {
    toastLog("这是横屏!!");}
    return '横屏'
}

chen();

 

 5.页面相关

"ui";
////__________________________________________点击页面中点击确定触发动作———————————————————————————
ui.layout(
    <vertical padding="16">
        <text textSize="16sp" textColor="black" text="请输入执行函数"/>
        <input id="name" text=""/>
        <button id="ok" text="确定"/>
    </vertical>
);


////指定确定按钮点击时要执行的动作
ui.ok.click(function(){
    //通过getText()获取输入的内容
    var name = ui.name.getText();
    toast(name + "您好!");
    eval(name+'()');//通过变量调用函数
    
});

////定义函数
function test(){
    var url="https://www.baidu.com/";
    console.log('网址:'+url);
}


////_____________________________________________布局________________________________________________
////布局一
"ui";
ui.layout(
    <vertical h="100dp" weightSum="5">
        <text layout_weight="1" text="控件1" bg="#ff0000"/>
        <text layout_weight="2" text="控件2" bg="#00ff00"/>
        <text layout_weight="1" text="控件3" bg="#0000ff"/>
    </vertical>
);


////布局二
"ui";
ui.layout(
    <vertical h="100dp">
        <text h="40dp" text="控件1" bg="#ff0000"/>
        <text layout_weight="2" text="控件2" bg="#00ff00"/>
        <text layout_weight="1" text="控件3" bg="#0000ff"/>
    </vertical>
);


////按钮布局
"ui";
ui.layout(
    <horizontal>
        <button text="第一个按钮"/>
        <button text="第二个按钮"/>
    </horizontal>
);


////页面布局
"ui";
ui.layout(
    <frame>
        <button gravity="right" w="*" h="auto" text="靠右的文字"/>
    </frame>
);

 

 

四、常用控件汇总

#包相关
launchApp('名字'); //通过app名字启动app应用
launch('app包名'); //通过包名启动app应用
app.uninstall('包名'); //卸载app
var name=getPackageName('应用名'); //通过应用名获取app包名
console.log(name);
var name_1=getAppName("com.tencent.mobileqq"); //通过包名返回应用名
console.log(name_1);

////获取当前正在运行的应用的包名
var Package=currentPackage();//获取当前正在运行的应用的包名,此函数依赖于无障碍服务(未启动会报异常)
print(Package);//print、console.log、log都能打印日志
console.log(Package);

////获取当前正在运行的Activity的名称
var Activity=currentActivity()//获取当前正在运行的Activity的名称,此函数依赖于无障碍服务(未启动会报异常)
print(Activity)

var a=app.openAppSetting('包名');//打开应用的详情页(设置页)。如果找不到该应用返回false; 否则返回true。
log(a);


#元素定位
text("属性值").findOne().parent().click(); //parent通过子控件查找父控件,常用于子控件不能点击,而通过子控件查找到父控件完成点击
text("属性值").findOne().childCount(); //获取控件中子控件的数量
text("进入游戏").find().click(); //点击进入游戏(先查找再点击)
text("进入游戏").findOne(3000).click(); //点击进入游戏___查询超时就报错,,(text()是完全匹配)
textContains("手机").find().click(); //匹配页面包含手机的元素
textStartsWith("手机").find().click(); //匹配以"手机"开头的元素
textEndsWith("手机").find().click(); //匹配以"手机"结尾的元素
text("xxxx").find(); //按控件文本查找,,  也可使用findOne()
desc("xxxx").find(); //按描述信息查找
id("xxxx").find(); //按元素id查找元素
className("xxxx").find(); //按元素类型查找
atextMatches("\\d+"); //以正则匹配


#等待
sleep(random(1000,5000)); //随机等待1到5秒
sleep(2000); //等待2秒


#常用功能键
home(); //回到桌面
back(); //返回上一步


#常用操作
click(x,y); //单点击坐标
click('登录'); //点击text的元素
press(x,y,time); //按住坐标,time表示时间毫秒
swipe(x1,y1,x2,y2,time); //滑动屏幕(time表示滑动的时间)

  //从(500,800)的位置滑动到(500,300)的位置,再移动到(200,300)的位置,使用1000毫秒(1秒)的时间来完成滑动
  gesture(1000,[500,800],[500,300],[200,300]);

  gesture(1000,[500,800],[500,300]); //也可以两组滑动


#日志信息相关 toast("hallo word"); //在手机toast提示 toastLog('hallo word'); //toast提示+log记录 log('hallo word'); //记录log console.verbose("要输出的内容");//颜色为灰色(一般用来打印不重要内容) console.info("要输出的内容");//颜色为绿色(一般用来打印运行信息) console.warn("要输出的内容");//颜色为蓝色(一般用来打印运行警报) console.error("要输出的内容");//颜色为红色(一般用来打印运行报错信息) #对话框 alert("标题","内容"); //对话框输出

 

 

五、疑问解答

1.在脚本前面加auto();、auto、auto.waitFor()有什么作用?

 auto()函数来确保无障碍服务已经启用。如果运行到某个需要权限的语句无障碍服务并没启动,则会抛出异常并跳转到无障碍服务界面.

   auto.waitFor()检查无障碍服务是否已经启用,如果没有启用则跳转到无障碍服务启用界面,并等待无障碍服务启动;当无障碍服务启动后脚本会继续运行

   var a=auto.service 获取无障碍服务。如果无障碍服务没有启动,则返回null。

    备注:无障碍服务不能直接通过autojs打开,可以配合adb+设置无障碍快捷方式

2.autojs怎么运行?

  1.在手机上装了auto.js可以直接写代码运行,2.可以VS Code来编写脚本运行到手机(需要手机安装了autojs)

 3.Visual Studio Code可以连接模拟器吗?

 可以连接模拟器(vs code终端输入 adb connect 127.0.0.1:5037)

4.重启了VS Code为什么autojs连不上?

   重启后VS Code后 Auto.js: Start Server服务不会自动开启,需要手动启动

5.如何连接手机?

      1.开启AutoJS插件

        按 Ctrl+Shift+P 或点击"查看"->"命令面板"可调出命令面板,输入 Auto.js 可以看到几个命令,移动光标到命令Auto.js: Start Server,按回车键执行该命令。

       

 

   2.autojs连接VS Code

    将手机连接到电脑启用的Wifi或者同一局域网中。通过命令行ipconfig(或者其他操作系统的相同功能命令)查看电脑的IP地址。在Auto.js的侧拉菜单中启用调试服务,并输入IP地址,等待连接成功。 

      

 

     3.VS Code这样页面就连接成功了  

      

 

6.定时器或定时任务无法在手机黑屏操作(待确定)?

 可以在脚本前加个 device.wakeUp();就会自动点亮屏(1.黑屏非锁屏状态(休眠),2.usb连接电脑或插座充电)

 

 

相关连接:

https://blog.csdn.net/QiHsMing/article/details/86762007 ..........................在VS Code运行AutoJS(包含电脑端调试到手机,,页面布局)

https://blog.csdn.net/ss7379829/article/details/80819374 ........................VS Code中怎么运行js文件,,autojs pro版本在VS Code使用

https://pro.autojs.org/docs/#/zh-cn/ ..........................................................autojs官方教程

https://gitee.com/jianyue/autojsDemo?skip_mobile=true ..........................gitee的autojs案例

https://blog.csdn.net/zy0412326/article/details/117155945 ...............autojs打包成apk,,找图并点击

 https://blog.csdn.net/camel2014/article/details/104928199 .....................autojs模块调用(放到同一个目录下运行,必须是手机上的目录,不能pc F5,因为require的文件在pc上没有在手机上)

https://blog.csdn.net/yinmingxuan/article/details/90266388 ......................autojs实例教程,,autojs模块调用三种方法

https://space.bilibili.com/26079586 ...........................................................autojs视频,,UI教程

https://blog.csdn.net/qq_17175585/article/details/120279193 ..................线程通讯与线程详解

posted on 2020-06-09 18:22  chen_2987  阅读(12310)  评论(2编辑  收藏  举报

导航