一、介紹:
1.Auto.js是一款安卓應用,針對安卓7.0以上機型,它可以無需root執行腳本。主要是運用系統自帶的“無障礙服務”來獲取頁面的,這是個亮點,但有個缺陷就是每次關閉 Auto.js 這個app后都要重新開啟“無障礙服務”,頗為繁瑣。
2.Auto.js可以打包成apk直接裝到手機
3.Auto.js可以查看頁面布局,需要打開懸浮窗權限
二、簡單案例:
1.快手刷金幣
//判斷當前頁面是否有指定text if (text("發現").exists() || text("同城").exists()){ log('在設置頁面—記錄log')//可在手機的log中打印 sleep(500); swipe(500,1800,500,300,200);//上滑屏幕 } else{ toast('不在刷視頻頁面_刷不到金幣'); }
2.華為輔助安裝處理
//app.launchApp("設置");//打開應用 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('沒有應用安裝彈框'); }
3.oppo手機安裝處理
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('沒有應用安裝彈框_安裝出錯'); }
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);
三、語法案例
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) ////帶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('上傳文件成功') }
四、常用控件匯總
launchApp('名字'); //通過app名字啟動app應用 launch(‘app包名’); //通過包名啟動app應用 app.uninstall('包名'); //卸載app sleep(random(1000,5000)); //隨機等待1到5秒 swipe(x1,y1,x2,y2,time); //滑動屏幕(time表示滑動的時間) click(x,y); //單點擊坐標,, click("加好友"); //點擊"加好友"按鈕 press(x,y,time); //按住坐標,time表示時間好像是毫秒 home(); //回到桌面 back(); //返回上一步 getpackagename('應用名'); //通過應用名獲取app包名 toast("hallo word"); //在手機toast提示 toastLog('hallo word'); //提示信息+log記錄 log('hallo word'); //記錄log 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+"); //以正則匹配 setText("城南花已開") ; //在光標處輸入數據 alert("標題","內容"); //對話框輸出
五、疑問解答
1.在腳本前面加auto();、auto、auto.waitFor()有什么作用?
auto()
函數來確保無障礙服務已經啟用。如果運行到某個需要權限的語句無障礙服務並沒啟動,則會拋出異常並跳轉到無障礙服務界面.
相關連接:
https://blog.csdn.net/QiHsMing/article/details/86762007 .........................VS Code運行AutoJS(包含電腦端調試到手機,,頁面布局)
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