ภาพรวม
ตัวอย่างนี้สาธิตการรับและจัดการ 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
วิธี 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_CANCEL | Gesture ถูกยกเลิก |
| ACTION_POINTER_DOWN | นิ้วเพิ่มเติมสัมผัส (Multi-touch) |
| ACTION_POINTER_UP | นิ้วเพิ่มเติมปล่อย |
| ACTION_HOVER_MOVE | Pointer (Mouse/Stylus) ลอยเหนือจอ |