กลุ่มสื่อสาร QQ: 815453846 Discord: https://discord.gg/PbJhnZJKDd
ฉันไม่ได้ดูแลโปรเจ็กต์นี้มาระยะหนึ่งแล้ว (อาจจะสองปี) แต่เมื่อเร็ว ๆ นี้ฉันต้องศึกษาระบบอัตโนมัติแบบเนทีฟของ Android อีกครั้ง แน่นอนว่าฉันได้ตรวจสอบ Appium ด้วย หลังจากเปรียบเทียบแล้ว ฉันพบว่าความเร็วในการทำงานของโปรเจ็กต์ uiautomator2 ดีมากจริงๆ มันรวดเร็วตั้งแต่การตรวจจับองค์ประกอบไปจนถึงการคลิก ทั้งหมดใช้เวลาเป็นมิลลิวินาที และโค้ดก็เข้าใจง่ายกว่า ฉันไม่เคยคาดหวังว่าฉันจะเขียนโปรเจ็กต์มหัศจรรย์เช่นนี้มาก่อนได้อย่างไร โปรเจ็กต์ดีๆ แบบนี้จะปล่อยให้มันสะสมฝุ่นได้อย่างไร มันจำเป็นต้องได้รับการจัดระเบียบใหม่และโค้ดขยะบางส่วนควรได้รับการทำความสะอาด ดังนั้นเวอร์ชันโปรเจ็กต์จึงได้รับการอัปเกรดจาก 2.xx เป็น 3.xx
ผู้ใช้ที่ยังใช้เวอร์ชัน 2.xx สามารถดู 2to3 ก่อนตัดสินใจว่าจะอัพเกรดเป็น 3.xx หรือไม่ (โดยส่วนตัวผมแนะนำให้อัปเกรดเป็นอย่างยิ่ง)
ท้ายที่สุดแล้ว เวอร์ชัน 2 ถึง 3 ถือเป็นการอัพเกรดเวอร์ชันหลัก และฟังก์ชันต่างๆ มากมายได้ถูกลบออกไปแล้ว สิ่งแรกที่ต้องลบคือ atx-agent และอย่างที่สองคือมีฟังก์ชันที่เกี่ยวข้องกับ atx-agent มากมาย ฟังก์ชันที่เลิกใช้แล้ว เช่น init
หมายเลขเวอร์ชันของไลบรารีที่ต้องพึ่งพาต่างๆ
UiAutomator เป็นไลบรารี Java ที่จัดทำโดย Google สำหรับการทดสอบอัตโนมัติของ Android โดยอิงตามบริการการเข้าถึง มันมีประสิทธิภาพมากและสามารถทดสอบแอพของบุคคลที่สาม รับคุณสมบัติการควบคุมของแอพใด ๆ บนหน้าจอ และดำเนินการใด ๆ กับมันได้ แต่มีข้อเสียสองประการ: 1. สคริปต์ทดสอบสามารถใช้ได้เฉพาะภาษา Java เท่านั้น 2. การทดสอบ script จะต้องบรรจุลงในแพ็คเกจ jar หรือ apk และอัปโหลดไปยังอุปกรณ์จึงจะรันได้
เราหวังว่าตรรกะการทดสอบสามารถเขียนด้วยภาษา Python และสามารถควบคุมโทรศัพท์มือถือขณะทำงานบนคอมพิวเตอร์ได้ ฉันขอขอบคุณ Xiaocong He (@xiaocong) เป็นอย่างมากสำหรับการตระหนักถึงแนวคิดนี้ (ดู xiaocong/uiautomator) หลักการคือการเรียกใช้บริการ http rpc บนโทรศัพท์มือถือ เปิดฟังก์ชันใน uiautomator จากนั้นใช้ http เหล่านี้ อินเทอร์เฟซถูกห่อหุ้มไว้ในไลบรารี Python เนื่องจากไลบรารี xiaocong/uiautomator
ยังไม่ได้รับการอัพเดตเป็นเวลานาน ดังนั้นเราจึงแยกเวอร์ชันโดยตรง เพื่อให้แยกแยะได้ง่ายขึ้น เราได้เพิ่ม 2 openatx/uiautomator2 ในตอนท้าย ฉันยังแยกสำเนาของซอร์สโค้ดแพ็คเกจ Android ที่เกี่ยวข้อง openatx/android-uiautomator-server
นอกเหนือจากการแก้ไขข้อบกพร่องในไลบรารีดั้งเดิมแล้ว ยังมีการเพิ่มฟีเจอร์ใหม่ ๆ มากมายอีกด้วย ส่วนใหญ่จะประกอบด้วยส่วนต่างๆ ดังต่อไปนี้:
ให้ฉันอธิบายตรงนี้ก่อน เพราะหลายคนมักถามว่า openatx/uiautomator2 ไม่รองรับการทดสอบ iOS หากคุณต้องการการทดสอบอัตโนมัติของ iOS คุณสามารถไปที่ไลบรารี openatx/facebook-wda นี้
PS: ห้องสมุดแห่งนี้
https://github.com/NeteaseGame/ATXไม่ได้อยู่ในระหว่างการบำรุงรักษาอีกต่อไป โปรดเปลี่ยนใหม่โดยเร็วที่สุด
นี่คือคู่มืออ้างอิงฉบับย่อซึ่งเหมาะสำหรับผู้ที่เริ่มต้นแล้ว ยินดีรับฟังความคิดเห็น
ขั้นแรกให้เตรียมโทรศัพท์ Android หนึ่งเครื่อง (ไม่ใช่สองเครื่อง) โดยเปิด开发者选项
ไว้ เชื่อมต่อกับคอมพิวเตอร์ และตรวจสอบให้แน่ใจว่าคุณมองเห็นอุปกรณ์ที่เชื่อมต่ออยู่โดยเรียกใช้ adb devices
รัน pip3 install -U uiautomator2
เพื่อติดตั้ง uiautomator2
เรียกใช้ python
จากบรรทัดคำสั่งเพื่อเปิดหน้าต่างโต้ตอบของ python จากนั้นป้อนคำสั่งต่อไปนี้ลงในหน้าต่าง
import uiautomator2 as u2
d = u2 . connect () # connect to device
print ( d . info )
เมื่อคุณเห็นผลลัพธ์ที่คล้ายกับด้านล่างนี้ คุณสามารถเริ่มใช้ไลบรารีของเราอย่างเป็นทางการได้ เนื่องจากไลบรารี่นี้มีฟังก์ชั่นมากเกินไปและมีเนื้อหาอยู่เบื้องหลังมากมายจึงต้องอ่านช้าๆ....
{'currentPackageName': 'net.oneplus.launcher', 'displayHeight': 1920, 'displayRotation': 0, 'displaySizeDpX': 411, 'displaySizeDpY': 731, 'displayWidth': 1080, 'productName': 'OnePlus5', '
screenOn': True, 'sdkInt': 27, 'naturalOrientation': True}
นอกจากนี้ เพื่อรักษาเสถียรภาพ คุณต้องเปิดใช้งานการอนุญาตหน้าต่างลอยของ小黄车
บทความอ้างอิง py-uiautomator2 ให้บริการเป็นเวลานานผ่านหน้าต่างลอย
มักจะประสบความสำเร็จ แต่อาจมีเรื่องประหลาดใจ คุณสามารถเข้าร่วมกลุ่ม QQ เพื่อรายงานปัญหาได้ (หมายเลขกลุ่มอยู่ด้านบน) มีหนุ่มใหญ่หลายคนในกลุ่มที่สามารถช่วยคุณแก้ปัญหาได้
ขอขอบคุณผู้สนับสนุนของเราทุกคน!
ว่างเปล่า
แนะนำบทความดีๆ (ยินดีต้อนรับผมในกลุ่ม QQ สำหรับข้อเสนอแนะ)
成都-测试只会一点点
การติดตั้ง
เชื่อมต่อกับอุปกรณ์
บรรทัดคำสั่ง
การตั้งค่าส่วนกลาง
การจัดการแอป
UI อัตโนมัติ
ผู้ร่วมให้ข้อมูล
ใบอนุญาต
ติดตั้ง uiautomator2
pip install -U uiautomator2
ทดสอบว่าการติดตั้งสำเร็จหรือไม่ uiautomator2 --help
ตัวตรวจสอบ UI
pip install uiautodev
# 启动
uiauto.dev
เปิด https://uiauto.dev ในเบราว์เซอร์เพื่อดูโครงสร้างอินเทอร์เฟซของอุปกรณ์ปัจจุบัน
uiauto.dev
uiauto.dev เป็นโปรเจ็กต์ที่ไม่ขึ้นอยู่กับ uiautomator2 ซึ่งใช้ในการดูโครงสร้างเลเยอร์ เป็นเวอร์ชันที่ปรับปรุงใหม่ของตัวแก้ไขโปรเจ็กต์เก่า อาจมีค่าธรรมเนียมในอนาคต (ราคาคุ้มค่าเงินแน่นอน) เพื่อรองรับการบำรุงรักษาโปรเจ็กต์ปัจจุบันอย่างต่อเนื่อง หากสนใจสามารถเข้าร่วมกลุ่มเพื่อพูดคุย(รวมทั้งยื่นคำร้อง) กลุ่ม QQ 536481989
ใช้ serialno เพื่อเชื่อมต่ออุปกรณ์เช่น 123456f
(ดูจาก adb devices
)
import uiautomator2 as u2
d = u2 . connect ( '123456f' ) # alias for u2.connect_usb('123456f')
print ( d . info )
Serial สามารถส่งผ่าน env-var ANDROID_SERIAL
# export ANDROID_SERIAL=123456f
d = u2 . connect ()
$device_ip
แสดงถึงที่อยู่ IP ของอุปกรณ์
หากคุณต้องการระบุอุปกรณ์ คุณจะต้องส่งผ่านใน --serial
เช่น python3 -m uiautomator2 --serial bff1234 <SubCommand>
, SubCommand เป็นคำสั่งย่อย (ภาพหน้าจอ ปัจจุบัน ฯลฯ)
1.0.3 เพิ่ม:
python3 -m uiautomator2
เท่ากับuiautomator2
ภาพหน้าจอ: ภาพหน้าจอ
$ uiautomator2 screenshot screenshot.jpg
ปัจจุบัน: รับชื่อแพ็คเกจและกิจกรรมปัจจุบัน
$ uiautomator2 current
{
" package " : " com.android.browser " ,
" activity " : " com.uc.browser.InnerUCMobile " ,
" pid " : 28478
}
ถอนการติดตั้ง: ถอนการติดตั้งแอป
$ uiautomator2 uninstall < package-name > # 卸载一个包
$ uiautomator2 uninstall < package-name- 1> < package-name- 2> # 卸载多个包
$ uiautomator2 uninstall --all # 全部卸载
หยุด: หยุดแอป
$ uiautomator2 stop com.example.app # 停止一个app
$ uiautomator2 stop --all # 停止所有的app
หมอ:
$ uiautomator2 doctor
[I 2024-04-25 19:53:36,288 __main__:101 pid:15596] uiautomator2 is OK
เมื่อ python หยุดทำงาน บริการ UiAutomation ก็จะหยุดทำงานเช่นกัน
พิมพ์ข้อมูลคำขอ HTTP ด้านหลังโค้ด
> >> d . debug = True
> >> d . info
12 : 32 : 47.182 $ curl - X POST - d '{"jsonrpc": "2.0", "id": "b80d3a488580be1f3e9cb3e926175310", "method": "deviceInfo", "params": {}}' 'http://127.0.0.1:54179/jsonrpc/0'
12 : 32 : 47.225 Response >> >
{ "jsonrpc" : "2.0" , "id" : "b80d3a488580be1f3e9cb3e926175310" , "result" :{ "currentPackageName" : "com.android.mms" , "displayHeight" : 1920 , "displayRotation" : 0 , "displaySizeDpX" : 360 , "displaySizeDpY" : 640 , "displayWidth" : 1080 , "productName"
: "odin" , "screenOn" : true , "sdkInt" : 25 , "naturalOrientation" : true }}
< << END
ตั้งเวลารอการค้นหาองค์ประกอบ (ค่าเริ่มต้น 20 วินาที)
d . implicitly_wait ( 10.0 ) # 也可以通过d.settings['wait_timeout'] = 10.0 修改
d ( text = "Settings" ). click () # if Settings button not show in 10s, UiObjectNotFoundError will raised
print ( "wait timeout" , d . implicitly_wait ()) # get default implicit wait
ฟังก์ชั่นนี้จะมีอิทธิพลต่อ click
, long_click
, drag_to
, get_text
, set_text
, clear_text
ฯลฯ
ส่วนนี้จะแสดงวิธีการจัดการแอป
เรารองรับการติดตั้ง APK จาก URL เท่านั้น
d . app_install ( 'http://some-domain.com/some.apk' )
# 默认的这种方法是先通过atx-agent解析apk包的mainActivity,然后调用am start -n $package/$activity启动
d . app_start ( "com.example.hello_world" )
# 使用 monkey -p com.example.hello_world -c android.intent.category.LAUNCHER 1 启动
# 这种方法有个副作用,它自动会将手机的旋转锁定给关掉
d . app_start ( "com.example.hello_world" , use_monkey = True ) # start with package name
# 通过指定main activity的方式启动应用,等价于调用am start -n com.example.hello_world/.MainActivity
d . app_start ( "com.example.hello_world" , ".MainActivity" )
# equivalent to `am force-stop`, thus you could lose data
d . app_stop ( "com.example.hello_world" )
# equivalent to `pm clear`
d . app_clear ( 'com.example.hello_world' )
# stop all
d . app_stop_all ()
# stop all app except for com.examples.demo
d . app_stop_all ( excludes = [ 'com.examples.demo' ])
d . app_info ( "com.examples.demo" )
# expect output
#{
# "mainActivity": "com.github.uiautomator.MainActivity",
# "label": "ATX",
# "versionName": "1.1.7",
# "versionCode": 1001007,
# "size":1760809
#}
# save app icon
img = d . app_icon ( "com.examples.demo" )
img . save ( "icon.png" )
d . app_list_running ()
# expect output
# ["com.xxxx.xxxx", "com.github.uiautomator", "xxxx"]
pid = d . app_wait ( "com.example.android" ) # 等待应用运行, return pid(int)
if not pid :
print ( "com.example.android is not running" )
else :
print ( "com.example.android pid is %d" % pid )
d . app_wait ( "com.example.android" , front = True ) # 等待应用前台运行
d . app_wait ( "com.example.android" , timeout = 20.0 ) # 最长等待时间20s(默认)
เพิ่มในเวอร์ชัน 1.2.0
พุชไฟล์ไปที่อุปกรณ์
# push to a folder
d . push ( "foo.txt" , "/sdcard/" )
# push and rename
d . push ( "foo.txt" , "/sdcard/bar.txt" )
# push fileobj
with open ( "foo.txt" , 'rb' ) as f :
d . push ( f , "/sdcard/" )
# push and change file access mode
d . push ( "foo.sh" , "/data/local/tmp/" , mode = 0o755 )
ดึงไฟล์ออกจากอุปกรณ์
d . pull ( "/sdcard/tmp.txt" , "tmp.txt" )
# FileNotFoundError will raise if the file is not found on the device
d . pull ( "/sdcard/some-file-not-exists.txt" , "tmp.txt" )
# grant all the permissions
d . app_auto_grant_permissions ( "io.appium.android.apis" )
# open scheme
d . open_url ( "appname://appnamehost" )
# same as
# adb shell am start -a android.intent.action.VIEW -d "appname://appnamehost"
ส่วนนี้จะแสดงวิธีการใช้งานอุปกรณ์ทั่วไป:
รันคำสั่งเชลล์อายุสั้นพร้อมการป้องกันการหมดเวลา (การหมดเวลาเริ่มต้น 60 วินาที)
หมายเหตุ: การสนับสนุนการหมดเวลาต้องใช้ atx-agent >=0.3.3
ฟังก์ชัน adb_shell
เลิกใช้แล้ว ใช้ shell
แทน
การใช้งานที่เรียบง่าย
output , exit_code = d . shell ( "pwd" , timeout = 60 ) # timeout 60s (Default)
# output: "/n", exit_code: 0
# Similar to command: adb shell pwd
# Since `shell` function return type is `namedtuple("ShellResponse", ("output", "exit_code"))`
# so we can do some tricks
output = d . shell ( "pwd" ). output
exit_code = d . shell ( "pwd" ). exit_code
อาร์กิวเมนต์แรกสามารถเป็นรายการได้
output , exit_code = d . shell ([ "ls" , "-l" ])
# output: "/....", exit_code: 0
สิ่งนี้จะส่งคืนสตริงสำหรับ stdout ที่ผสานกับ stderr หากคำสั่งเป็นคำสั่งบล็อก shell
จะบล็อกจนกว่าคำสั่งจะเสร็จสมบูรณ์หรือหมดเวลาใช้งาน โดยจะไม่ได้รับเอาต์พุตบางส่วนระหว่างการดำเนินการของคำสั่ง adb
adb shell
shell
สั่งที่รันนาน
รันคำสั่งเชลล์ที่ใช้เวลานาน (ลบออก)
เซสชันแสดงถึงวงจรชีวิตของแอป สามารถใช้เพื่อเริ่มแอป ตรวจจับข้อขัดข้องของแอป
เปิดและปิดแอป
sess = d . session ( "com.netease.cloudmusic" ) # start 网易云音乐
sess . close () # 停止网易云音乐
sess . restart () # 冷启动网易云音乐
ใช้ python with
เพื่อเปิดและปิดแอป
with d . session ( "com.netease.cloudmusic" ) as sess :
sess ( text = "Play" ). click ()
แนบไปกับแอปที่รันอยู่
# launch app if not running, skip launch if already running
sess = d . session ( "com.netease.cloudmusic" , attach = True )
ตรวจจับความผิดพลาดของแอพ
# When app is still running
sess ( text = "Music" ). click () # operation goes normal
# If app crash or quit
sess ( text = "Music" ). click () # raise SessionBrokenError
# other function calls under session will raise SessionBrokenError too
# check if session is ok.
# Warning: function name may change in the future
sess . running () # True or False
รับข้อมูลพื้นฐาน
d . info
ด้านล่างนี้เป็นผลลัพธ์ที่เป็นไปได้:
{'currentPackageName': 'com.android.systemui',
'displayHeight': 1560,
'displayRotation': 0,
'displaySizeDpX': 360,
'displaySizeDpY': 780,
'displayWidth': 720,
'naturalOrientation': True,
'productName': 'ELE-AL00',
'screenOn': True,
'sdkInt': 29}
รับขนาดหน้าต่าง
print ( d . window_size ())
# device upright output example: (1080, 1920)
# device horizontal output example: (1920, 1080)
รับข้อมูลแอปปัจจุบัน สำหรับอุปกรณ์ Android บางรุ่น ผลลัพธ์อาจว่างเปล่า (ดู ตัวอย่างผลลัพธ์ 3 )
print ( d . app_current ())
# Output example 1: {'activity': '.Client', 'package': 'com.netease.example', 'pid': 23710}
# Output example 2: {'activity': '.Client', 'package': 'com.netease.example'}
# Output example 3: {'activity': None, 'package': None}
รอกิจกรรม.
d . wait_activity ( ".ApiDemos" , timeout = 10 ) # default timeout 10.0 seconds
# Output: true of false
รับหมายเลขซีเรียลของอุปกรณ์
print ( d . serial )
# output example: 74aAEDR428Z9
รับไอพี WLAN
print ( d . wlan_ip )
# output example: 10.0.0.1 or None
รับข้อมูลอุปกรณ์โดยละเอียด d.device_info
อุปกรณ์_ข้อมูล
print ( d . device_info )
ด้านล่างนี้เป็นผลลัพธ์ที่เป็นไปได้:
{'arch': 'arm64-v8a',
'brand': 'google',
'model': 'sdk_gphone64_arm64',
'sdk': 34,
'serial': 'EMULATOR34X1X19X0',
'version': 14}
รับเนื้อหาคลิปบอร์ดชุด
ตั้งค่าเนื้อหาบอร์ดพาสหรือรับเนื้อหา
คลิปบอร์ด/set_clipboard
d . clipboard = 'hello-world'
# or
d . set_clipboard ( 'hello-world' , 'label' )
รับเนื้อหาคลิปบอร์ด
รับคลิปบอร์ดต้องใช้ IME(com.github.uiautomator/.AdbKeyboard) โทร
d.set_input_ime()
ก่อนใช้งาน
```python
# get clipboard content
print(d.clipboard)
```
เปิด/ปิดหน้าจอ
d . screen_on () # turn on the screen
d . screen_off () # turn off the screen
รับสถานะหน้าจอปัจจุบัน
d . info . get ( 'screenOn' ) # require Android >= 4.4
กดปุ่มฮาร์ด/ซอฟท์
d . press ( "home" ) # press the home key, with key name
d . press ( "back" ) # press the back key, with key name
d . press ( 0x07 , 0x02 ) # press keycode 0x07('0') with META ALT(0x02)
ชื่อคีย์เหล่านี้ได้รับการสนับสนุนในปัจจุบัน:
คุณสามารถค้นหาคำจำกัดความของรหัสคีย์ทั้งหมดได้ที่ Android KeyEvnet
ปลดล็อคหน้าจอ
d . unlock ()
# This is equivalent to
# 1. press("power")
# 2. swipe from left-bottom to right-top
คลิกบนหน้าจอ
d . click ( x , y )
ดับเบิลคลิก
d . double_click ( x , y )
d . double_click ( x , y , 0.1 ) # default duration between two click is 0.1s
ลองคลิกบนหน้าจอ
d . long_click ( x , y )
d . long_click ( x , y , 0.5 ) # long click 0.5s (default)
ปัด
d . swipe ( sx , sy , ex , ey )
d . swipe ( sx , sy , ex , ey , 0.5 ) # swipe for 0.5s(default)
ฟังก์ชั่นส่วนขยาย SwipeExt
d . swipe_ext ( "right" ) # 手指右滑,4选1 "left", "right", "up", "down"
d . swipe_ext ( "right" , scale = 0.9 ) # 默认0.9, 滑动距离为屏幕宽度的90%
d . swipe_ext ( "right" , box = ( 0 , 0 , 100 , 100 )) # 在 (0,0) -> (100, 100) 这个区域做滑动
# 实践发现上滑或下滑的时候,从中点开始滑动成功率会高一些
d . swipe_ext ( "up" , scale = 0.8 ) # 代码会vkk
# 还可以使用Direction作为参数
from uiautomator2 import Direction
d . swipe_ext ( Direction . FORWARD ) # 页面下翻, 等价于 d.swipe_ext("up"), 只是更好理解
d . swipe_ext ( Direction . BACKWARD ) # 页面上翻
d . swipe_ext ( Direction . HORIZ_FORWARD ) # 页面水平右翻
d . swipe_ext ( Direction . HORIZ_BACKWARD ) # 页面水平左翻
ลาก
d . drag ( sx , sy , ex , ey )
d . drag ( sx , sy , ex , ey , 0.5 ) # swipe for 0.5s(default)
ปัดจุด
# swipe from point(x0, y0) to point(x1, y1) then to point(x2, y2)
# time will speed 0.2s bwtween two points
d . swipe_points ([( x0 , y0 ), ( x1 , y1 ), ( x2 , y2 )], 0.2 ))
ส่วนใหญ่จะใช้เพื่อปลดล็อครูปแบบ Jiugong สามารถรับพิกัดสัมพัทธ์ของแต่ละจุดล่วงหน้าได้ (รองรับเปอร์เซ็นต์ที่นี่) สำหรับการใช้งานโดยละเอียดเพิ่มเติม โปรดดูที่โพสต์นี้
แตะแล้ววาง (เบต้า)
อินเทอร์เฟซนี้เป็นอินเทอร์เฟซดั้งเดิมระดับต่ำ แม้จะดูไม่สมบูรณ์แบบ แต่ก็ใช้งานได้ หมายเหตุ: สถานที่นี้ไม่รองรับเปอร์เซ็นต์
d . touch . down ( 10 , 10 ) # 模拟按下
time . sleep ( .01 ) # down 和 move 之间的延迟,自己控制
d . touch . move ( 15 , 15 ) # 模拟移动
d . touch . up ( 10 , 10 ) # 模拟抬起
หมายเหตุ: การคลิก ปัด และลาก รองรับค่าตำแหน่งเป็นเปอร์เซ็นต์ ตัวอย่าง:
d.long_click(0.5, 0.5)
หมายถึง คลิกยาวตรงกลางหน้าจอ
ดึง/ตั้งค่าการวางแนวอุปกรณ์
ทิศทางที่เป็นไปได้:
natural
หรือ n
left
หรือ l
right
หรือ r
upsidedown
หรือ u
(ไม่สามารถตั้งค่าได้) # retrieve orientation. the output could be "natural" or "left" or "right" or "upsidedown"
orientation = d . orientation
# WARNING: not pass testing in my TT-M1
# set orientation and freeze rotation.
# notes: setting "upsidedown" requires Android>=4.3.
d . set_orientation ( 'l' ) # or "left"
d . set_orientation ( "l" ) # or "left"
d . set_orientation ( "r" ) # or "right"
d . set_orientation ( "n" ) # or "natural"
การหมุนการแช่แข็ง/ยกเลิกการแช่แข็ง
# freeze rotation
d . freeze_rotation ()
# un-freeze rotation
d . freeze_rotation ( False )
จับภาพหน้าจอ
# take screenshot and save to a file on the computer, require Android>=4.2.
d . screenshot ( "home.jpg" )
# get PIL.Image formatted images. Naturally, you need pillow installed first
image = d . screenshot () # default format="pillow"
image . save ( "home.jpg" ) # or home.png. Currently, only png and jpg are supported
# get opencv formatted images. Naturally, you need numpy and cv2 installed first
import cv2
image = d . screenshot ( format = 'opencv' )
cv2 . imwrite ( 'home.jpg' , image )
# get raw jpeg data
imagebin = d . screenshot ( format = 'raw' )
open ( "some.jpg" , "wb" ). write ( imagebin )
ลำดับชั้น UI การถ่ายโอนข้อมูล
# get the UI hierarchy dump content
xml = d . dump_hierarchy ()
# compressed=True: include not import nodes
# pretty: format xml
# max_depth: limit xml depth, default 50
xml = d . dump_hierarchy ( compressed = False , pretty = False , max_depth = 50 )
เปิดการแจ้งเตือนหรือการตั้งค่าด่วน
d . open_notification ()
d . open_quick_settings ()
ตัวเลือกเป็นกลไกที่มีประโยชน์ในการระบุวัตถุ UI เฉพาะในหน้าต่างปัจจุบัน
# Select the object with text 'Clock' and its className is 'android.widget.TextView'
d ( text = 'Clock' , className = 'android.widget.TextView' )
ตัวเลือกรองรับพารามิเตอร์ด้านล่าง โปรดดูเอกสาร UiSelector Java สำหรับข้อมูลโดยละเอียด
text
, textContains
, textMatches
, textStartsWith
className
, classNameMatches
description
, descriptionContains
, descriptionMatches
, descriptionStartsWith
checkable
, checked
, clickable
, longClickable
scrollable
, enabled
, focusable
, focused
, selected
packageName
, packageNameMatches
resourceId
, resourceIdMatches
index
, instance
เด็ก
# get the children or grandchildren
d ( className = "android.widget.ListView" ). child ( text = "Bluetooth" )
พี่น้อง