diff --git a/WebRTCControlled/app/src/main/java/com/ttstd/controlled/input/InputCommandHandler.java b/WebRTCControlled/app/src/main/java/com/ttstd/controlled/input/InputCommandHandler.java index 1fdcc28..a9ced1e 100644 --- a/WebRTCControlled/app/src/main/java/com/ttstd/controlled/input/InputCommandHandler.java +++ b/WebRTCControlled/app/src/main/java/com/ttstd/controlled/input/InputCommandHandler.java @@ -37,6 +37,9 @@ public class InputCommandHandler { case "SWIPE": handleSwipe(command); break; + case "LONG_PRESS": + handleLongPress(command); + break; default: Log.w(TAG, "Unknown action: " + action); } @@ -82,6 +85,16 @@ public class InputCommandHandler { 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) { try { 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) { try { Runtime.getRuntime().exec("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + duration); diff --git a/WebRTCController/app/src/main/java/com/ttstd/controller/MainActivity.java b/WebRTCController/app/src/main/java/com/ttstd/controller/MainActivity.java index a01e5cf..cc66828 100644 --- a/WebRTCController/app/src/main/java/com/ttstd/controller/MainActivity.java +++ b/WebRTCController/app/src/main/java/com/ttstd/controller/MainActivity.java @@ -123,6 +123,11 @@ public class MainActivity extends AppCompatActivity { public void onKeyEvent(int keyCode, int action) { sendKeyCommand(keyCode, action); } + + @Override + public void onLongPress(float relX, float relY) { + sendLongPressCommand(relX, relY); + } }); updateUI(false); @@ -244,8 +249,9 @@ public class MainActivity extends AppCompatActivity { @Override public void onDisconnected() { runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "网络连接已断开", Toast.LENGTH_SHORT).show(); + disconnect(); 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() { if (webRtcClient != null) { webRtcClient.close(); diff --git a/WebRTCController/app/src/main/java/com/ttstd/controller/view/RemoteTouchView.java b/WebRTCController/app/src/main/java/com/ttstd/controller/view/RemoteTouchView.java index ce4d519..58dcc39 100644 --- a/WebRTCController/app/src/main/java/com/ttstd/controller/view/RemoteTouchView.java +++ b/WebRTCController/app/src/main/java/com/ttstd/controller/view/RemoteTouchView.java @@ -3,9 +3,12 @@ package com.ttstd.controller.view; import android.content.Context; import android.util.AttributeSet; import android.util.Log; +import android.view.GestureDetector; import android.view.MotionEvent; import android.view.SurfaceView; +import androidx.annotation.NonNull; + import com.google.gson.Gson; import com.google.gson.JsonObject; @@ -25,11 +28,14 @@ public class RemoteTouchView extends SurfaceView { private float lastAbsX; private float lastAbsY; private long swipeStartTime; + private boolean isLongPressed = false; + private GestureDetector gestureDetector; public interface TouchEventListener { void onTouch(float relX, float relY); void onSwipe(float relX1, float relY1, float relX2, float relY2, long duration); void onKeyEvent(int keyCode, int action); + void onLongPress(float relX, float relY); } public RemoteTouchView(Context context) { @@ -50,6 +56,20 @@ public class RemoteTouchView extends SurfaceView { private void init() { setFocusable(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) { @@ -76,6 +96,7 @@ public class RemoteTouchView extends SurfaceView { @Override public boolean onTouchEvent(MotionEvent event) { + gestureDetector.onTouchEvent(event); if (listener == null) return super.onTouchEvent(event); float absX = event.getX(); @@ -91,6 +112,7 @@ public class RemoteTouchView extends SurfaceView { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: + isLongPressed = false; lastTouchX = relX; lastTouchY = relY; lastAbsX = absX; @@ -103,6 +125,9 @@ public class RemoteTouchView extends SurfaceView { return true; case MotionEvent.ACTION_UP: + if (isLongPressed) { + return true; + } long duration = System.currentTimeMillis() - swipeStartTime; float dx = Math.abs(relX - lastTouchX); float dy = Math.abs(relY - lastTouchY); @@ -140,4 +165,12 @@ public class RemoteTouchView extends SurfaceView { cmd.addProperty("duration", duration); 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(); + } } diff --git a/WebRTCController/app/src/main/java/com/ttstd/controller/webrtc/WebRtcClient.java b/WebRTCController/app/src/main/java/com/ttstd/controller/webrtc/WebRtcClient.java index df2c4a5..abc4e5d 100644 --- a/WebRTCController/app/src/main/java/com/ttstd/controller/webrtc/WebRtcClient.java +++ b/WebRTCController/app/src/main/java/com/ttstd/controller/webrtc/WebRtcClient.java @@ -122,12 +122,11 @@ public class WebRtcClient { if (newState == PeerConnection.IceConnectionState.CONNECTED) { if (connectionListener != null) connectionListener.onConnectionEstablished(); } else if (newState == PeerConnection.IceConnectionState.DISCONNECTED) { - // DISCONNECTED 可能是暂时的,通常建议观察一段时间或尝试重放信令 - Log.w(TAG, "ICE Disconnected, waiting for recovery..."); - } else if (newState == PeerConnection.IceConnectionState.FAILED) { - // FAILED 通常意味着需要重新发起呼叫 + Log.w(TAG, "ICE Disconnected"); + if (connectionListener != null) connectionListener.onDisconnected(); + } else if (newState == PeerConnection.IceConnectionState.FAILED) { + Log.e(TAG, "ICE Connection Failed"); if (connectionListener != null) connectionListener.onDisconnected(); - // 这里可以触发重新创建 Offer 的逻辑 } }