Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีจำลอง Touch Event ที่ตำแหน่งที่กำหนดใน Android

ภาพรวม

ตัวอย่างนี้สาธิตการรับและจัดการ Touch Event (onTouchEvent) ใน Activity เพื่อตรวจจับตำแหน่ง X, Y และประเภทการสัมผัส (Down, Move, Up)

📝 หมายเหตุ

หัวข้อ "Simulate touch event" (สร้าง Touch Event เทียม) จริงๆ ต้องใช้ Instrumentation หรือ adb shell input tap ซึ่งต้องการ Permission เฉพาะ แต่ตัวอย่างนี้เป็นการ รับและแสดง Touch Event จริง จากผู้ใช้

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

Android Studio → File → New Project → Empty Activity

ขั้นตอนที่ 2: จัดรูปแบบหน้าจอ (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="4dp"
    tools:context=".MainActivity">
</RelativeLayout>

ขั้นตอนที่ 3: เขียนโค้ด MainActivity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private boolean isTouch = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        int action = event.getAction();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                // นิ้วสัมผัสจอครั้งแรก
                Toast.makeText(this, "ACTION_DOWN - X: " + x + " Y: " + y, Toast.LENGTH_SHORT).show();
                isTouch = true;
                break;

            case MotionEvent.ACTION_MOVE:
                // นิ้วเลื่อนบนจอ
                // หมายเหตุ: จะยิง Event บ่อยมาก อาจล็อค UI ถ้าใช้ Toast ใน Loop
                // Toast.makeText(this, "MOVE - X: " + x + " Y: " + y, Toast.LENGTH_SHORT).show();
                break;

            case MotionEvent.ACTION_UP:
                // นิ้วปล่อยจอ
                Toast.makeText(this, "ACTION_UP - X: " + x + " Y: " + y, Toast.LENGTH_SHORT).show();
                break;

            case MotionEvent.ACTION_CANCEL:
                // Event ถูกยกเลิก (เช่น โทรศัพท์เข้า)
                break;

            case MotionEvent.ACTION_POINTER_DOWN:
            case MotionEvent.ACTION_POINTER_UP:
                // Multi-touch (นิ้วที่ 2, 3, ...)
                int pointerIndex = event.getActionIndex();
                int pointerId = event.getPointerId(pointerIndex);
                float px = event.getX(pointerIndex);
                float py = event.getY(pointerIndex);
                Toast.makeText(this, "Pointer " + pointerId + " - X: " + px + " Y: " + py, Toast.LENGTH_SHORT).show();
                break;
        }
        return true; // true = consume event, false = ส่งต่อให้ parent
    }
}

ขั้นตอนที่ 4: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                
                
            </intent-filter>
        </activity>

    </application>
</manifest>

การทดสอบ

รันแอป → กด/ลาก/ปล่อยบนหน้าจอ → จะแสดง Toast พร้อมพิกัด X, Y

วิธีจำลอง Touch Event ที่ตำแหน่งที่กำหนดใน Android วิธีจำลอง Touch Event ที่ตำแหน่งที่กำหนดใน Android

วิธี Simulate Touch Event จริง (Programmatic)

1. ใช้ Instrumentation (ต้องใช้ใน Test/Instrumented Test)

// ใน Instrumented Test (androidTest)
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
instrumentation.runOnMainSync(() -> {
    // Tap ที่พิกัด (500, 500)
    long downTime = SystemClock.uptimeMillis();
    MotionEvent downEvent = MotionEvent.obtain(downTime, downTime, 
        MotionEvent.ACTION_DOWN, 500, 500, 0);
    MotionEvent upEvent = MotionEvent.obtain(downTime, downTime + 100, 
        MotionEvent.ACTION_UP, 500, 500, 0);
    
    instrumentation.sendPointerSync(downEvent);
    instrumentation.sendPointerSync(upEvent);
});

2. ใช้ ADB Command (สำหรับ Developer/Automation)

# Tap ที่พิกัด (x, y)
adb shell input tap 500 500

# Swipe จาก (x1,y1) ไป (x2,y2) ใช้เวลา 300ms
adb shell input swipe 500 1000 500 500 300

# Text input
adb shell input text "Hello World"

3. ใช้ AccessibilityService (สำหรับ Automation App)

// ต้องการ BIND_ACCESSIBILITY_SERVICE permission และ User เปิดใน Settings
AccessibilityService service = ...;
GestureDescription.StrokeDescription stroke = new GestureDescription.StrokeDescription(
    Path().apply { moveTo(500f, 500f) }, 0, 100);
GestureDescription gesture = new GestureDescription.Builder().addStroke(stroke).build();
service.dispatchGesture(gesture, null, null);

สรุป MotionEvent Actions

Actionคำอธิบาย
ACTION_DOWNนิ้วสัมผัสครั้งแรก (เริ่ม Gesture)
ACTION_MOVEนิ้วเลื่อน (อาจเกิดหลายครั้งต่อวินาที)
ACTION_UPนิ้วปล่อย (จบ Gesture)
ACTION_CANCELGesture ถูกยกเลิก
ACTION_POINTER_DOWNนิ้วเพิ่มเติมสัมผัส (Multi-touch)
ACTION_POINTER_UPนิ้วเพิ่มเติมปล่อย
ACTION_HOVER_MOVEPointer (Mouse/Stylus) ลอยเหนือจอ