diff --git a/app/src/main/java/com/auto/autoclicker/AutoClickService.java b/app/src/main/java/com/auto/autoclicker/AutoClickService.java index 30ffdf8..000e825 100644 --- a/app/src/main/java/com/auto/autoclicker/AutoClickService.java +++ b/app/src/main/java/com/auto/autoclicker/AutoClickService.java @@ -29,49 +29,6 @@ public class AutoClickService extends AccessibilityService { private static final int MIN_SLIDE_DURATION = 100; private static final int MAX_SLIDE_DURATION = 2000; - // 事件基类 - public abstract static class Event { - public abstract void perform(); - } - - // 点击事件 - public class ClickEvent extends Event { - public int x; - public int y; - public int index; // 用于闪烁反馈 - - public ClickEvent(int x, int y, int index) { - this.x = x; - this.y = y; - this.index = index; - } - - @Override - public void perform() { - performSingleClick(new Point(x, y), index); - } - } - - // 滑动事件 - public class SlideEvent extends Event { - public int startX; - public int startY; - public int endX; - public int endY; - - public SlideEvent(int startX, int startY, int endX, int endY) { - this.startX = startX; - this.startY = startY; - this.endX = endX; - this.endY = endY; - } - - @Override - public void perform() { - performSingleSlide(this); - } - } - private final List eventQueue = new ArrayList<>(); private final Handler handler = new Handler(Looper.getMainLooper()); private boolean isRunning = false; @@ -140,7 +97,7 @@ public class AutoClickService extends AccessibilityService { Point constrainedStart = ViewUtils.constrainToScreen(startX, startY, screenWidth, screenHeight); Point constrainedEnd = ViewUtils.constrainToScreen(endX, endY, screenWidth, screenHeight); - eventQueue.add(new SlideEvent( + eventQueue.add(new SlideMultipleEvent( constrainedStart.x, constrainedStart.y, constrainedEnd.x, constrainedEnd.y)); @@ -150,7 +107,7 @@ public class AutoClickService extends AccessibilityService { public void addMultipleSlideEvents(List slides) { for (Slide slide : slides) { - addSlideEvent((int) slide.startX, (int) slide.startY, (int) slide.endX, (int) slide.endY); + addSlideEvent(slide.startX, slide.startY, slide.endX, slide.endY); } logDebug("添加多个滑动事件: " + slides.size() + " 个"); } @@ -215,7 +172,29 @@ public class AutoClickService extends AccessibilityService { } Event event = eventQueue.get(currentEventIndex); - event.perform(); + + if (event instanceof ClickEvent) { + ClickEvent clickEvent = (ClickEvent) event; + logDebug("即将执行点击事件: (" + clickEvent.getX() + ", " + clickEvent.getY() + "), index=" + clickEvent.getAdditionalInfo()); + } else if (event instanceof SlideMultipleEvent) { + SlideMultipleEvent slideMultipleEvent = (SlideMultipleEvent) event; + logDebug("即将执行滑动事件: 从 (" + slideMultipleEvent.startX + ", " + slideMultipleEvent.startY + ") 到 (" + slideMultipleEvent.endX + ", " + slideMultipleEvent.endY + ")"); + } else { + logDebug("未知事件类型: " + event.getClass().getSimpleName()); + } + + if (event instanceof ClickEvent) { + ClickEvent clickEvent = (ClickEvent) event; + Point clickPoint = new Point(clickEvent.getX(), clickEvent.getY()); + performSingleClick(clickPoint, clickEvent.getAdditionalInfo()); + } else if (event instanceof SlideMultipleEvent) { + SlideMultipleEvent slideMultipleEvent = (SlideMultipleEvent) event; + performSlide(slideMultipleEvent); + } else { + logDebug("未知事件类型,跳过执行: " + event.getClass().getSimpleName()); + // 也可以选择继续执行下一个 + handler.postDelayed(this::executeNextEvent, clickInterval); + } // 准备下一个事件 currentEventIndex = (currentEventIndex + 1) % eventQueue.size(); @@ -223,7 +202,6 @@ public class AutoClickService extends AccessibilityService { private void performSingleClick(Point clickPoint, int index) { logDebug("执行点击: (" + clickPoint.x + ", " + clickPoint.y + ")"); - flashTouchFeedback(index); Path path = new Path(); path.moveTo(clickPoint.x, clickPoint.y); @@ -238,6 +216,7 @@ public class AutoClickService extends AccessibilityService { logDebug("点击完成"); if (isRunning) { handler.postDelayed(() -> executeNextEvent(), clickInterval); + flashTouchFeedback(index); } } @@ -251,7 +230,7 @@ public class AutoClickService extends AccessibilityService { }, null); } - private void performSingleSlide(SlideEvent slide) { + private void performSlide(SlideMultipleEvent slide) { logDebug("执行滑动: 从 (" + slide.startX + ", " + slide.startY + ") 到 (" + slide.endX + ", " + slide.endY + ")"); @@ -290,7 +269,6 @@ public class AutoClickService extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { - // 不需要处理辅助功能事件 } private void logDebug(String message) { diff --git a/app/src/main/java/com/auto/autoclicker/ClickEvent.java b/app/src/main/java/com/auto/autoclicker/ClickEvent.java new file mode 100644 index 0000000..3e6599c --- /dev/null +++ b/app/src/main/java/com/auto/autoclicker/ClickEvent.java @@ -0,0 +1,19 @@ +package com.auto.autoclicker; + +public class ClickEvent extends Event { + private int additionalInfo; + + public ClickEvent(int x, int y, int additionalInfo) { + super(additionalInfo, x, y); + this.additionalInfo = additionalInfo; + } + + public int getAdditionalInfo() { + return additionalInfo; + } + + public void setAdditionalInfo(int additionalInfo) { + this.additionalInfo = additionalInfo; + } +} + diff --git a/app/src/main/java/com/auto/autoclicker/ConnectingLineView.java b/app/src/main/java/com/auto/autoclicker/ConnectingLineView.java index 8bfd1ae..c25648c 100644 --- a/app/src/main/java/com/auto/autoclicker/ConnectingLineView.java +++ b/app/src/main/java/com/auto/autoclicker/ConnectingLineView.java @@ -8,7 +8,7 @@ import android.view.View; public class ConnectingLineView extends View { private float startX, startY, endX, endY; - private Paint paint; + private final Paint paint; public ConnectingLineView(Context context) { super(context); diff --git a/app/src/main/java/com/auto/autoclicker/Event.java b/app/src/main/java/com/auto/autoclicker/Event.java index 19b6bde..3b6a2f5 100644 --- a/app/src/main/java/com/auto/autoclicker/Event.java +++ b/app/src/main/java/com/auto/autoclicker/Event.java @@ -1,5 +1,26 @@ package com.auto.autoclicker; -public interface Event { - int getId(); +public class Event { + protected int id; + protected int x; + protected int y; + + public Event(int id, int x, int y) { + this.id = id; + this.x = x; + this.y = y; + } + + // Getter 方法 + public int getId() { + return id; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } } diff --git a/app/src/main/java/com/auto/autoclicker/FloatingViewManager.java b/app/src/main/java/com/auto/autoclicker/FloatingViewManager.java index 720dbaa..59d9f12 100644 --- a/app/src/main/java/com/auto/autoclicker/FloatingViewManager.java +++ b/app/src/main/java/com/auto/autoclicker/FloatingViewManager.java @@ -20,7 +20,6 @@ import android.view.View; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; -import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -38,115 +37,113 @@ import java.util.List; public class FloatingViewManager { private static final String TAG = "FloatingViewManager"; + private static final long DEBOUNCE_INTERVAL = 500; + private static final int TOUCH_POINT_SIZE = 100; + + private static final int MODE_SINGLE = 1; + private static final int MODE_MULTIPLE = 2; private final Context context; - - private static final long DEBOUNCE_INTERVAL = 500; - private final WindowManager windowManager; - - private int touchPointNumber = 1; // 默认数字 - - private final List moreTouchPointViews = new ArrayList<>(); - private final List moreTouchPointParams = new ArrayList<>(); + private final int screenWidth; + private final int screenHeight; + private final List eventQueue = new ArrayList<>(); private TextView singleTouchPointView; private WindowManager.LayoutParams singleTouchPointParams; - private LinearLayout singleControlBarView; - private LinearLayout moreControlBarView; - private WindowManager.LayoutParams singleControlBarParams; - private WindowManager.LayoutParams moreControlBarParams; + private LinearLayout multipleControlBarView; + private WindowManager.LayoutParams multipleControlBarParams; - private boolean isMoreClicking = false; + private final List multipleTouchPointViews = new ArrayList<>(); + private final List multipleTouchPointParams = new ArrayList<>(); + private int touchPointNumber = 1; + private int eventIdCounter = 1; + + private final List clickPointEvents = new ArrayList<>(); + private final List slideEvents = new ArrayList<>(); private float touchPointX = 500; private float touchPointY = 500; - - private boolean isClicking = false; - + private boolean isRunning = false; + private boolean isMultipleRunning = false; private long lastToggleTime = 0; - private final int screenWidth; - private final int screenHeight; - - private final List eventQueue = new ArrayList<>(); // 事件队列 - private int eventIdCounter = 1; // 事件编号 - public FloatingViewManager(Context context) { this.context = context; this.windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Point screenSize = ScreenUtils.getScreenSize(context); this.screenWidth = screenSize.x; this.screenHeight = screenSize.y; - registerBroadcast(context); - logDebug("屏幕尺寸: " + screenWidth + "x" + screenHeight); + registerBroadcastReceiver(); + Log.d(TAG, "Screen size: " + screenWidth + "x" + screenHeight); } - private void registerBroadcast(Context context) { - LocalBroadcastManager.getInstance(context).registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if ("com.auto.autoclicker.FLASH_TOUCH_POINT".equals(intent.getAction())) { - int index = intent.getIntExtra("index", -1); // 默认是-1 - flashTouchPoint(index); - } - } - }, new IntentFilter("com.auto.autoclicker.FLASH_TOUCH_POINT")); + private void registerBroadcastReceiver() { + LocalBroadcastManager.getInstance(context).registerReceiver( + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if ("com.auto.autoclicker.FLASH_TOUCH_POINT".equals(intent.getAction())) { + int index = intent.getIntExtra("index", -1); + flashTouchPoint(index); + } + } + }, + new IntentFilter("com.auto.autoclicker.FLASH_TOUCH_POINT") + ); } public void showFloatingViews(int mode) throws SecurityException { if (!Settings.canDrawOverlays(context)) { - throw new SecurityException("需要悬浮窗权限"); + throw new SecurityException("Overlay permission required"); } removeFloatingViews(); - if (mode == 1) { - initSingleTouchPointView(); - initSingleControlBar(); - - if (singleTouchPointView != null) { - windowManager.addView(singleTouchPointView, singleTouchPointParams); - } - - if (singleControlBarView != null) { - windowManager.addView(singleControlBarView, singleControlBarParams); - } - } else if (mode == 2) { - initMoreTouchPointView(); - initMoreControlBar(); - - if (moreControlBarView != null) { - windowManager.addView(moreControlBarView, moreControlBarParams); - } + switch (mode) { + case MODE_SINGLE: + showSingleModeViews(); + break; + case MODE_MULTIPLE: + showMultipleModeViews(); + break; + default: + Log.e(TAG, "Invalid mode: " + mode); + break; } - logDebug("悬浮窗已添加,模式 = " + mode); + Log.d(TAG, "Floating views added, mode = " + mode); + } + + private void showSingleModeViews() { + initSingleTouchPointView(); + initSingleControlBar(); + + if (singleTouchPointView != null) { + windowManager.addView(singleTouchPointView, singleTouchPointParams); + } + + if (singleControlBarView != null) { + windowManager.addView(singleControlBarView, singleControlBarParams); + } + } + + private void showMultipleModeViews() { + initMultipleTouchPointView(); + initMultipleControlBar(); + + if (multipleControlBarView != null) { + windowManager.addView(multipleControlBarView, multipleControlBarParams); + } } @SuppressLint("ClickableViewAccessibility") private void initSingleTouchPointView() { - singleTouchPointView = new TextView(context); + singleTouchPointView = createTouchPointView("1"); - singleTouchPointView.setBackgroundResource(R.drawable.un_touch_point); - singleTouchPointView.setGravity(Gravity.CENTER); // 文字居中 - singleTouchPointView.setText("1"); // 设置初始数字 - singleTouchPointView.setTextColor(Color.BLACK); // 数字颜色 - singleTouchPointView.setTextSize(16); // 数字大小(可调整) - - singleTouchPointParams = new WindowManager.LayoutParams( - 100, 100, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : - WindowManager.LayoutParams.TYPE_PHONE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, - PixelFormat.TRANSLUCENT - ); - - singleTouchPointParams.gravity = Gravity.TOP | Gravity.START; + singleTouchPointParams = createTouchPointParams(); singleTouchPointParams.x = (int) touchPointX; singleTouchPointParams.y = (int) touchPointY; @@ -156,12 +153,12 @@ public class FloatingViewManager { @Override public boolean onTouch(View v, MotionEvent event) { - if (isClicking) { - // 拖动禁用时,仅处理点击 - if (event.getAction() == MotionEvent.ACTION_UP) { - v.performClick(); - return true; - } + if (isRunning && event.getAction() == MotionEvent.ACTION_UP) { + v.performClick(); + return true; + } + + if (isRunning) { return false; } @@ -176,11 +173,7 @@ public class FloatingViewManager { float dx = event.getRawX() - lastX; float dy = event.getRawY() - lastY; updateTouchPointPosition(paramX, paramY, dx, dy); - AutoClickService service = AutoClickService.getInstance(); - if (service != null) { - service.setClickPosition(touchPointX, touchPointY); - logDebug("单点触摸点移动到: (" + touchPointX + ", " + touchPointY + ")"); - } + updateServiceClickPosition(); break; } return true; @@ -188,65 +181,54 @@ public class FloatingViewManager { }); } - private void initMoreTouchPointView() { - moreTouchPointViews.clear(); - moreTouchPointParams.clear(); - eventQueue.clear(); // 清空事件队列 - eventIdCounter = 1; // 重置编号 + private void updateServiceClickPosition() { + AutoClickService service = AutoClickService.getInstance(); + if (service != null) { + service.setClickPosition(touchPointX, touchPointY); + Log.d(TAG, "Single touch point moved to: (" + touchPointX + ", " + touchPointY + ")"); + } + } + + private void initMultipleTouchPointView() { + multipleTouchPointViews.clear(); + multipleTouchPointParams.clear(); + eventQueue.clear(); + eventIdCounter = 1; touchPointNumber = 1; } + private TextView createTouchPointView(String label) { + TextView touchPointView = new TextView(context); + touchPointView.setBackgroundResource(R.drawable.un_touch_point); + touchPointView.setGravity(Gravity.CENTER); + touchPointView.setText(label); + touchPointView.setTextColor(Color.BLACK); + touchPointView.setTextSize(16); + return touchPointView; + } + + private WindowManager.LayoutParams createTouchPointParams() { + int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : + WindowManager.LayoutParams.TYPE_PHONE; + + WindowManager.LayoutParams params = new WindowManager.LayoutParams( + TOUCH_POINT_SIZE, TOUCH_POINT_SIZE, + overlayType, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, + PixelFormat.TRANSLUCENT + ); + params.gravity = Gravity.TOP | Gravity.START; + return params; + } + @SuppressLint("ClickableViewAccessibility") private void initSingleControlBar() { singleControlBarView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.single_control_bar, null); - singleControlBarParams = new WindowManager.LayoutParams( - WindowManager.LayoutParams.WRAP_CONTENT, - WindowManager.LayoutParams.WRAP_CONTENT, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : - WindowManager.LayoutParams.TYPE_PHONE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, - PixelFormat.TRANSLUCENT - ); - singleControlBarParams.gravity = Gravity.TOP | Gravity.START; - singleControlBarParams.x = 0; - singleControlBarParams.y = 200; + singleControlBarParams = createControlBarParams(); - singleControlBarView.setOnTouchListener(new View.OnTouchListener() { - private float lastX, lastY; - private float paramX, paramY; - - @Override - public boolean onTouch(View v, MotionEvent event) { - if (isClicking) { - // 拖动禁用时,仅处理点击 - if (event.getAction() == MotionEvent.ACTION_UP) { - v.performClick(); - return true; - } - return false; - } - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - lastX = event.getRawX(); - lastY = event.getRawY(); - paramX = singleControlBarParams.x; - paramY = singleControlBarParams.y; - return true; - case MotionEvent.ACTION_MOVE: - float dx = event.getRawX() - lastX; - float dy = event.getRawY() - lastY; - updateSingleControlBarPosition(paramX, paramY, dx, dy); - return true; - case MotionEvent.ACTION_UP: - v.performClick(); - return true; - } - return false; - } - }); + setupDraggableView(singleControlBarView, singleControlBarParams, this::updateSingleControlBarPosition); ImageView play = singleControlBarView.findViewById(R.id.play_button); ImageView close = singleControlBarView.findViewById(R.id.close_button); @@ -258,30 +240,62 @@ public class FloatingViewManager { } @SuppressLint("ClickableViewAccessibility") - private void initMoreControlBar() { - moreControlBarView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.more_control_bar, null); - moreControlBarParams = new WindowManager.LayoutParams( + private void initMultipleControlBar() { + multipleControlBarView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.multiple_control_bar, null); + multipleControlBarParams = createControlBarParams(); + + setupDraggableView(multipleControlBarView, multipleControlBarParams, this::updateMoreControlBarPosition); + + ImageView playButton = multipleControlBarView.findViewById(R.id.play_button); + ImageView addButton = multipleControlBarView.findViewById(R.id.add_button); + ImageView removeButton = multipleControlBarView.findViewById(R.id.remove_button); + ImageView slideButton = multipleControlBarView.findViewById(R.id.slide_button); + ImageView closeButton = multipleControlBarView.findViewById(R.id.close_button); + ImageView settingButton = multipleControlBarView.findViewById(R.id.settings_button); + + playButton.setOnClickListener(v -> toggleMultipleClicking()); + addButton.setOnClickListener(v -> addPointEvent()); + removeButton.setOnClickListener(v -> removeLastEvent()); + slideButton.setOnClickListener(v -> addSlideEvent()); + closeButton.setOnClickListener(v -> closeFloatingViews()); + settingButton.setOnClickListener(v -> showInputDialog()); + } + + private WindowManager.LayoutParams createControlBarParams() { + int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : + WindowManager.LayoutParams.TYPE_PHONE; + + WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : - WindowManager.LayoutParams.TYPE_PHONE, + overlayType, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT ); - moreControlBarParams.gravity = Gravity.TOP | Gravity.START; - moreControlBarParams.x = 0; - moreControlBarParams.y = 200; + params.gravity = Gravity.TOP | Gravity.START; + params.x = 0; + params.y = 200; + return params; + } - moreControlBarView.setOnTouchListener(new View.OnTouchListener() { + interface PositionUpdater { + void update(float paramX, float paramY, float dx, float dy); + } + + @SuppressLint("ClickableViewAccessibility") + private void setupDraggableView(View view, WindowManager.LayoutParams params, PositionUpdater positionUpdater) { + view.setOnTouchListener(new View.OnTouchListener() { private float lastX, lastY; private float paramX, paramY; + private boolean isDragging = false; @Override public boolean onTouch(View v, MotionEvent event) { - if (isMoreClicking) { - // 拖动禁用时,仅处理点击 + boolean clickingState = view == multipleControlBarView ? isMultipleRunning : isRunning; + + if (clickingState) { if (event.getAction() == MotionEvent.ACTION_UP) { v.performClick(); return true; @@ -293,65 +307,62 @@ public class FloatingViewManager { case MotionEvent.ACTION_DOWN: lastX = event.getRawX(); lastY = event.getRawY(); - paramX = moreControlBarParams.x; - paramY = moreControlBarParams.y; + paramX = params.x; + paramY = params.y; + isDragging = true; return true; + case MotionEvent.ACTION_MOVE: - float dx = event.getRawX() - lastX; - float dy = event.getRawY() - lastY; - updateMoreControlBarPosition(paramX, paramY, dx, dy); - return true; + if (isDragging) { + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + positionUpdater.update(paramX, paramY, dx, dy); + return true; + } + break; + case MotionEvent.ACTION_UP: + isDragging = false; v.performClick(); return true; } return false; } }); - - ImageView playButton = moreControlBarView.findViewById(R.id.play_button); - ImageView addButton = moreControlBarView.findViewById(R.id.add_button); - ImageView removeButton = moreControlBarView.findViewById(R.id.remove_button); - ImageView slideButton = moreControlBarView.findViewById(R.id.slide_button); - ImageView closeButton = moreControlBarView.findViewById(R.id.close_button); - ImageView settingButton = moreControlBarView.findViewById(R.id.settings_button); - - playButton.setOnClickListener(v -> toggleMoreClicking()); - addButton.setOnClickListener(v -> addPointEvent()); - removeButton.setOnClickListener(v -> removeLastEvent()); - slideButton.setOnClickListener(v -> addSlideEvent()); - closeButton.setOnClickListener(v -> closeFloatingViews()); - settingButton.setOnClickListener(v -> showInputDialog()); } - private void toggleSingleClicking(ImageView play) { + private void toggleSingleClicking(ImageView playButton) { if (isDebounced()) return; AutoClickService service = AutoClickService.getInstance(); if (service == null) { - Log.e(TAG, "AutoClickService 未初始化"); - Toast.makeText(context, "请在设置中启用无障碍服务", Toast.LENGTH_LONG).show(); - Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); + handleMissingService(); return; } - if (isClicking) { - service.stopClicking(); - play.setBackgroundResource(R.drawable.play); - singleTouchPointView.setBackgroundResource(R.drawable.un_touch_point); - Toast.makeText(context, "停止自动点击", Toast.LENGTH_SHORT).show(); + if (isRunning) { + stopSingleClicking(service, playButton); } else { - service.setClickPosition(touchPointX, touchPointY); - service.startClicking(); - play.setBackgroundResource(R.drawable.pause); - singleTouchPointView.setBackgroundResource(R.drawable.touch_point); - Toast.makeText(context, "开始自动点击", Toast.LENGTH_SHORT).show(); + startSingleClicking(service, playButton); } - isClicking = !isClicking; - logDebug("单点服务是否点击中: " + service.isClicking()); + isRunning = !isRunning; + Log.d(TAG, "Single service clicking state: " + service.isClicking()); + } + + private void startSingleClicking(AutoClickService service, ImageView playButton) { + service.setClickPosition(touchPointX, touchPointY); + service.startClicking(); + playButton.setBackgroundResource(R.drawable.pause); + singleTouchPointView.setBackgroundResource(R.drawable.touch_point); + Toast.makeText(context, "Auto clicking started", Toast.LENGTH_SHORT).show(); + } + + private void stopSingleClicking(AutoClickService service, ImageView playButton) { + service.stopClicking(); + playButton.setBackgroundResource(R.drawable.play); + singleTouchPointView.setBackgroundResource(R.drawable.un_touch_point); + Toast.makeText(context, "Auto clicking stopped", Toast.LENGTH_SHORT).show(); } private void closeFloatingViews() { @@ -359,17 +370,11 @@ public class FloatingViewManager { if (service != null) { service.stopClicking(); } else { - logDebug("AutoClickService 未初始化"); - Toast.makeText(context, "请启用无障碍服务", Toast.LENGTH_SHORT).show(); - } - - if (singleTouchPointView != null) { - singleTouchPointView.setBackgroundResource(R.drawable.un_touch_point); - } - for (View point : moreTouchPointViews) { - point.setBackgroundResource(R.drawable.un_touch_point); + Log.d(TAG, "AutoClickService not initialized"); + Toast.makeText(context, "Please enable accessibility service", Toast.LENGTH_SHORT).show(); } + updateTouchPointsBackground(R.drawable.un_touch_point); removeFloatingViews(); context.stopService(new Intent(context, ForegroundService.class)); @@ -380,87 +385,103 @@ public class FloatingViewManager { LocalBroadcastManager.getInstance(context).sendBroadcast(intent); } - private void toggleMoreClicking() { + private void updateTouchPointsBackground(int resourceId) { + if (singleTouchPointView != null) { + singleTouchPointView.setBackgroundResource(resourceId); + } + + for (View point : multipleTouchPointViews) { + point.setBackgroundResource(resourceId); + } + } + + private void toggleMultipleClicking() { if (isDebounced()) return; AutoClickService service = AutoClickService.getInstance(); if (service == null) { - Log.e(TAG, "AutoClickService 未初始化"); - Toast.makeText(context, "请在设置中启用无障碍服务", Toast.LENGTH_LONG).show(); - Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); + handleMissingService(); return; } if (eventQueue.isEmpty()) { - Toast.makeText(context, "请先添加触摸点或滑动事件", Toast.LENGTH_SHORT).show(); + Toast.makeText(context, "Please add touch points or slide events first", Toast.LENGTH_SHORT).show(); return; } - if (isMoreClicking) { - service.stopClicking(); - Toast.makeText(context, "停止多点点击", Toast.LENGTH_SHORT).show(); - for (View point : moreTouchPointViews) { - point.setBackgroundResource(R.drawable.un_touch_point); - } + if (isMultipleRunning) { + stopMultiClicking(service); } else { - service.addMultipleClickEvents(getMoreTouchPositions()); - service.addMultipleSlideEvents(getSlideEvents()); - service.startClicking(); - Toast.makeText(context, "开始多点点击", Toast.LENGTH_SHORT).show(); - for (View point : moreTouchPointViews) { - point.setBackgroundResource(R.drawable.touch_point); - } + startMultiClicking(service); } - isMoreClicking = !isMoreClicking; - logDebug("多点服务是否点击中: " + service.isClicking()); + isMultipleRunning = !isMultipleRunning; + Log.d(TAG, "Multi service clicking state: " + service.isClicking()); + } + + private void startMultiClicking(AutoClickService service) { + service.addMultipleClickEvents(getMoreTouchPositions()); + service.addMultipleSlideEvents(getSlideEvents()); + service.startClicking(); + Toast.makeText(context, "Multi-point clicking started", Toast.LENGTH_SHORT).show(); + Log.d(TAG, "开始多点点击事件 " + getMoreTouchPositions()); + + for (View point : multipleTouchPointViews) { + point.setBackgroundResource(R.drawable.touch_point); + } + } + + private void stopMultiClicking(AutoClickService service) { + service.stopClicking(); + Toast.makeText(context, "Multi-point clicking stopped", Toast.LENGTH_SHORT).show(); + + for (View point : multipleTouchPointViews) { + point.setBackgroundResource(R.drawable.un_touch_point); + } + } + + private void handleMissingService() { + Log.e(TAG, "AutoClickService not initialized"); + Toast.makeText(context, "Please enable accessibility service in settings", Toast.LENGTH_LONG).show(); + Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); } @SuppressLint("ClickableViewAccessibility") private void addPointEvent() { - if (isMoreClicking) { - Toast.makeText(context, "请先停止点击", Toast.LENGTH_SHORT).show(); + if (isMultipleRunning) { + Toast.makeText(context, "Please stop clicking first", Toast.LENGTH_SHORT).show(); return; } - TextView point = new TextView(context); - - point.setBackgroundResource(R.drawable.un_touch_point); - point.setGravity(Gravity.CENTER); // 文字居中 - point.setText(String.valueOf(touchPointNumber)); // 设置初始数字 - point.setTextColor(Color.BLACK); // 数字颜色 - point.setTextSize(16); // 数字大小(可调整) - + TextView point = createTouchPointView(String.valueOf(touchPointNumber)); touchPointNumber++; - WindowManager.LayoutParams params = new WindowManager.LayoutParams( - 100, 100, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : - WindowManager.LayoutParams.TYPE_PHONE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, - PixelFormat.TRANSLUCENT - ); - params.gravity = Gravity.TOP | Gravity.START; - params.x = screenWidth / 2 - 50; - params.y = screenHeight / 2 - 50; + WindowManager.LayoutParams params = createTouchPointParams(); + params.x = screenWidth / 2 - TOUCH_POINT_SIZE / 2; + params.y = screenHeight / 2 - TOUCH_POINT_SIZE / 2; PointEvent pointEvent = new PointEvent(eventIdCounter++, params.x, params.y, point, params); eventQueue.add(pointEvent); - moreTouchPointViews.add(point); - moreTouchPointParams.add(params); + clickPointEvents.add(pointEvent); + multipleTouchPointViews.add(point); + multipleTouchPointParams.add(params); + setupDraggablePoint(point, params, pointEvent); + windowManager.addView(point, params); + updateServicePositions(); + } + + @SuppressLint("ClickableViewAccessibility") + private void setupDraggablePoint(TextView point, WindowManager.LayoutParams params, PointEvent pointEvent) { point.setOnTouchListener(new View.OnTouchListener() { private float lastX, lastY; private float paramX, paramY; @Override public boolean onTouch(View v, MotionEvent event) { - if (isMoreClicking) { - // 拖动禁用时,仅处理点击 + if (isMultipleRunning) { if (event.getAction() == MotionEvent.ACTION_UP) { v.performClick(); return true; @@ -495,277 +516,193 @@ public class FloatingViewManager { return false; } }); - - windowManager.addView(point, params); - updateServicePositions(); } @SuppressLint("ClickableViewAccessibility") private void addSlideEvent() { - if (isMoreClicking) { - Toast.makeText(context, "请先停止点击", Toast.LENGTH_SHORT).show(); + if (isMultipleRunning) { + Toast.makeText(context, "Please stop clicking first", Toast.LENGTH_SHORT).show(); return; } - // 起点 - TextView startPoint = new TextView(context); - - startPoint.setBackgroundResource(R.drawable.un_touch_point); - startPoint.setGravity(Gravity.CENTER); // 文字居中 - startPoint.setText(String.valueOf(touchPointNumber)); // 设置初始数字 - startPoint.setTextColor(Color.BLACK); // 数字颜色 - startPoint.setTextSize(16); // 数字大小(可调整) - - WindowManager.LayoutParams startParams = new WindowManager.LayoutParams( - 100, 100, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : - WindowManager.LayoutParams.TYPE_PHONE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, - PixelFormat.TRANSLUCENT - ); - startParams.gravity = Gravity.TOP | Gravity.START; + TextView startPoint = createTouchPointView(String.valueOf(touchPointNumber)); + WindowManager.LayoutParams startParams = createTouchPointParams(); startParams.x = screenWidth / 2 - 100; startParams.y = screenHeight / 2 - 50; PointEvent startPointEvent = new PointEvent(eventIdCounter++, startParams.x, startParams.y, startPoint, startParams); - // 终点 - TextView endPoint = new TextView(context); - - endPoint.setBackgroundResource(R.drawable.un_touch_point); - endPoint.setGravity(Gravity.CENTER); // 文字居中 - endPoint.setText(String.valueOf(touchPointNumber)); // 设置初始数字 - endPoint.setTextColor(Color.BLACK); // 数字颜色 - endPoint.setTextSize(16); // 数字大小(可调整) - + TextView endPoint = createTouchPointView(String.valueOf(touchPointNumber)); touchPointNumber++; - - WindowManager.LayoutParams endParams = new WindowManager.LayoutParams( - 100, 100, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : - WindowManager.LayoutParams.TYPE_PHONE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, - PixelFormat.TRANSLUCENT - ); - endParams.gravity = Gravity.TOP | Gravity.START; + WindowManager.LayoutParams endParams = createTouchPointParams(); endParams.x = screenWidth / 2 + 100; endParams.y = screenHeight / 2 - 50; PointEvent endPointEvent = new PointEvent(eventIdCounter++, endParams.x, endParams.y, endPoint, endParams); - // 创建连接线视图 - 关键是使用全屏大小 ConnectingLineView lineView = new ConnectingLineView(context); - WindowManager.LayoutParams lineParams = new WindowManager.LayoutParams( - WindowManager.LayoutParams.MATCH_PARENT, // 全屏宽度 - WindowManager.LayoutParams.MATCH_PARENT, // 全屏高度 - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : - WindowManager.LayoutParams.TYPE_PHONE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | - WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, // 不接收触摸事件 - PixelFormat.TRANSLUCENT - ); - lineParams.gravity = Gravity.TOP | Gravity.START; - lineParams.x = 0; // 从屏幕左上角开始 - lineParams.y = 0; + WindowManager.LayoutParams lineParams = createLineViewParams(); SlideEvent slideEvent = new SlideEvent(eventIdCounter++, startPointEvent, endPointEvent, lineView, lineParams); eventQueue.add(slideEvent); - moreTouchPointViews.add(startPoint); - moreTouchPointViews.add(endPoint); - moreTouchPointParams.add(startParams); - moreTouchPointParams.add(endParams); + slideEvents.add(slideEvent); + multipleTouchPointViews.add(startPoint); + multipleTouchPointViews.add(endPoint); + multipleTouchPointParams.add(startParams); + multipleTouchPointParams.add(endParams); - // 起点拖动监听 - startPoint.setOnTouchListener(new View.OnTouchListener() { - private float lastX, lastY; - private float paramX, paramY; + setupDraggableSlidePoint(startPoint, startParams, startPointEvent, slideEvent); + setupDraggableSlidePoint(endPoint, endParams, endPointEvent, slideEvent); - @Override - public boolean onTouch(View v, MotionEvent event) { - if (isMoreClicking) { - // 拖动禁用时,仅处理点击 - if (event.getAction() == MotionEvent.ACTION_UP) { - v.performClick(); - return true; - } - return false; - } - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - lastX = event.getRawX(); - lastY = event.getRawY(); - paramX = startParams.x; - paramY = startParams.y; - return true; - case MotionEvent.ACTION_MOVE: - float dx = event.getRawX() - lastX; - float dy = event.getRawY() - lastY; - Point constrainedPoint = ViewUtils.constrainToScreen( - paramX + dx, paramY + dy, - screenWidth - startPoint.getWidth(), screenHeight - startPoint.getHeight()); - startParams.x = constrainedPoint.x; - startParams.y = constrainedPoint.y; - startPointEvent.x = startParams.x; - startPointEvent.y = startParams.y; - windowManager.updateViewLayout(startPoint, startParams); - - // 更新连接线 - updateLinePosition(slideEvent); - updateServicePositions(); - return true; - case MotionEvent.ACTION_UP: - v.performClick(); - return true; - } - return false; - } - }); - - // 终点拖动监听 - endPoint.setOnTouchListener(new View.OnTouchListener() { - private float lastX, lastY; - private float paramX, paramY; - - @Override - public boolean onTouch(View v, MotionEvent event) { - if (isMoreClicking) { - // 拖动禁用时,仅处理点击 - if (event.getAction() == MotionEvent.ACTION_UP) { - v.performClick(); - return true; - } - return false; - } - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - lastX = event.getRawX(); - lastY = event.getRawY(); - paramX = endParams.x; - paramY = endParams.y; - return true; - case MotionEvent.ACTION_MOVE: - float dx = event.getRawX() - lastX; - float dy = event.getRawY() - lastY; - Point constrainedPoint = ViewUtils.constrainToScreen( - paramX + dx, paramY + dy, - screenWidth - endPoint.getWidth(), screenHeight - endPoint.getHeight()); - endParams.x = constrainedPoint.x; - endParams.y = constrainedPoint.y; - endPointEvent.x = endParams.x; - endPointEvent.y = endParams.y; - windowManager.updateViewLayout(endPoint, endParams); - - // 更新连接线 - updateLinePosition(slideEvent); - - updateServicePositions(); - return true; - case MotionEvent.ACTION_UP: - v.performClick(); - return true; - } - return false; - } - }); - - // 首先添加连接线,确保它在最下层 windowManager.addView(lineView, lineParams); windowManager.addView(startPoint, startParams); windowManager.addView(endPoint, endParams); - // 初始化连接线位置 updateLinePosition(slideEvent); updateServicePositions(); } - // 更新连接线位置的方法 + private WindowManager.LayoutParams createLineViewParams() { + int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : + WindowManager.LayoutParams.TYPE_PHONE; + + WindowManager.LayoutParams params = new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT, + overlayType, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | + WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, + PixelFormat.TRANSLUCENT + ); + params.gravity = Gravity.TOP | Gravity.START; + params.x = 0; + params.y = 0; + return params; + } + + @SuppressLint("ClickableViewAccessibility") + private void setupDraggableSlidePoint(TextView point, WindowManager.LayoutParams params, + PointEvent pointEvent, SlideEvent slideEvent) { + point.setOnTouchListener(new View.OnTouchListener() { + private float lastX, lastY; + private float paramX, paramY; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (isMultipleRunning) { + if (event.getAction() == MotionEvent.ACTION_UP) { + v.performClick(); + return true; + } + return false; + } + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + paramX = params.x; + paramY = params.y; + return true; + case MotionEvent.ACTION_MOVE: + float dx = event.getRawX() - lastX; + float dy = event.getRawY() - lastY; + Point constrainedPoint = ViewUtils.constrainToScreen( + paramX + dx, paramY + dy, + screenWidth - point.getWidth(), screenHeight - point.getHeight()); + params.x = constrainedPoint.x; + params.y = constrainedPoint.y; + pointEvent.x = params.x; + pointEvent.y = params.y; + windowManager.updateViewLayout(point, params); + + updateLinePosition(slideEvent); + updateServicePositions(); + return true; + case MotionEvent.ACTION_UP: + v.performClick(); + return true; + } + return false; + } + }); + } + private void updateLinePosition(SlideEvent slideEvent) { - PointEvent start = slideEvent.startPoint; - PointEvent end = slideEvent.endPoint; - ConnectingLineView lineView = (ConnectingLineView) slideEvent.lineView; + PointEvent start = slideEvent.getStartPoint(); + PointEvent end = slideEvent.getEndPoint(); + ConnectingLineView lineView = slideEvent.getLineView(); - // 计算两点中心位置 - float startCenterX = start.x + 50; // 假设点的宽度为100 - float startCenterY = start.y + 50; - float endCenterX = end.x + 50; - float endCenterY = end.y + 50; + float startCenterX = start.x + (float) TOUCH_POINT_SIZE / 2; + float startCenterY = start.y + (float) TOUCH_POINT_SIZE / 2; + float endCenterX = end.x + (float) TOUCH_POINT_SIZE / 2; + float endCenterY = end.y + (float) TOUCH_POINT_SIZE / 2; - // 更新线条位置 - 直接设置线条的起点和终点 lineView.setPoints(startCenterX, startCenterY, endCenterX, endCenterY); } - // 新增:移除最后一个事件 private void removeLastEvent() { - if (isMoreClicking) { - Toast.makeText(context, "请先停止点击", Toast.LENGTH_SHORT).show(); + if (isMultipleRunning) { + Toast.makeText(context, "Please stop clicking first", Toast.LENGTH_SHORT).show(); return; } if (eventQueue.isEmpty()) { - Toast.makeText(context, "没有更多事件可以删除", Toast.LENGTH_SHORT).show(); + Toast.makeText(context, "No more events to remove", Toast.LENGTH_SHORT).show(); return; } Event lastEvent = eventQueue.remove(eventQueue.size() - 1); - - if (lastEvent instanceof PointEvent) { - PointEvent pointEvent = (PointEvent) lastEvent; - try { - windowManager.removeView(pointEvent.view); - } catch (Exception e) { - Log.w(TAG, "移除触摸点失败", e); - } - moreTouchPointViews.remove(pointEvent.view); - moreTouchPointParams.remove(pointEvent.params); - } else if (lastEvent instanceof SlideEvent) { - SlideEvent slideEvent = (SlideEvent) lastEvent; - try { - windowManager.removeView(slideEvent.startPoint.view); - windowManager.removeView(slideEvent.endPoint.view); - windowManager.removeView(slideEvent.lineView); - } catch (Exception e) { - Log.w(TAG, "移除滑动事件失败", e); - } - moreTouchPointViews.remove(slideEvent.startPoint.view); - moreTouchPointViews.remove(slideEvent.endPoint.view); - moreTouchPointParams.remove(slideEvent.startPoint.params); - moreTouchPointParams.remove(slideEvent.endPoint.params); - } - + removeEvent(lastEvent); touchPointNumber--; - updateServicePositions(); } - // 新增:同步事件位置到 AutoClickService + private void removeEvent(Event event) { + try { + if (event instanceof PointEvent) { + PointEvent pointEvent = (PointEvent) event; + windowManager.removeView(pointEvent.getView()); + multipleTouchPointViews.remove(pointEvent.getView()); + multipleTouchPointParams.remove(pointEvent.getParams()); + } else if (event instanceof SlideEvent) { + SlideEvent slideEvent = (SlideEvent) event; + windowManager.removeView(slideEvent.getStartPoint().getView()); + windowManager.removeView(slideEvent.getEndPoint().getView()); + windowManager.removeView(slideEvent.getLineView()); + multipleTouchPointViews.remove(slideEvent.getStartPoint().getView()); + multipleTouchPointViews.remove(slideEvent.getEndPoint().getView()); + multipleTouchPointParams.remove(slideEvent.getStartPoint().getParams()); + multipleTouchPointParams.remove(slideEvent.getEndPoint().getParams()); + } + } catch (Exception e) { + Log.w(TAG, "Failed to remove event", e); + } + } + private void updateServicePositions() { List points = new ArrayList<>(); List slides = new ArrayList<>(); for (Event event : eventQueue) { if (event instanceof PointEvent) { PointEvent pe = (PointEvent) event; - points.add(new Point((int) pe.x, (int) pe.y)); + points.add(new Point(pe.x, pe.y)); } else if (event instanceof SlideEvent) { SlideEvent se = (SlideEvent) event; - slides.add(new Slide(se.startPoint.x, se.startPoint.y, se.endPoint.x, se.endPoint.y)); + slides.add(new Slide(se.getStartPoint().x, se.getStartPoint().y, se.getEndPoint().x, se.getEndPoint().y)); } } + AutoClickService service = AutoClickService.getInstance(); if (service != null) { service.addMultipleClickEvents(points); service.addMultipleSlideEvents(slides); + Log.d(TAG, "添加多点点击事件 " + points); } } public void removeFloatingViews() { try { - // 移除单点触摸视图 if (singleTouchPointView != null) { try { windowManager.removeView(singleTouchPointView); @@ -775,23 +712,22 @@ public class FloatingViewManager { singleTouchPointView = null; } - // 移除多点触摸视图 - List pointsToRemove = new ArrayList<>(moreTouchPointViews); + List pointsToRemove = new ArrayList<>(multipleTouchPointViews); for (View point : pointsToRemove) { try { windowManager.removeView(point); - moreTouchPointViews.remove(point); // 成功移除后从列表中删除 + multipleTouchPointViews.remove(point); } catch (Exception e) { Log.w(TAG, "移除 multiTouchPoint 失败", e); } } - moreTouchPointParams.clear(); // 清空参数列表 + multipleTouchPointParams.clear(); for (Event event : new ArrayList<>(eventQueue)) { if (event instanceof SlideEvent) { SlideEvent se = (SlideEvent) event; try { - windowManager.removeView(se.lineView); + windowManager.removeView(se.getLineView()); } catch (Exception e) { Log.w(TAG, "移除滑动线失败", e); } @@ -799,7 +735,6 @@ public class FloatingViewManager { } eventQueue.clear(); - // 移除单点控制栏 if (singleControlBarView != null) { try { windowManager.removeView(singleControlBarView); @@ -809,23 +744,22 @@ public class FloatingViewManager { singleControlBarView = null; } - // 移除多点控制栏 - if (moreControlBarView != null) { + if (multipleControlBarView != null) { try { - windowManager.removeView(moreControlBarView); + windowManager.removeView(multipleControlBarView); } catch (Exception e) { - Log.w(TAG, "移除 moreControlBarView 失败", e); + Log.w(TAG, "移除 multipleControlBarView 失败", e); } - moreControlBarView = null; + multipleControlBarView = null; } - isClicking = false; - isMoreClicking = false; - logDebug("悬浮窗已移除"); + isRunning = false; + isMultipleRunning = false; + Log.d(TAG, "悬浮窗已移除"); } catch (Exception e) { Log.e(TAG, "移除悬浮窗失败", e); - isClicking = false; - isMoreClicking = false; + isRunning = false; + isMultipleRunning = false; } } @@ -849,16 +783,16 @@ public class FloatingViewManager { private void updateMoreControlBarPosition(float paramX, float paramY, float dx, float dy) { Point constrainedPoint = ViewUtils.constrainToScreen( - paramX + dx, paramY + dy, screenWidth - moreControlBarView.getWidth(), screenHeight - moreControlBarView.getHeight()); - moreControlBarParams.x = constrainedPoint.x; - moreControlBarParams.y = constrainedPoint.y; - windowManager.updateViewLayout(moreControlBarView, moreControlBarParams); + paramX + dx, paramY + dy, screenWidth - multipleControlBarView.getWidth(), screenHeight - multipleControlBarView.getHeight()); + multipleControlBarParams.x = constrainedPoint.x; + multipleControlBarParams.y = constrainedPoint.y; + windowManager.updateViewLayout(multipleControlBarView, multipleControlBarParams); } private List getMoreTouchPositions() { List points = new ArrayList<>(); - for (WindowManager.LayoutParams params : moreTouchPointParams) { - points.add(new Point(params.x, params.y)); + for (PointEvent pointEvent : clickPointEvents) { + points.add(new Point(pointEvent.getX(), pointEvent.getY())); } return points; } @@ -912,22 +846,19 @@ public class FloatingViewManager { }); } - // 新增:获取滑动事件列表 private List getSlideEvents() { List slides = new ArrayList<>(); for (Event event : eventQueue) { if (event instanceof SlideEvent) { SlideEvent se = (SlideEvent) event; - slides.add(new Slide(se.startPoint.x, se.startPoint.y, se.endPoint.x, se.endPoint.y)); + slides.add(new Slide(se.getStartPoint().x, se.getStartPoint().y, se.getEndPoint().x, se.getEndPoint().y)); } } return slides; } - // 改成只闪烁当前索引的触摸点 public void flashTouchPoint(int index) { if (index == -1) { - // 单点模式 if (singleTouchPointView != null) { singleTouchPointView.animate() .alpha(0.3f) @@ -941,9 +872,8 @@ public class FloatingViewManager { .start(); } } else { - // 多点模式 - if (index >= 0 && index < moreTouchPointViews.size()) { - View point = moreTouchPointViews.get(index); + if (index >= 0 && index < multipleTouchPointViews.size()) { + View point = multipleTouchPointViews.get(index); point.animate() .alpha(0.3f) .setDuration(100) @@ -967,7 +897,4 @@ public class FloatingViewManager { return false; } - private void logDebug(String message) { - Log.d(TAG, message); - } } \ No newline at end of file diff --git a/app/src/main/java/com/auto/autoclicker/PointEvent.java b/app/src/main/java/com/auto/autoclicker/PointEvent.java index 624b23e..1571a46 100644 --- a/app/src/main/java/com/auto/autoclicker/PointEvent.java +++ b/app/src/main/java/com/auto/autoclicker/PointEvent.java @@ -1,24 +1,31 @@ package com.auto.autoclicker; -import android.view.View; import android.view.WindowManager; +import android.widget.TextView; -public class PointEvent implements Event { - int id; - float x, y; - View view; - WindowManager.LayoutParams params; +public class PointEvent extends Event { + private TextView view; + private WindowManager.LayoutParams params; - PointEvent(int id, float x, float y, View view, WindowManager.LayoutParams params) { - this.id = id; - this.x = x; - this.y = y; + public PointEvent(int id, int x, int y, TextView view, WindowManager.LayoutParams params) { + super(id, x, y); this.view = view; this.params = params; } - @Override - public int getId() { - return id; + public TextView getView() { + return view; } -} + + public WindowManager.LayoutParams getParams() { + return params; + } + + public void setView(TextView view) { + this.view = view; + } + + public void setParams(WindowManager.LayoutParams params) { + this.params = params; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/auto/autoclicker/Slide.java b/app/src/main/java/com/auto/autoclicker/Slide.java index 79deb3e..4b0dc84 100644 --- a/app/src/main/java/com/auto/autoclicker/Slide.java +++ b/app/src/main/java/com/auto/autoclicker/Slide.java @@ -1,12 +1,16 @@ package com.auto.autoclicker; public class Slide { - float startX, startY, endX, endY; + public final int startX; + public final int startY; + public final int endX; + public final int endY; - Slide(float startX, float startY, float endX, float endY) { + public Slide(int startX, int startY, int endX, int endY) { this.startX = startX; this.startY = startY; this.endX = endX; this.endY = endY; } } + diff --git a/app/src/main/java/com/auto/autoclicker/SlideEvent.java b/app/src/main/java/com/auto/autoclicker/SlideEvent.java index 275b5e0..8d50c8b 100644 --- a/app/src/main/java/com/auto/autoclicker/SlideEvent.java +++ b/app/src/main/java/com/auto/autoclicker/SlideEvent.java @@ -1,25 +1,52 @@ package com.auto.autoclicker; -import android.view.View; import android.view.WindowManager; -public class SlideEvent implements Event { - int id; - PointEvent startPoint; - PointEvent endPoint; - View lineView; - WindowManager.LayoutParams lineParams; +public class SlideEvent extends Event { + private PointEvent startPoint; + private PointEvent endPoint; + private ConnectingLineView lineView; + private WindowManager.LayoutParams lineParams; - SlideEvent(int id, PointEvent startPoint, PointEvent endPoint, View lineView, WindowManager.LayoutParams lineParams) { - this.id = id; + public SlideEvent(int id, PointEvent startPoint, PointEvent endPoint, + ConnectingLineView lineView, WindowManager.LayoutParams lineParams) { + super(id, 0, 0); this.startPoint = startPoint; this.endPoint = endPoint; this.lineView = lineView; this.lineParams = lineParams; } - @Override - public int getId() { - return id; + public PointEvent getStartPoint() { + return startPoint; + } + + public PointEvent getEndPoint() { + return endPoint; + } + + public ConnectingLineView getLineView() { + return lineView; + } + + public WindowManager.LayoutParams getLineParams() { + return lineParams; + } + + public void setStartPoint(PointEvent startPoint) { + this.startPoint = startPoint; + } + + public void setEndPoint(PointEvent endPoint) { + this.endPoint = endPoint; + } + + public void setLineView(ConnectingLineView lineView) { + this.lineView = lineView; + } + + public void setLineParams(WindowManager.LayoutParams lineParams) { + this.lineParams = lineParams; } } + diff --git a/app/src/main/java/com/auto/autoclicker/SlideMultipleEvent.java b/app/src/main/java/com/auto/autoclicker/SlideMultipleEvent.java new file mode 100644 index 0000000..b2e264f --- /dev/null +++ b/app/src/main/java/com/auto/autoclicker/SlideMultipleEvent.java @@ -0,0 +1,26 @@ +package com.auto.autoclicker; + +public class SlideMultipleEvent extends Event { + public int startX; + public int startY; + public int endX; + public int endY; + + public SlideMultipleEvent(int startX, int startY, int endX, int endY) { + super(-1, startX, startY); + this.startX = startX; + this.startY = startY; + this.endX = endX; + this.endY = endY; + } + + public SlideMultipleEvent(int id, int startX, int startY, int endX, int endY) { + super(id, startX, startY); + this.startX = startX; + this.startY = startY; + this.endX = endX; + this.endY = endY; + } +} + + diff --git a/app/src/main/res/layout/more_control_bar.xml b/app/src/main/res/layout/multiple_control_bar.xml similarity index 100% rename from app/src/main/res/layout/more_control_bar.xml rename to app/src/main/res/layout/multiple_control_bar.xml