-坐標(biāo)操作)
1.前言坐標(biāo)操作是基于坐標(biāo)模擬人的點擊、長按、滑動、觸摸等操作。雖然這部分內(nèi)容比較簡單但是這是腳本開發(fā)最重要的部分。坐標(biāo)操作貫穿腳本的整個過程每個腳本開發(fā)軟件都會帶有這些功能我這里就不過多介紹。2.setScreenMetrics屏幕寬高設(shè)置函數(shù)需要傳遞兩個參數(shù)分別為屏幕寬度和屏幕高度參數(shù)類型均為數(shù)字單位均為像素。這個函數(shù)一般在多屏幕分辨率場景下使用用于指定當(dāng)前坐標(biāo)操作在哪個分辨率下完成的當(dāng)屏幕分辨率改變時會自動根據(jù)當(dāng)前屏幕分辨率進行校對。比如指定手機寬度為720和高度為1280點擊200,400坐標(biāo)到了手機寬度為360和高度為640的手機點擊坐標(biāo)自動轉(zhuǎn)換為100,200。通過轉(zhuǎn)換規(guī)則會發(fā)現(xiàn)坐標(biāo)轉(zhuǎn)換會完全按照屏幕比進行一比一轉(zhuǎn)換。其實我們在腳本開發(fā)過程中會在固定分辨率下完成腳本比如我常用的分辨率720*1280。。一般不會有人開發(fā)多個分辨率的腳本雖然坐標(biāo)操作會自動轉(zhuǎn)換但是圖像處理要做多個分辨率的處理腳本開發(fā)的工作量成倍增加。正常情況下我們會在固定屏幕分辨率下完成腳本后面無論是在模擬器還是虛擬機下運行腳本都采用這個分辨率。這種情況下根本不需要進行坐標(biāo)轉(zhuǎn)換因此這個函數(shù)大多數(shù)情況下不需要使用。3.坐標(biāo)信息我們平時說的屏幕分辨率為豎屏情況下的寬度和高度的像素值比如720*1280就是代表豎屏情況下屏幕寬度為720像素高度為1280像素。為了坐標(biāo)點擊更準(zhǔn)確腳本會以屏幕左上角為原點以向右為x軸正方向以向下為y軸正方向生成一個二維坐標(biāo)系。下面坐標(biāo)點擊的xy值都是代表這個坐標(biāo)系的值不會再過多介紹。一般情況下所有腳本軟件在豎屏情況下的橫縱坐標(biāo)設(shè)置都是這個情況。但是在橫屏情況下橫縱坐標(biāo)設(shè)置會五花八門這才是讓人頭疼的地方。autojs腳本腳本橫縱坐標(biāo)設(shè)置還是按照我上面說的規(guī)則以屏幕左上角為原點以向右為x軸正方向以向下為y軸正方向生成一個二維坐標(biāo)系。但是橫屏情況下豎屏情況下以寬度為橫坐標(biāo)橫屏情況下以高度為橫坐標(biāo)豎屏情況下以高度為縱坐標(biāo)橫屏情況下以寬度為縱坐標(biāo)。autojs比較好的就是原點還是左上角并且xy軸的正方向也沒有改變。如果你使用過按鍵精靈手機助手進行截圖會發(fā)現(xiàn)橫屏情況下的縱坐標(biāo)的正方向都會改變那才是讓人頭疼的為了不誤解大家我就不截圖按鍵精靈手機助手坐標(biāo)系了。默認(rèn)情況下使用此橫屏坐標(biāo)系如果不使用此坐標(biāo)系時會進行說明。其實腳本開發(fā)過程中我們根本不關(guān)心這個坐標(biāo)是怎么轉(zhuǎn)換的。雖然按鍵精靈手機助手橫屏轉(zhuǎn)換后坐標(biāo)系很難讓人理解但是按鍵精靈手機助手有自己的截圖和選點助手我們只要保證我們選點和點擊位置能夠與屏幕對應(yīng)就可以了到時候直接復(fù)制使用即可根本不需要關(guān)心坐標(biāo)系問題。如果你看過其他人講解的autojs腳本開發(fā)教程他們都會采用各種方式獲取屏幕坐標(biāo)點這種方式用于講解腳本還可以要是用于項目級別的腳本開發(fā)怎么辦尤其是圖像處理過程中一個處理就需要那么多點和顏色通過哪些方式開發(fā)個腳本得浪費都多少時間??赡苡行』锇檎f有個別教程上有截圖助手但是那些助手好獲取嗎真的好用嗎當(dāng)然沒有截圖助手難道就不能開發(fā)腳本了嗎當(dāng)然可以但是真的很慢很痛苦。我做了個豎屏的游戲腳本通過按鍵精靈手機助手獲取點坐標(biāo)因為豎屏情況下兩者點坐標(biāo)是一致的但是按鍵精靈手機助手和autojs的顏色表示不一致我當(dāng)初還沒有找到轉(zhuǎn)換規(guī)律。只能想通過按鍵精靈手機助手先獲取需要比對點的信息然后通過我封裝的按鍵精靈點信息到autojs點信息轉(zhuǎn)換的函數(shù)打印需要的信息這個過程很復(fù)雜就不介紹了。但是每個圖像處理我都得先運行代碼獲取轉(zhuǎn)換信息然后將信息替換到代碼然后再運行代碼檢查是否識別到。就是每個圖像處理我都得運行兩次autojs代碼才行還得配合按鍵精靈手機助手使用速度真的很慢。我比較慶幸的是這個項目是豎屏項目我如果剛接觸是橫屏項目沒有理解按鍵精靈手機助手和autojs腳本之間的坐標(biāo)轉(zhuǎn)換我真可能會放棄。那個游戲很老了是小時候那種直板機都可以玩的游戲。后來我去接觸橫屏游戲發(fā)現(xiàn)這種方式效率越來越低經(jīng)過一系列為了提高效率的各種方式我直接通過html封裝了兩個轉(zhuǎn)換頁面最終達成直接復(fù)制按鍵精靈生成的點顏色信轉(zhuǎn)換成自己需要的點顏色信息。后面會介紹坐標(biāo)轉(zhuǎn)換工具對于點顏色轉(zhuǎn)換工具在圖像處理模塊會進行介紹。4.無障礙操作1.click點擊屏幕需要傳遞兩個參數(shù)分別為x坐標(biāo)和y坐標(biāo)參數(shù)類型均為數(shù)字點擊過程大約150毫秒。2.longClick長按屏幕需要傳遞兩個參數(shù)分別為x坐標(biāo)和y坐標(biāo)參數(shù)類型均為數(shù)字長按過程大約600毫秒。3.press按住屏幕需要傳遞三個參數(shù)分別為x坐標(biāo)、y坐標(biāo)和按住時間參數(shù)類型均為數(shù)字。這個函數(shù)可以完成上面的click和longClick函數(shù)的功能按住時間較少時可以理解為點擊按住時間較長時間是可以理解為長按。一般對于上面兩個函數(shù)默認(rèn)操作時間不滿意時可以通過這個函數(shù)完成功能。4.swipe兩點之間滑動屏幕需要傳遞5個參數(shù)分別為滑動起始位置的x坐標(biāo)、滑動起始位置的y坐標(biāo)、滑動結(jié)束位置的x坐標(biāo)、滑動結(jié)束位置的y坐標(biāo)和滑動時長單位毫秒?yún)?shù)類型均為數(shù)字。我自己感覺這個滑動起始位置和結(jié)束位置很容易弄反了每次使用這個函數(shù)時可以自己將手指放在屏幕上試下然后再取點。5.gesture一個手指多點滑動屏幕需要傳遞兩個參數(shù)分別為滑動時長單位毫秒和點數(shù)組參數(shù)類型分別為數(shù)字和數(shù)組。這個函數(shù)過程類似屏幕滑動解鎖的過程。gesture(1000, [[30, 296], [454, 350], [127, 553], [489, 599]]);6.gestures一個手指多點滑動屏幕需要至少一個參數(shù)參數(shù)類型為數(shù)組。傳遞一個參數(shù)時功能和gesture函數(shù)一致gestures函數(shù)可以理解為多個gesture函數(shù)同時操作。每個參數(shù)數(shù)組包含至少三個值分別代表延遲多久執(zhí)行、執(zhí)行時長和第三值以后代表點數(shù)組。這個函數(shù)我不建議使用我發(fā)現(xiàn)這個函數(shù)穩(wěn)定性不太行。很容易導(dǎo)致應(yīng)用閃退。建議如果使用多手指滑動不如執(zhí)行g(shù)esture函數(shù)。gestures([0, 500, [1199, 527], [137, 500]], [500, 500, [743, 129], [389, 125]] );5.Root操作1.Tap使用方式以及作用與無障礙操作的click函數(shù)完全一致。但是Tap函數(shù)需要在Root權(quán)限的基礎(chǔ)上執(zhí)行效率遠低于click函數(shù)一般不會使用。2.Swipe使用方式以及作用與無障礙操作的swipe函數(shù)完全一致。但是Swipe函數(shù)需要在Root權(quán)限的基礎(chǔ)上執(zhí)行效率遠低于swipe函數(shù)一般不會使用。6.RootAutomator操作1.概況RootAutomator操作橫屏狀態(tài)下的坐標(biāo)系與按鍵精靈手機助手的坐標(biāo)系完全一致如果使用此對象進行坐標(biāo)系操作就不會涉及坐標(biāo)轉(zhuǎn)換。但是RootAutomator操作需要在root環(huán)境下完成目前很多手機已經(jīng)沒有root環(huán)境因此無障礙操作還是我們使用最多的坐標(biāo)操作?,F(xiàn)在是學(xué)習(xí)情況下橫屏條件下使用此對象操作坐標(biāo)的坐標(biāo)情況如下圖雖然這個坐標(biāo)系正方向感覺有點怪但是按鍵精靈手機助手的抓抓就是在此環(huán)境下完成的抓取的坐標(biāo)可以直接使用。如果腳本環(huán)境是支持root的情況下用RootAutomator操作坐標(biāo)也是不錯的選擇最起碼不用考慮坐標(biāo)轉(zhuǎn)換問題了但是還要配合顏色信息轉(zhuǎn)換工具完成轉(zhuǎn)換具體使用到此工具時候再進行介紹。但是哪怕在root環(huán)境下我也會通過無障礙操作坐標(biāo)因為無障礙兼容性最好操作速度也是最快的。2.構(gòu)造函數(shù)所有的RootAutomator操作都是通過構(gòu)造函數(shù)獲取的對象完成。也就是說使用RootAutomator操作之前先構(gòu)造這個對象然后通過這個對象調(diào)用里面的函數(shù)。構(gòu)造函數(shù)接受一個對象對象包含adb和inputDevice兩個參數(shù)參數(shù)分別代表是否使用adb權(quán)限和指定操作的設(shè)備參數(shù)類型分別為boolean和字符串類型。雖然這個構(gòu)造函數(shù)可以傳遞對象信息但是我們在使用時不需要進行傳遞使用默認(rèn)配置即可。這個對象參數(shù)我也沒有很深入的研究大家記得使用默認(rèn)即可因為整個RootAutomator操作一般情況下都不會使用對于這部分有所了解即可。let currentObj new RootAutomator(); getAutojsObjectFunctions(currentObj); // 獲取Autojs對象所有的函數(shù) function getAutojsObjectFunctions(obj) { if (obj null || typeof obj ! object) { console.log(參數(shù)必須是一個對象); return; } // 獲取對象自身的所有屬性名 var propertyNames Object.getOwnPropertyNames(obj); // 篩選出函數(shù)類型的屬性 var functionNames propertyNames.filter(function (prop) { return typeof obj[prop] function; }); if (functionNames.length 0) { console.log(該對象沒有函數(shù)屬性); return; } // 遍歷并打印每個函數(shù)的信息 functionNames.forEach(function (methodName) { // 按照指定格式打印 console.log(函數(shù)名: methodName ()); }); }3.exit退出函數(shù)用于銷毀創(chuàng)建的RootAutomator操作對象。如果想使用RootAutomator進行坐標(biāo)操作可以想通過構(gòu)造函數(shù)獲取操作對象然后進行一系列操作然后在腳本最后調(diào)用退出函數(shù)銷毀操作對象。也就是說整個腳本過程中可以通過構(gòu)造函數(shù)只創(chuàng)建一個RootAutomator對象在腳本最后只通過exit函數(shù)銷毀一次操作對象。其實我們真正腳本開發(fā)中我們使用最多的還是無障礙操作其他坐標(biāo)操作很少使用。注意如果用于簡單的功能測試時在操作函數(shù)調(diào)用之后加個延遲再調(diào)用exit函數(shù)。如果不加延遲會導(dǎo)致直接銷毀對象導(dǎo)致操作函數(shù)不生效。這種問題只是會出現(xiàn)在測試過程中由于exit函數(shù)比操作函數(shù)快導(dǎo)致未操作之前銷毀了對象。但是在實際腳本開發(fā)過程中坐標(biāo)操作和圖像處理配合使用exit函數(shù)也就執(zhí)行一次不會出現(xiàn)操作不執(zhí)行的情況就是腳本最后一個操作注意一下就行為了不出現(xiàn)問題可以在exit函數(shù)退出之前都加個500毫秒的延遲。4.tap點擊屏幕需要傳遞三個參數(shù)分別為x坐標(biāo)、y坐標(biāo)、操作id參數(shù)類型均為數(shù)字。這個函數(shù)的功能和無障礙的click函數(shù)功能類似RootAutomator對象下的操作函數(shù)都是有個操作id這個id是操作的唯一標(biāo)識用于區(qū)分不同的操作。后面操作函數(shù)的參數(shù)操作id功能相同不會再介紹。let currentObj new RootAutomator(); currentObj.tap(280, 540, 1); sleep(500); currentObj.exit();注意官方文檔中說操作id可以選填默認(rèn)為1但是我不傳遞操作id操作會不執(zhí)行。我們在單操作過程中為了保證函數(shù)執(zhí)行也手動填寫一個值為1的操作id。5.swipe兩點之間滑動屏幕需要傳遞6個參數(shù)分別為滑動起始位置的x坐標(biāo)、滑動起始位置的y坐標(biāo)、滑動結(jié)束位置的x坐標(biāo)、滑動結(jié)束位置的y坐標(biāo)、滑動時長單位毫秒和操作id參數(shù)類型均為數(shù)字。功能和無障礙操作的swipe函數(shù)類似。swipe函數(shù)傳參可以和官方文檔中說明一致滑動時長和操作id可以不傳遞。6.press與longPresspress代表觸摸屏幕需要傳遞四個參數(shù)分別為x坐標(biāo)、y坐標(biāo)、按下時間單位毫秒、操作id參數(shù)類型均為數(shù)字。longPress代表長時間觸摸屏幕需要傳遞三個參數(shù)分別為x坐標(biāo)、y坐標(biāo)、操作id。press可以和官方文檔中說明一致操作id可以不傳遞默認(rèn)為1。但是longPress官方文檔說可以傳遞按下時長實際上此函數(shù)只能傳遞上述三個參數(shù)最后一個參數(shù)操作id可以不傳遞。這兩個函數(shù)功能也類似只是longPress函數(shù)不能設(shè)置按下時間罷了。let currentObj new RootAutomator(); currentObj.press(574, 73, 100); sleep(1000); currentObj.exit();7.touchDown、touchMove和touchUptouchDown和touchMove分別代表手指按下和手指滑動均需要傳遞三個參數(shù)分別為x坐標(biāo)、y坐標(biāo)、操作id操作id可以不傳遞默認(rèn)為1。touchUp代表手指彈起只需要傳遞操作id這一個參數(shù)這個參數(shù)可以不傳遞默認(rèn)為1。通過這三個函數(shù)可以實現(xiàn)點擊、觸摸、滑動等操作這三個函數(shù)更像是將一個功能分步完成特別需要注意按下或者滑動后調(diào)用一下手指彈起函數(shù)。let currentObj new RootAutomator(); // 模擬點擊 currentObj.touchDown(574, 73); currentObj.touchUp(); sleep(1000); // 模擬滑動 currentObj.touchDown(116, 756, 2); currentObj.touchMove(326,748, 2); currentObj.touchUp(2); sleep(1000); currentObj.exit();7.RootAutomator2操作在官方第一代API文檔中存在RootAutomator2的相關(guān)內(nèi)容但是實際上autojs免費版根本沒有RootAutomator2對象。我們使用免費版參考第一代API文檔內(nèi)容能夠滿足大部分需求但是第一代API文檔中的部分內(nèi)容與我們autojs免費版有沖突甚至有些對象或者函數(shù)在免費版中根本不存在這也是制作autojs教程的原因。下面代碼證明了RootAutomator對象存在但是RootAutomator2對象不存在。if (typeof RootAutomator ! undefined) { console.log(存在RootAutomator對象); } else { console.log(不存在RootAutomator對象); } if (typeof RootAutomator2 ! undefined) { console.log(存在RootAutomator2對象); } else { console.log(不存在RootAutomator2對象); }8.總結(jié)對于autojs免費版來說坐標(biāo)操作有無障礙和RootAutomator兩種方式。豎屏狀態(tài)下兩者坐標(biāo)系是一致的。在橫屏狀態(tài)下無障礙的坐標(biāo)系利于理解RootAutomator的坐標(biāo)系和按鍵精靈手機助手一致。無障礙的坐標(biāo)系雖然和截圖軟件的坐標(biāo)系會有沖突但是配合后面的顏色信息轉(zhuǎn)換工具使用就不存在這個問題。哪怕使用RootAutomator不用轉(zhuǎn)換坐標(biāo)但是按鍵精靈手機助手的顏色信息和autojs的顏色信息有區(qū)別也要通過顏色信息轉(zhuǎn)換工具進行顏色轉(zhuǎn)換。因此無障礙的坐標(biāo)系沖突顯得不那么重要哪怕點擊操作只需要獲取轉(zhuǎn)換后的坐標(biāo)也有對應(yīng)的坐標(biāo)轉(zhuǎn)換工具。我不推薦RootAutomator的原因是現(xiàn)在很多環(huán)境是不支持Root的同時RootAutomator速度遠沒有無障礙快兼容性也沒無障礙好。