diff --git a/app/src/main/java/com/auto/autoclicker/AutoClickService.java b/app/src/main/java/com/auto/autoclicker/AutoClickService.java index 747ef06..5018d3c 100644 --- a/app/src/main/java/com/auto/autoclicker/AutoClickService.java +++ b/app/src/main/java/com/auto/autoclicker/AutoClickService.java @@ -40,6 +40,10 @@ public class AutoClickService extends AccessibilityService { private int screenWidth; private int screenHeight; + private final List slideEvents = new ArrayList<>(); + private int currentEventIndex = 0; + private int slideDuration = 500; // 新增:滑动时长 + @Override public void onCreate() { super.onCreate(); @@ -80,6 +84,12 @@ public class AutoClickService extends AccessibilityService { logDebug("设置多点点击位置: " + positions.size() + " 个点"); } + public void setSlideEvents(List slides) { + this.slideEvents.clear(); + this.slideEvents.addAll(slides); + logDebug("设置滑动事件: " + slides.size() + " 个"); + } + public void setClickInterval(long interval) { if (interval < MIN_CLICK_INTERVAL || interval > MAX_CLICK_INTERVAL) { Log.w(TAG, "点击间隔超出范围: " + interval + "ms"); @@ -100,15 +110,15 @@ public class AutoClickService extends AccessibilityService { public void startClicking() { if (!isClicking) { - if (moreClickPositions.isEmpty() && (clickX == 0 && clickY == 0)) { - Log.w(TAG, "无有效点击位置,忽略开始点击"); + if (moreClickPositions.isEmpty() && slideEvents.isEmpty() && (clickX == 0 && clickY == 0)) { + Log.w(TAG, "无有效点击或滑动事件,忽略开始"); return; } isClicking = true; - currentClickIndex = 0; - logDebug("开始自动点击"); - performClick(); + currentEventIndex = 0; + logDebug("开始自动点击/滑动"); + performEvent(); } } @@ -116,7 +126,7 @@ public class AutoClickService extends AccessibilityService { if (isClicking) { isClicking = false; handler.removeCallbacksAndMessages(null); - logDebug("停止自动点击"); + logDebug("停止自动点击/滑动"); } } @@ -124,26 +134,9 @@ public class AutoClickService extends AccessibilityService { return isClicking; } - private void performClick() { - if (!isClicking) { - logDebug("跳过点击:服务未处于运行中"); - return; - } - - Point clickPoint; - int flashIndex = -1; // 新增变量,控制闪烁哪个点 - - if (!moreClickPositions.isEmpty()) { - // 多点模式:取当前索引的点 - clickPoint = moreClickPositions.get(currentClickIndex); - flashIndex = currentClickIndex; // 标记当前点击的是第几个点 - } else { - // 单点模式 - clickPoint = new Point(clickX, clickY); - } - + private void performClick(Point clickPoint, int index) { logDebug("执行点击: (" + clickPoint.x + ", " + clickPoint.y + ")"); - flashTouchFeedback(flashIndex); + flashTouchFeedback(index); Path path = new Path(); path.moveTo(clickPoint.x, clickPoint.y); @@ -156,28 +149,86 @@ public class AutoClickService extends AccessibilityService { @Override public void onCompleted(GestureDescription gestureDescription) { logDebug("点击完成"); - if (isClicking) { - if (!moreClickPositions.isEmpty()) { - // 多点模式:下一个触摸点 - currentClickIndex = (currentClickIndex + 1) % moreClickPositions.size(); - logDebug("当前点击点" + currentClickIndex); - } - // 安排下一次点击(无论是单点还是多点) - handler.postDelayed(() -> performClick(), clickInterval); + handler.postDelayed(() -> performEvent(), clickInterval); } } @Override public void onCancelled(GestureDescription gestureDescription) { Log.e(TAG, "点击被取消"); - if (isClicking) { - if (!moreClickPositions.isEmpty()) { - currentClickIndex = (currentClickIndex + 1) % moreClickPositions.size(); - } - // 点击取消也继续循环 - handler.postDelayed(() -> performClick(), clickInterval + 300); + handler.postDelayed(() -> performEvent(), clickInterval + 300); + } + } + }, null); + } + + private void performEvent() { + if (!isClicking) { + logDebug("跳过事件:服务未处于运行中"); + return; + } + + if (moreClickPositions.isEmpty() && slideEvents.isEmpty()) { + if (clickX != 0 || clickY != 0) { + // 单点模式 + performClick(new Point(clickX, clickY), -1); + return; + } + stopClicking(); + return; + } + + // 多点模式:按事件队列顺序执行 + int pointIndex = 0; + int slideIndex = 0; + for (int i = 0; i <= currentEventIndex; i++) { + if (pointIndex < moreClickPositions.size() && i == pointIndex) { + pointIndex++; + } else if (slideIndex < slideEvents.size()) { + slideIndex++; + } + } + + if (pointIndex > currentEventIndex) { + // 执行点击 + Point clickPoint = moreClickPositions.get(pointIndex - 1); + performClick(clickPoint, pointIndex - 1); + } else if (slideIndex > currentEventIndex) { + // 执行滑动 + Slide slide = slideEvents.get(slideIndex - 1); + performSlide(slide); + } + + currentEventIndex = (currentEventIndex + 1) % (moreClickPositions.size() + slideEvents.size()); + } + + private void performSlide(Slide slide) { + logDebug("执行滑动: 从 (" + slide.startX + ", " + slide.startY + ") 到 (" + slide.endX + ", " + slide.endY + ")"); + + Path path = new Path(); + path.moveTo(slide.startX, slide.startY); + path.lineTo(slide.endX, slide.endY); + GestureDescription.StrokeDescription stroke = + new GestureDescription.StrokeDescription(path, 0, slideDuration); + GestureDescription gesture = + new GestureDescription.Builder().addStroke(stroke).build(); + + dispatchGesture(gesture, new GestureResultCallback() { + @Override + public void onCompleted(GestureDescription gestureDescription) { + logDebug("滑动完成"); + if (isClicking) { + handler.postDelayed(() -> performEvent(), clickInterval); + } + } + + @Override + public void onCancelled(GestureDescription gestureDescription) { + Log.e(TAG, "滑动被取消"); + if (isClicking) { + handler.postDelayed(() -> performEvent(), clickInterval + 300); } } }, null); diff --git a/app/src/main/java/com/auto/autoclicker/ConnectingLineView.java b/app/src/main/java/com/auto/autoclicker/ConnectingLineView.java new file mode 100644 index 0000000..8bfd1ae --- /dev/null +++ b/app/src/main/java/com/auto/autoclicker/ConnectingLineView.java @@ -0,0 +1,37 @@ +package com.auto.autoclicker; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.view.View; + +public class ConnectingLineView extends View { + private float startX, startY, endX, endY; + private Paint paint; + + public ConnectingLineView(Context context) { + super(context); + paint = new Paint(); + paint.setColor(Color.RED); + paint.setAlpha(180); + paint.setStrokeWidth(5); + paint.setAntiAlias(true); + paint.setStyle(Paint.Style.STROKE); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + // 直接在全屏视图上绘制线条 + canvas.drawLine(startX, startY, endX, endY, paint); + } + + public void setPoints(float startX, float startY, float endX, float endY) { + this.startX = startX; + this.startY = startY; + this.endX = endX; + this.endY = endY; + invalidate(); // 请求重绘 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/auto/autoclicker/Event.java b/app/src/main/java/com/auto/autoclicker/Event.java new file mode 100644 index 0000000..19b6bde --- /dev/null +++ b/app/src/main/java/com/auto/autoclicker/Event.java @@ -0,0 +1,5 @@ +package com.auto.autoclicker; + +public interface Event { + int getId(); +} diff --git a/app/src/main/java/com/auto/autoclicker/FloatingViewManager.java b/app/src/main/java/com/auto/autoclicker/FloatingViewManager.java index bade7ac..28cbe02 100644 --- a/app/src/main/java/com/auto/autoclicker/FloatingViewManager.java +++ b/app/src/main/java/com/auto/autoclicker/FloatingViewManager.java @@ -6,6 +6,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Point; import android.os.Build; @@ -66,6 +67,9 @@ public class FloatingViewManager { 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); @@ -166,6 +170,8 @@ public class FloatingViewManager { private void initMoreTouchPointView() { moreTouchPointViews.clear(); moreTouchPointParams.clear(); + eventQueue.clear(); // 清空事件队列 + eventIdCounter = 1; // 重置编号 } @SuppressLint("ClickableViewAccessibility") @@ -271,9 +277,9 @@ public class FloatingViewManager { ImageView settingButton = moreControlBarView.findViewById(R.id.settings_button); playButton.setOnClickListener(v -> toggleMoreClicking()); - addButton.setOnClickListener(v -> addMoreTouchPoint()); - removeButton.setOnClickListener(v -> removeMoreTouchPoint()); - + addButton.setOnClickListener(v -> addPointEvent()); + removeButton.setOnClickListener(v -> removeLastEvent()); + slideButton.setOnClickListener(v -> addSlideEvent()); closeButton.setOnClickListener(v -> closeFloatingViews()); settingButton.setOnClickListener(v -> showInputDialog()); } @@ -334,6 +340,37 @@ public class FloatingViewManager { LocalBroadcastManager.getInstance(context).sendBroadcast(intent); } +// private void toggleMoreClicking() { +// 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); +// return; +// } +// +// if (moreTouchPointViews.isEmpty()) { +// Toast.makeText(context, "请先添加触摸点", Toast.LENGTH_SHORT).show(); +// return; +// } +// +// if (isMoreClicking) { +// service.stopClicking(); +// Toast.makeText(context, "停止多点点击", Toast.LENGTH_SHORT).show(); +// } else { +// service.setMoreClickPositions(getMoreTouchPositions()); +// service.startClicking(); +// Toast.makeText(context, "开始多点点击", Toast.LENGTH_SHORT).show(); +// } +// +// isMoreClicking = !isMoreClicking; +// logDebug("多点服务是否点击中: " + service.isClicking()); +// } + private void toggleMoreClicking() { if (isDebounced()) return; @@ -341,22 +378,26 @@ public class FloatingViewManager { if (service == null) { Log.e(TAG, "AutoClickService 未初始化"); Toast.makeText(context, "请在设置中启用无障碍服务", Toast.LENGTH_LONG).show(); - Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); + Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); return; } - if (moreTouchPointViews.isEmpty()) { - Toast.makeText(context, "请先添加触摸点", Toast.LENGTH_SHORT).show(); + if (eventQueue.isEmpty()) { + Toast.makeText(context, "请先添加触摸点或滑动事件", 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); + } } else { service.setMoreClickPositions(getMoreTouchPositions()); + service.setSlideEvents(getSlideEvents()); service.startClicking(); Toast.makeText(context, "开始多点点击", Toast.LENGTH_SHORT).show(); } @@ -438,6 +479,319 @@ public class FloatingViewManager { moreTouchPointParams.add(params); } + private void addPointEvent() { + View point = new View(context); + point.setBackgroundResource(R.drawable.un_touch_point); + + 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; + + PointEvent pointEvent = new PointEvent(eventIdCounter++, params.x, params.y, point, params); + eventQueue.add(pointEvent); + moreTouchPointViews.add(point); + moreTouchPointParams.add(params); + + point.setOnTouchListener(new View.OnTouchListener() { + private float lastX, lastY; + private float paramX, paramY; + + @Override + public boolean onTouch(View v, MotionEvent event) { + 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); + updateServicePositions(); + return true; + case MotionEvent.ACTION_UP: + v.performClick(); + return true; + } + return false; + } + }); + + windowManager.addView(point, params); + updateServicePositions(); + } + + private void addSlideEvent() { + // 起点 + View startPoint = new View(context); + startPoint.setBackgroundResource(R.drawable.un_touch_point); + 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; + startParams.x = screenWidth / 2 - 100; + startParams.y = screenHeight / 2 - 50; + PointEvent startPointEvent = new PointEvent(eventIdCounter++, startParams.x, startParams.y, startPoint, startParams); + + // 终点 + View endPoint = new View(context); + endPoint.setBackgroundResource(R.drawable.un_touch_point); + 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; + 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; + + SlideEvent slideEvent = new SlideEvent(eventIdCounter++, startPointEvent, endPointEvent, lineView, lineParams); + eventQueue.add(slideEvent); + moreTouchPointViews.add(startPoint); + moreTouchPointViews.add(endPoint); + moreTouchPointParams.add(startParams); + moreTouchPointParams.add(endParams); + + // 起点拖动监听 + startPoint.setOnTouchListener(new View.OnTouchListener() { + private float lastX, lastY; + private float paramX, paramY; + + @Override + public boolean onTouch(View v, MotionEvent event) { + 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) { + 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 void updateLinePosition(SlideEvent slideEvent) { + PointEvent start = slideEvent.startPoint; + PointEvent end = slideEvent.endPoint; + ConnectingLineView lineView = (ConnectingLineView) slideEvent.lineView; + + // 计算两点中心位置 + float startCenterX = start.x + 50; // 假设点的宽度为100 + float startCenterY = start.y + 50; + float endCenterX = end.x + 50; + float endCenterY = end.y + 50; + + // 更新线条位置 - 直接设置线条的起点和终点 + lineView.setPoints(startCenterX, startCenterY, endCenterX, endCenterY); + } + + private void updateLineView(SlideEvent slideEvent) { + WindowManager.LayoutParams lineParams = slideEvent.lineParams; + PointEvent start = slideEvent.startPoint; + PointEvent end = slideEvent.endPoint; + View lineView = slideEvent.lineView; + + // 计算两点中心位置 + float startCenterX = start.x + 50; // 假设点的宽度为100,中心点坐标为x+50 + float startCenterY = start.y + 50; // 假设点的高度为100,中心点坐标为y+50 + float endCenterX = end.x + 50; + float endCenterY = end.y + 50; + + // 计算两点之间的距离和角度 + float deltaX = endCenterX - startCenterX; + float deltaY = endCenterY - startCenterY; + float distance = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY); + float angle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX)); + + // 设置连接线的宽度为两点之间的距离 + lineParams.width = (int) distance; + lineParams.height = 5; // 固定高度 + + // 设置连接线的起始位置为起始点的中心 + lineParams.x = (int) startCenterX; + lineParams.y = (int) startCenterY - lineParams.height / 2; // 垂直居中 + + // 由于线条是从左到右绘制的,我们需要设置旋转中心点 + lineView.setPivotX(0); // 设置旋转中心为线条的起点 + lineView.setPivotY(lineParams.height / 2); // 设置旋转中心为线条高度的一半 + + // 设置连接线的旋转角度 + lineView.setRotation(angle); + + // 更新连接线的布局 + windowManager.updateViewLayout(lineView, lineParams); + } + + // 新增:移除最后一个事件 + private void removeLastEvent() { + if (eventQueue.isEmpty()) { + Toast.makeText(context, "没有更多事件可以删除", 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); + } + updateServicePositions(); + } + + // 新增:同步事件位置到 AutoClickService + 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)); + } 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)); + } + } + AutoClickService service = AutoClickService.getInstance(); + if (service != null) { + service.setMoreClickPositions(points); + service.setSlideEvents(slides); + } + } + private void removeMoreTouchPoint() { if (!moreTouchPointViews.isEmpty()) { View lastPoint = moreTouchPointViews.get(moreTouchPointViews.size() - 1); @@ -477,6 +831,18 @@ public class FloatingViewManager { } moreTouchPointParams.clear(); // 清空参数列表 + for (Event event : new ArrayList<>(eventQueue)) { + if (event instanceof SlideEvent) { + SlideEvent se = (SlideEvent) event; + try { + windowManager.removeView(se.lineView); + } catch (Exception e) { + Log.w(TAG, "移除滑动线失败", e); + } + } + } + eventQueue.clear(); + // 移除单点控制栏 if (singleControlBarView != null) { try { @@ -498,10 +864,12 @@ public class FloatingViewManager { } isClicking = false; + isMoreClicking = false; logDebug("悬浮窗已移除"); } catch (Exception e) { Log.e(TAG, "移除悬浮窗失败", e); isClicking = false; + isMoreClicking = false; } } @@ -588,6 +956,18 @@ 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)); + } + } + return slides; + } + // 改成只闪烁当前索引的触摸点 public void flashTouchPoint(int index) { if (index == -1) { diff --git a/app/src/main/java/com/auto/autoclicker/PointEvent.java b/app/src/main/java/com/auto/autoclicker/PointEvent.java new file mode 100644 index 0000000..624b23e --- /dev/null +++ b/app/src/main/java/com/auto/autoclicker/PointEvent.java @@ -0,0 +1,24 @@ +package com.auto.autoclicker; + +import android.view.View; +import android.view.WindowManager; + +public class PointEvent implements Event { + int id; + float x, y; + View view; + WindowManager.LayoutParams params; + + PointEvent(int id, float x, float y, View view, WindowManager.LayoutParams params) { + this.id = id; + this.x = x; + this.y = y; + this.view = view; + this.params = params; + } + + @Override + public int getId() { + return id; + } +} diff --git a/app/src/main/java/com/auto/autoclicker/Slide.java b/app/src/main/java/com/auto/autoclicker/Slide.java new file mode 100644 index 0000000..79deb3e --- /dev/null +++ b/app/src/main/java/com/auto/autoclicker/Slide.java @@ -0,0 +1,12 @@ +package com.auto.autoclicker; + +public class Slide { + float startX, startY, endX, endY; + + Slide(float startX, float startY, float endX, float 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 new file mode 100644 index 0000000..275b5e0 --- /dev/null +++ b/app/src/main/java/com/auto/autoclicker/SlideEvent.java @@ -0,0 +1,25 @@ +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; + + SlideEvent(int id, PointEvent startPoint, PointEvent endPoint, View lineView, WindowManager.LayoutParams lineParams) { + this.id = id; + this.startPoint = startPoint; + this.endPoint = endPoint; + this.lineView = lineView; + this.lineParams = lineParams; + } + + @Override + public int getId() { + return id; + } +}