การทำงานอัตโนมัติพื้นฐาน

บทนี้จะอธิบายถึงฟังก์ชันพื้นฐานอัตโนมัติที่ 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)
คุณอยู่ในโหมดนักพัฒนาซอฟต์แวร์แล้ว ไม่จำเป็นต้องดำเนินการนี้