การทำงานอัตโนมัติพื้นฐาน¶
บทนี้จะอธิบายถึงฟังก์ชันพื้นฐานอัตโนมัติที่ FIRERPA มีให้ แน่นอนว่ายังมีการใช้งานขั้นสูงที่จะอธิบายในภายหลัง ในบทนี้จะแนะนำอินเทอร์เฟซฟังก์ชันพื้นฐานที่ใช้กันบ่อย
การรับข้อมูลอุปกรณ์¶
รับข้อมูลอุปกรณ์ปัจจุบัน เช่น ชื่ออุปกรณ์, ขนาดหน้าจอ, การหมุนหน้าจอ และแอปพลิเคชันปัจจุบัน
d.device_info()
>>> d.device_info()
productName: "bumblebee"
sdkInt: 34
displayHeight: 2400
displaySizeDpX: 411
displaySizeDpY: 914
displayWidth: 1080
screenOn: true
naturalOrientation: true
currentPackageName: "com.android.launcher3"
>>> result = d.device_info()
>>> print (result.displayWidth)
1080
การรับข้อมูลบริการ¶
รับข้อมูลของบริการปัจจุบัน เช่น เวอร์ชัน, ID เฉพาะของอุปกรณ์, เวอร์ชัน, ABI และข้อมูลอื่นๆ
d.server_info()
>>> d.server_info( )
uniqueId: "673abbe0-ff7b-9d82-1792-8876cb72cf56"
version: "8.28"
architecture: "arm64-v8a"
uptime: 293
secure: True
>>> result = d.server_info()
>>> print (result.secure)
False
ปิดหน้าจอ¶
อินเทอร์เฟซต่อไปนี้จะทำให้หน้าจอโทรศัพท์ปัจจุบันปิดลง ซึ่งเทียบเท่ากับการกดปุ่มเปิด/ปิดเครื่องหนึ่งครั้งเมื่อหน้าจอเปิดอยู่
d.sleep()
เปิดหน้าจอ¶
อินเทอร์เฟซต่อไปนี้จะทำให้หน้าจอโทรศัพท์ปัจจุบันเปิดขึ้น ซึ่งเทียบเท่ากับการกดปุ่มเปิด/ปิดเครื่องหนึ่งครั้งเมื่อหน้าจอปิดอยู่
d.wake_up()
หน้าจอเปิดอยู่หรือไม่¶
คุณสามารถใช้อินเทอร์เฟซต่อไปนี้เพื่อตรวจสอบว่าหน้าจอของอุปกรณ์ปัจจุบันเปิดอยู่หรือไม่ เพื่อตัดสินใจว่าจะสามารถดำเนินการต่อได้หรือไม่
d.is_screen_on()
หน้าจอล็อกอยู่หรือไม่¶
คุณสามารถใช้อินเทอร์เฟซต่อไปนี้เพื่อตรวจสอบว่าหน้าจอของอุปกรณ์ปัจจุบันถูกปลดล็อกอยู่หรือไม่ เพื่อตัดสินใจว่าจะสามารถดำเนินการต่อได้หรือไม่
d.is_screen_locked()
แสดง Toast¶
คุณสามารถใช้อินเทอร์เฟซต่อไปนี้เพื่อแสดงข้อความ Toast Hello from Lamda! บนหน้าจอโทรศัพท์
d.show_toast("Hello from Lamda!")
อ่านคลิปบอร์ด¶
อินเทอร์เฟซต่อไปนี้ใช้สำหรับอ่านเนื้อหาในคลิปบอร์ดปัจจุบันของโทรศัพท์ ยังไม่รองรับ Android 10+ ชั่วคราว
d.get_clipboard()
เขียนลงคลิปบอร์ด¶
อินเทอร์เฟซต่อไปนี้ใช้สำหรับเขียนเนื้อหาลงในคลิปบอร์ดของอุปกรณ์ปัจจุบัน
d.set_clipboard("เนื้อหาคลิปบอร์ด")
ปุ่มกดกายภาพ¶
คุณสามารถใช้วิธีการด้านล่างเพื่อจำลองการกดปุ่ม รองรับปุ่มต่างๆ กว่าสิบชนิด เช่น KEY_BACK, KEY_DOWN, KEY_HOME เป็นต้น
d.press_key(Keys.KEY_BACK)
d.press_key(Keys.KEY_CAMERA)
d.press_key(Keys.KEY_CENTER)
d.press_key(Keys.KEY_DELETE)
d.press_key(Keys.KEY_DOWN)
d.press_key(Keys.KEY_ENTER)
d.press_key(Keys.KEY_HOME)
d.press_key(Keys.KEY_LEFT)
d.press_key(Keys.KEY_MENU)
d.press_key(Keys.KEY_POWER)
d.press_key(Keys.KEY_RECENT)
d.press_key(Keys.KEY_RIGHT)
d.press_key(Keys.KEY_SEARCH)
d.press_key(Keys.KEY_UP)
d.press_key(Keys.KEY_VOLUME_DOWN)
d.press_key(Keys.KEY_VOLUME_MUTE)
d.press_key(Keys.KEY_VOLUME_UP)
นอกจากนี้ เพื่อรองรับปุ่มอื่นๆ เพิ่มเติม คุณยังสามารถใช้วิธีนี้ในการจำลองได้ คุณสามารถค้นหาชื่อปุ่มที่รองรับทั้งหมดได้ในเอกสารทางการของ Android ที่นี่ https://developer.android.com/reference/android/view/KeyEvent
d.press_keycode(KeyCodes.KEYCODE_CALL)
จับภาพหน้าจอ¶
เรามีวิธีการจับภาพหน้าจอเพื่อให้คุณสามารถบันทึกขั้นตอนการทำงานหรือทำการจดจำรูปภาพได้ การเรียกใช้ด้านล่างนี้หมายถึงการจับภาพที่มีคุณภาพ 60 และบันทึกเป็นไฟล์ screenshot.png ในไดเรกทอรีปัจจุบัน
d.screenshot(60).save("screenshot.png")
>>> result = d.screenshot(60)
>>> result
<lamda.types.BytesIO object at 0x7a28361d60>
>>> result.save("screenshot.png")
52917
>>> result.getvalue( )
b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01....'
ปัจจุบัน เรารองรับการจับภาพหน้าจอเฉพาะส่วนและเฉพาะองค์ประกอบ (element) การจับภาพเฉพาะองค์ประกอบจะไม่ได้อธิบายในบทนี้ ที่นี่เราจะแนะนำการจับภาพเฉพาะส่วน คุณจำเป็นต้องเข้าใจแนวคิดและคำจำกัดความของพื้นที่ ในอินเทอร์เฟซของเรา พื้นที่จะถูกกำหนดโดย Bound ซึ่งประกอบด้วยพารามิเตอร์สี่ตัว: top, left, right, bottom หน้าจอ Android มีระบบพิกัดที่แตกต่างจากระบบพิกัดทั่วไป โดยมุมบนซ้ายของหน้าจออุปกรณ์ปัจจุบันคือจุดกำเนิด (origin) ซึ่งมีพิกัดเป็น x=0, y=0 สมมติว่าหน้าจอปัจจุบันเป็นแนวตั้ง มีความละเอียด 1080x1920 หากคุณต้องการจับภาพหน้าจอเฉพาะส่วนแบบเต็มจอ คุณสามารถทำได้ดังนี้
d.screenshot(60, bound=Bound(top=0, left=0, right=1080, bottom=1920)).save("screenshot.png")
ซึ่งจะทำให้ได้ภาพหน้าจอแบบเต็มจอ แน่นอนว่านี่ไม่จำเป็น เพราะค่าเริ่มต้นคือการจับภาพเต็มจออยู่แล้ว ถ้าเราต้องการจับภาพขนาด 200x200 ที่มุมบนซ้าย จะทำอย่างไร? ก็ง่ายมาก เพียงแค่ทำตามด้านล่างนี้
d.screenshot(60, bound=Bound(top=0, left=0, right=200, bottom=200)).save("screenshot.png")
ถึงตรงนี้ เราจะอธิบายความหมายของพารามิเตอร์เหล่านี้ ในพารามิเตอร์ top หมายถึงระยะห่างจากแกน Y ลงมา top พิกเซล, bottom หมายถึงระยะห่างจากแกน Y ลงมา bottom พิกเซล, ส่วน left และ right หมายถึงระยะห่างจากแกน X ไปทางขวา N พิกเซล โดยที่ top จะน้อยกว่า bottom เสมอ และ left จะน้อยกว่า right เสมอ ต่อไปเราจะสาธิตอีกหนึ่งตัวอย่าง คือการจับภาพขนาด 200x200 ที่มุมล่างขวาของหน้าจอ คุณเพียงแค่เรียกใช้อินเทอร์เฟซดังนี้
d.screenshot(60, bound=Bound(top=1920-200, bottom=1920, left=1080-200, right=1080)).save("screenshot.png")
คลิกที่จุดหนึ่งบนหน้าจอ¶
คุณสามารถใช้อินเทอร์เฟซต่อไปนี้เพื่อจำลองการคลิกบนหน้าจอ ในตัวอย่าง เราได้คลิกที่จุดพิกัด 100,100 บนหน้าจอ
d.click(Point(x=100, y=100))
กดค้างที่จุด A แล้วลากไปยังจุด B¶
ด้วยอินเทอร์เฟซต่อไปนี้ คุณสามารถลากวัตถุจากตำแหน่งจุด A ไปยังจุด B ได้ เช่น การลากไอคอนไปยังโฟลเดอร์
A = Point(x=100, y=100)
B = Point(x=500, y=500)
d.drag(A, B)
ปัดจากจุด A ไปยังจุด B¶
ด้วยอินเทอร์เฟซต่อไปนี้ คุณสามารถทำการปัด (swipe) จากพิกัด 100x100 ไปยังพิกัด 500x500 บนหน้าจอได้
A = Point(x=100, y=100)
B = Point(x=500, y=500)
d.swipe(A, B)
การปัดหลายจุดที่ซับซ้อนขึ้น¶
อินเทอร์เฟซต่อไปนี้สามารถจำลองการปัดหลายจุดได้ เช่น การเรียกใช้ด้านล่างนี้จะปัดจาก 100x100 ไปยัง 500x500 แล้วกลับมาที่ 200x200 ในการสาธิตนี้มีการปัดเพียงสามจุด แต่ในความเป็นจริงคุณสามารถระบุจุดได้มากขึ้น หรือแม้กระทั่งใช้เพื่อปลดล็อกแบบลากเส้น (pattern unlock)
p1 = Point(x=100, y=100)
p2 = Point(x=500, y=500)
p3 = Point(x=200, y=200)
d.swipe_points(p1, p2, p3)
เปิดการตั้งค่าด่วน¶
การเรียกใช้ด้านล่างนี้สามารถเปิดแถบการแจ้งเตือนบนหน้าจอได้ แต่จะอยู่ในสถานะเปิดครึ่งหนึ่ง
d.open_quick_settings()
เปิดแถบการแจ้งเตือน¶
การเรียกใช้ด้านล่างนี้สามารถเปิดแถบการแจ้งเตือนบนหน้าจอได้
d.open_notification()
การรับโครงสร้างหน้าเว็บ (Layout)¶
การเรียกใช้ด้านล่างนี้สามารถรับโครงสร้าง XML ของหน้าปัจจุบันได้ คุณยังสามารถแยกวิเคราะห์ (parse) ด้วยตนเองเพื่อรองรับการทำงานอัตโนมัติด้วย xpath
d.dump_window_hierarchy()
>>> result = d.dump_window_hierarchy()
>>> result
<lamda.types.BytesIO object at 0x7add660680>
>>> result.getvalue()
b'<?xml version=\'1.0\' encoding=\'UTF-8\' standalone=\'yes\' ?>\r\n<hierarchy rotation="0">\r\n <node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="com.android.systemui" content-desc="" checkable="false" checked="false" clickable="false"...
รอให้หน้าต่างหยุดนิ่ง¶
คุณสามารถเรียกใช้คำสั่งต่อไปนี้เพื่อรอให้หน้าต่างปัจจุบันอยู่ในสถานะหยุดนิ่ง คล้ายกับ implicitly_wait ของ selenium พารามิเตอร์มีหน่วยเป็นมิลลิวินาที 5*1000 หมายถึงการรอ 5 วินาที โดย 1000 มิลลิวินาทีเท่ากับ 1 วินาที
d.wait_for_idle(5*1000)
การรับ Toast ล่าสุด¶
คุณสามารถเรียกใช้คำสั่งต่อไปนี้เพื่อรับข้อความ Toast ล่าสุดในระบบ แต่โปรดทราบว่ารองรับเฉพาะข้อความ Toast ที่ส่งโดย API ของระบบเท่านั้น ไม่สามารถรับข้อความที่มีลักษณะคล้าย Toast UI ที่สร้างโดยบุคคลที่สามได้
d.get_last_toast()
>>> result = d.get_last_toast()
>>> print (result)
timestamp: 1700000000000
package: "com.android.settings"
message: "\346\202\250\345\267\262\345\244\204\344\272\216\345\274\200\345\217\221\350\200\205\346\250\241\345\274\217\357\274\214\346\227\240\351\234\200\350\277\233\350\241\214\346\255\244\346\223\215\344\275\234\343\200\202"
>>> print (result.message)
คุณอยู่ในโหมดนักพัฒนาซอฟต์แวร์แล้ว ไม่จำเป็นต้องดำเนินการนี้