feat: 增加长按功能

This commit is contained in:
2026-07-14 12:55:47 +08:00
parent 5228188579
commit 2fdf3c3b9e
4 changed files with 76 additions and 6 deletions

View File

@@ -37,6 +37,9 @@ public class InputCommandHandler {
case "SWIPE": case "SWIPE":
handleSwipe(command); handleSwipe(command);
break; break;
case "LONG_PRESS":
handleLongPress(command);
break;
default: default:
Log.w(TAG, "Unknown action: " + action); Log.w(TAG, "Unknown action: " + action);
} }
@@ -82,6 +85,16 @@ public class InputCommandHandler {
injectSwipe(x1, y1, x2, y2, duration); injectSwipe(x1, y1, x2, y2, duration);
} }
private void handleLongPress(JsonObject command) {
float relX = command.get("x").getAsFloat();
float relY = command.get("y").getAsFloat();
int x = (int) (relX * screenWidth);
int y = (int) (relY * screenHeight);
Log.d(TAG, "Long press at: " + x + ", " + y);
injectLongPress(x, y);
}
private void injectTap(int x, int y) { private void injectTap(int x, int y) {
try { try {
Runtime.getRuntime().exec("input tap " + x + " " + y); Runtime.getRuntime().exec("input tap " + x + " " + y);
@@ -90,6 +103,15 @@ public class InputCommandHandler {
} }
} }
private void injectLongPress(int x, int y) {
try {
// 用起点和终点相同的 swipe 模拟长按,持续 1000ms
Runtime.getRuntime().exec("input swipe " + x + " " + y + " " + x + " " + y + " 1000");
} catch (Exception e) {
Log.e(TAG, "Error injecting long press event", e);
}
}
private void injectSwipe(int x1, int y1, int x2, int y2, long duration) { private void injectSwipe(int x1, int y1, int x2, int y2, long duration) {
try { try {
Runtime.getRuntime().exec("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + duration); Runtime.getRuntime().exec("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + duration);

View File

@@ -123,6 +123,11 @@ public class MainActivity extends AppCompatActivity {
public void onKeyEvent(int keyCode, int action) { public void onKeyEvent(int keyCode, int action) {
sendKeyCommand(keyCode, action); sendKeyCommand(keyCode, action);
} }
@Override
public void onLongPress(float relX, float relY) {
sendLongPressCommand(relX, relY);
}
}); });
updateUI(false); updateUI(false);
@@ -244,8 +249,9 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public void onDisconnected() { public void onDisconnected() {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "网络连接已断开", Toast.LENGTH_SHORT).show();
disconnect();
tvStatus.setText("状态: 远端已断开"); tvStatus.setText("状态: 远端已断开");
updateUI(false);
}); });
} }
}); });
@@ -327,6 +333,16 @@ public class MainActivity extends AppCompatActivity {
} }
} }
private void sendLongPressCommand(float relX, float relY) {
if (webRtcClient != null) {
JsonObject cmd = new JsonObject();
cmd.addProperty("action", "LONG_PRESS");
cmd.addProperty("x", relX);
cmd.addProperty("y", relY);
webRtcClient.sendControlCommand(cmd.toString());
}
}
private void disconnect() { private void disconnect() {
if (webRtcClient != null) { if (webRtcClient != null) {
webRtcClient.close(); webRtcClient.close();

View File

@@ -3,9 +3,12 @@ package com.ttstd.controller.view;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.SurfaceView; import android.view.SurfaceView;
import androidx.annotation.NonNull;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
@@ -25,11 +28,14 @@ public class RemoteTouchView extends SurfaceView {
private float lastAbsX; private float lastAbsX;
private float lastAbsY; private float lastAbsY;
private long swipeStartTime; private long swipeStartTime;
private boolean isLongPressed = false;
private GestureDetector gestureDetector;
public interface TouchEventListener { public interface TouchEventListener {
void onTouch(float relX, float relY); void onTouch(float relX, float relY);
void onSwipe(float relX1, float relY1, float relX2, float relY2, long duration); void onSwipe(float relX1, float relY1, float relX2, float relY2, long duration);
void onKeyEvent(int keyCode, int action); void onKeyEvent(int keyCode, int action);
void onLongPress(float relX, float relY);
} }
public RemoteTouchView(Context context) { public RemoteTouchView(Context context) {
@@ -50,6 +56,20 @@ public class RemoteTouchView extends SurfaceView {
private void init() { private void init() {
setFocusable(true); setFocusable(true);
setFocusableInTouchMode(true); setFocusableInTouchMode(true);
gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public void onLongPress(@NonNull MotionEvent e) {
if (listener != null) {
isLongPressed = true;
float relX = e.getX() / getWidth();
float relY = e.getY() / getHeight();
relX = Math.max(0, Math.min(1, relX));
relY = Math.max(0, Math.min(1, relY));
listener.onLongPress(relX, relY);
Log.d(TAG, "LongPress at: " + relX + ", " + relY);
}
}
});
} }
public void setTouchEventListener(TouchEventListener listener) { public void setTouchEventListener(TouchEventListener listener) {
@@ -76,6 +96,7 @@ public class RemoteTouchView extends SurfaceView {
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
gestureDetector.onTouchEvent(event);
if (listener == null) return super.onTouchEvent(event); if (listener == null) return super.onTouchEvent(event);
float absX = event.getX(); float absX = event.getX();
@@ -91,6 +112,7 @@ public class RemoteTouchView extends SurfaceView {
switch (event.getActionMasked()) { switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
isLongPressed = false;
lastTouchX = relX; lastTouchX = relX;
lastTouchY = relY; lastTouchY = relY;
lastAbsX = absX; lastAbsX = absX;
@@ -103,6 +125,9 @@ public class RemoteTouchView extends SurfaceView {
return true; return true;
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
if (isLongPressed) {
return true;
}
long duration = System.currentTimeMillis() - swipeStartTime; long duration = System.currentTimeMillis() - swipeStartTime;
float dx = Math.abs(relX - lastTouchX); float dx = Math.abs(relX - lastTouchX);
float dy = Math.abs(relY - lastTouchY); float dy = Math.abs(relY - lastTouchY);
@@ -140,4 +165,12 @@ public class RemoteTouchView extends SurfaceView {
cmd.addProperty("duration", duration); cmd.addProperty("duration", duration);
return cmd.toString(); return cmd.toString();
} }
public String createLongPressCommand(float relX, float relY) {
JsonObject cmd = new JsonObject();
cmd.addProperty("action", "LONG_PRESS");
cmd.addProperty("x", relX);
cmd.addProperty("y", relY);
return cmd.toString();
}
} }

View File

@@ -122,12 +122,11 @@ public class WebRtcClient {
if (newState == PeerConnection.IceConnectionState.CONNECTED) { if (newState == PeerConnection.IceConnectionState.CONNECTED) {
if (connectionListener != null) connectionListener.onConnectionEstablished(); if (connectionListener != null) connectionListener.onConnectionEstablished();
} else if (newState == PeerConnection.IceConnectionState.DISCONNECTED) { } else if (newState == PeerConnection.IceConnectionState.DISCONNECTED) {
// DISCONNECTED 可能是暂时的,通常建议观察一段时间或尝试重放信令 Log.w(TAG, "ICE Disconnected");
Log.w(TAG, "ICE Disconnected, waiting for recovery..."); if (connectionListener != null) connectionListener.onDisconnected();
} else if (newState == PeerConnection.IceConnectionState.FAILED) { } else if (newState == PeerConnection.IceConnectionState.FAILED) {
// FAILED 通常意味着需要重新发起呼叫 Log.e(TAG, "ICE Connection Failed");
if (connectionListener != null) connectionListener.onDisconnected(); if (connectionListener != null) connectionListener.onDisconnected();
// 这里可以触发重新创建 Offer 的逻辑
} }
} }