功能优化

This commit is contained in:
lihongwei 2025-06-27 13:48:31 +08:00
parent d021cdc9a9
commit 452f1d6377
5 changed files with 214 additions and 27 deletions

View File

@ -1,5 +1,6 @@
package com.auto.clicker.autoclicker.data; package com.auto.clicker.autoclicker.data;
import android.util.Log;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.TextView; import android.widget.TextView;
@ -31,6 +32,7 @@ public class PointEvent extends Event {
} }
public void setX(int x) { public void setX(int x) {
Log.d("PointEvent", "setX called on id=" + id + " with x=" + x);
this.x = x; this.x = x;
} }

View File

@ -12,12 +12,13 @@ import android.view.accessibility.AccessibilityEvent;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.auto.clicker.autoclicker.data.Event; import com.auto.clicker.autoclicker.data.Event;
import com.auto.clicker.autoclicker.data.EventWrapper; import com.auto.clicker.autoclicker.data.EventWrapper;
import com.auto.clicker.autoclicker.data.PointEvent; import com.auto.clicker.autoclicker.data.PointEvent;
import com.auto.clicker.autoclicker.data.SlideEvent; import com.auto.clicker.autoclicker.data.SlideEvent;
import com.auto.clicker.autoclicker.util.EventViewBinder;
import com.auto.clicker.autoclicker.util.ScreenUtils; import com.auto.clicker.autoclicker.util.ScreenUtils;
import com.auto.clicker.autoclicker.view.FloatingViewManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
@ -36,6 +37,9 @@ public class AutoClickService extends AccessibilityService {
private List<EventWrapper> runtimeEvents = new ArrayList<>(); private List<EventWrapper> runtimeEvents = new ArrayList<>();
private FloatingViewManager floatingViewManager;
private int touchPointSize;
private final Handler handler = new Handler(Looper.getMainLooper()); private final Handler handler = new Handler(Looper.getMainLooper());
private boolean isRunning = false; private boolean isRunning = false;
@ -52,6 +56,15 @@ public class AutoClickService extends AccessibilityService {
int screenWidth = screenSize.x; int screenWidth = screenSize.x;
int screenHeight = screenSize.y; int screenHeight = screenSize.y;
logDebug("屏幕尺寸: " + screenWidth + "x" + screenHeight); logDebug("屏幕尺寸: " + screenWidth + "x" + screenHeight);
ForegroundService service = ForegroundService.getInstance();
if (service != null) {
floatingViewManager = service.getFloatingViewManager();
}
if (floatingViewManager != null) {
touchPointSize = floatingViewManager.getTouchPointSize();
}
} }
public static AutoClickService getInstance() { public static AutoClickService getInstance() {
@ -118,6 +131,9 @@ public class AutoClickService extends AccessibilityService {
isRunning = true; isRunning = true;
currentEventIndex = 0; currentEventIndex = 0;
EventViewBinder.setAllTouchPointsDraggable(false);
logDebug("开始执行事件队列 - 共 " + runtimeEvents.size() + " 个事件"); logDebug("开始执行事件队列 - 共 " + runtimeEvents.size() + " 个事件");
executeEventsByType(); executeEventsByType();
} }
@ -127,6 +143,9 @@ public class AutoClickService extends AccessibilityService {
if (isRunning) { if (isRunning) {
isRunning = false; isRunning = false;
handler.removeCallbacksAndMessages(null); handler.removeCallbacksAndMessages(null);
EventViewBinder.setAllTouchPointsDraggable(true);
logDebug("停止执行事件"); logDebug("停止执行事件");
} }
} }
@ -162,13 +181,20 @@ public class AutoClickService extends AccessibilityService {
} }
private void performSingleClick(PointEvent pointEvent) { private void performSingleClick(PointEvent pointEvent) {
int x = pointEvent.getX(); int viewLeftX = pointEvent.getX();
int y = pointEvent.getY(); int viewTopY = pointEvent.getY();
logDebug("执行点击: (" + x + ", " + y + ")"); final int CORRECTION_X = 54;
final int CORRECTION_Y = 165;
int correctedViewLeftX = viewLeftX + CORRECTION_X;
int correctedViewTopY = viewTopY + CORRECTION_Y;
int finalClickX = correctedViewLeftX + touchPointSize / 2;
int finalClickY = correctedViewTopY + touchPointSize / 2;
Path path = new Path(); Path path = new Path();
path.moveTo(x, y); path.moveTo(finalClickX, finalClickY); // 使用最终计算出的点击中心坐标
GestureDescription.StrokeDescription stroke = GestureDescription.StrokeDescription stroke =
new GestureDescription.StrokeDescription(path, 0, clickDuration); new GestureDescription.StrokeDescription(path, 0, clickDuration);
GestureDescription gesture = GestureDescription gesture =
@ -200,16 +226,34 @@ public class AutoClickService extends AccessibilityService {
private void performSlide(SlideEvent slideEvent) { private void performSlide(SlideEvent slideEvent) {
PointEvent start = slideEvent.getStartPoint(); PointEvent start = slideEvent.getStartPoint();
PointEvent end = slideEvent.getEndPoint(); PointEvent end = slideEvent.getEndPoint();
int startX = start.getX();
int startY = start.getY();
int endX = end.getX();
int endY = end.getY();
logDebug("执行滑动: 从 (" + startX + ", " + startY + ") 到 (" + endX + ", " + endY + ")"); int viewStartX = start.getX();
int viewStartY = start.getY();
int viewEndX = end.getX();
int viewEndY = end.getY();
logDebug("--- performSlide start ---");
logDebug("原始 SlideEvent 起点: (" + viewStartX + ", " + viewStartY + ")");
logDebug("原始 SlideEvent 终点: (" + viewEndX + ", " + viewEndY + ")");
final int CORRECTION_X = 54;
final int CORRECTION_Y = 165;
int finalStartX = viewStartX + CORRECTION_X + touchPointSize / 2;
int finalStartY = viewStartY + CORRECTION_Y + touchPointSize / 2;
int finalEndX = viewEndX + CORRECTION_X + touchPointSize / 2;
int finalEndY = viewEndY + CORRECTION_Y + touchPointSize / 2;
logDebug("滑动起点(视图坐标): (" + viewStartX + ", " + viewStartY + ")");
logDebug("滑动终点(视图坐标): (" + viewEndX + ", " + viewEndY + ")");
logDebug("滑动起点(修正后): (" + finalStartX + ", " + finalStartY + ")");
logDebug("滑动终点(修正后): (" + finalEndX + ", " + finalEndY + ")");
Path path = new Path(); Path path = new Path();
path.moveTo(startX, startY); // 这里必须使用修正后的坐标才能确保手势在正确的位置执行
path.lineTo(endX, endY); path.moveTo(finalStartX, finalStartY);
path.lineTo(finalEndX, finalEndY);
GestureDescription.StrokeDescription stroke = GestureDescription.StrokeDescription stroke =
new GestureDescription.StrokeDescription(path, 0, slideDuration); new GestureDescription.StrokeDescription(path, 0, slideDuration);
GestureDescription gesture = GestureDescription gesture =
@ -225,6 +269,10 @@ public class AutoClickService extends AccessibilityService {
handler.postDelayed(() -> executeEventsByType(), clickInterval); handler.postDelayed(() -> executeEventsByType(), clickInterval);
flashTouchFeedback(feedbackIndex); flashTouchFeedback(feedbackIndex);
} }
logDebug("--- onCompleted: 下一个事件将是 index " + currentEventIndex + " ---");
// 再次打印确认 slideEvent.getStartPoint() getEndPoint() 是否被意外修改
logDebug("onCompleted 后SlideEvent 起点: (" + slideEvent.getStartPoint().getX() + ", " + slideEvent.getStartPoint().getY() + ")");
logDebug("onCompleted 后SlideEvent 终点: (" + slideEvent.getEndPoint().getX() + ", " + slideEvent.getEndPoint().getY() + ")");
} }
@Override @Override
@ -234,8 +282,13 @@ public class AutoClickService extends AccessibilityService {
currentEventIndex++; currentEventIndex++;
handler.postDelayed(() -> executeEventsByType(), clickInterval + 300); handler.postDelayed(() -> executeEventsByType(), clickInterval + 300);
} }
logDebug("--- onCancelled: 下一个事件将是 index " + currentEventIndex + " ---");
// 再次打印确认 slideEvent.getStartPoint() getEndPoint() 是否被意外修改
logDebug("onCancelled 后SlideEvent 起点: (" + slideEvent.getStartPoint().getX() + ", " + slideEvent.getStartPoint().getY() + ")");
logDebug("onCancelled 后SlideEvent 终点: (" + slideEvent.getEndPoint().getX() + ", " + slideEvent.getEndPoint().getY() + ")");
} }
}, null); }, null);
logDebug("--- performSlide end ---");
} }
private void flashTouchFeedback(int index) { private void flashTouchFeedback(int index) {
@ -257,6 +310,9 @@ public class AutoClickService extends AccessibilityService {
super.onDestroy(); super.onDestroy();
instance = null; instance = null;
stopClicking(); stopClicking();
EventViewBinder.setAllTouchPointsDraggable(true);
Intent intent = new Intent("com.auto.clicker.autoclicker.SERVICE_DESTROYED"); Intent intent = new Intent("com.auto.clicker.autoclicker.SERVICE_DESTROYED");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent); LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
logDebug("无障碍服务已销毁"); logDebug("无障碍服务已销毁");

View File

@ -7,6 +7,8 @@ import android.os.Build;
import android.util.Log; import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.TextView; import android.widget.TextView;
@ -15,19 +17,26 @@ import com.auto.clicker.autoclicker.data.PointEvent;
import com.auto.clicker.autoclicker.data.SlideEvent; import com.auto.clicker.autoclicker.data.SlideEvent;
import com.auto.clicker.autoclicker.view.ConnectingLineView; import com.auto.clicker.autoclicker.view.ConnectingLineView;
import java.util.HashMap;
import java.util.Map;
public class EventViewBinder { public class EventViewBinder {
// 存储每个视图及其对应的 OnTouchListener 实例用于启用/禁用拖动
private static final Map<View, View.OnTouchListener> activeDragListeners = new HashMap<>();
public interface OnPositionChangedCallback { public interface OnPositionChangedCallback {
void onPositionChanged(int x, int y); void onPositionChanged(int x, int y);
} }
// --- bindPoint 方法 ---
public static void bindPoint(Context context, WindowManager windowManager, public static void bindPoint(Context context, WindowManager windowManager,
PointEvent pointEvent, int touchPointSize, PointEvent pointEvent, int touchPointSize,
int screenWidth, int screenHeight, int screenWidth, int screenHeight,
OnPositionChangedCallback callback,int order,float initialTextSize) { OnPositionChangedCallback callback, int order, float initialTextSize) {
TextView pointView = createTouchPointView(context, String.valueOf(order)); TextView pointView = createTouchPointView(context, String.valueOf(order));
Log.d("bind","id: " + order); Log.d("bind", "id: " + order);
WindowManager.LayoutParams params = createTouchPointParams(context, touchPointSize); WindowManager.LayoutParams params = createTouchPointParams(context, touchPointSize);
params.x = pointEvent.getX(); params.x = pointEvent.getX();
@ -38,21 +47,26 @@ public class EventViewBinder {
pointView.setTextSize(TypedValue.COMPLEX_UNIT_SP, initialTextSize); pointView.setTextSize(TypedValue.COMPLEX_UNIT_SP, initialTextSize);
DraggableHelper.makeDraggable(pointView, params, windowManager, // 创建并保存 OnTouchListener
screenWidth, screenHeight, View.OnTouchListener touchListener = createTouchListener(
pointView, params, windowManager, screenWidth, screenHeight,
(x, y) -> { (x, y) -> {
pointEvent.setX(x); pointEvent.setX(x);
pointEvent.setY(y); pointEvent.setY(y);
if (callback != null) callback.onPositionChanged(x, y); if (callback != null) callback.onPositionChanged(x, y);
}); });
pointView.setOnTouchListener(touchListener);
activeDragListeners.put(pointView, touchListener); // 保存监听器到 Map
windowManager.addView(pointView, params); windowManager.addView(pointView, params);
} }
// --- bindSlide 方法 ---
public static void bindSlide(Context context, WindowManager windowManager, public static void bindSlide(Context context, WindowManager windowManager,
SlideEvent slideEvent, int touchPointSize, SlideEvent slideEvent, int touchPointSize,
int screenWidth, int screenHeight, int screenWidth, int screenHeight,
OnPositionChangedCallback callback,int order,float initialTextSize) { OnPositionChangedCallback callback, int order, float initialTextSize) {
PointEvent start = slideEvent.getStartPoint(); PointEvent start = slideEvent.getStartPoint();
PointEvent end = slideEvent.getEndPoint(); PointEvent end = slideEvent.getEndPoint();
@ -81,25 +95,29 @@ public class EventViewBinder {
slideEvent.setLineView(lineView); slideEvent.setLineView(lineView);
slideEvent.setLineParams(lineParams); slideEvent.setLineParams(lineParams);
// 拖动起点 // 拖动起点 - 创建并保存监听器
DraggableHelper.makeDraggable(startView, startParams, windowManager, View.OnTouchListener startTouchListener = createTouchListener(
screenWidth, screenHeight, startView, startParams, windowManager, screenWidth, screenHeight,
(x, y) -> { (x, y) -> {
start.setX(x); start.setX(x);
start.setY(y); start.setY(y);
updateLinePosition(slideEvent, touchPointSize); updateLinePosition(slideEvent, touchPointSize);
if (callback != null) callback.onPositionChanged(x, y); if (callback != null) callback.onPositionChanged(x, y);
}); });
startView.setOnTouchListener(startTouchListener);
activeDragListeners.put(startView, startTouchListener); // 保存监听器
// 拖动终点 // 拖动终点 - 创建并保存监听器
DraggableHelper.makeDraggable(endView, endParams, windowManager, View.OnTouchListener endTouchListener = createTouchListener(
screenWidth, screenHeight, endView, endParams, windowManager, screenWidth, screenHeight,
(x, y) -> { (x, y) -> {
end.setX(x); end.setX(x);
end.setY(y); end.setY(y);
updateLinePosition(slideEvent, touchPointSize); updateLinePosition(slideEvent, touchPointSize);
if (callback != null) callback.onPositionChanged(x, y); if (callback != null) callback.onPositionChanged(x, y);
}); });
endView.setOnTouchListener(endTouchListener);
activeDragListeners.put(endView, endTouchListener); // 保存监听器
windowManager.addView(lineView, lineParams); windowManager.addView(lineView, lineParams);
windowManager.addView(startView, startParams); windowManager.addView(startView, startParams);
@ -108,12 +126,95 @@ public class EventViewBinder {
updateLinePosition(slideEvent, touchPointSize); updateLinePosition(slideEvent, touchPointSize);
} }
// --- DraggableHelper 移动过来的 OnTouchListener 创建逻辑 ---
// 这个方法创建并返回一个 View.OnTouchListener 实例
private static View.OnTouchListener createTouchListener(
View view, WindowManager.LayoutParams params, WindowManager windowManager,
int screenWidth, int screenHeight, DraggableHelper.DragCallback callback) { // 仍然使用 DraggableHelper.DragCallback 接口
return new View.OnTouchListener() {
private float lastX, lastY;
private float paramX, paramY;
private boolean isDragging = false; // 标记是否正在拖动
@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;
isDragging = false; // 重置拖动状态
return true;
case MotionEvent.ACTION_MOVE:
isDragging = true; // 正在拖动
float dx = event.getRawX() - lastX;
float dy = event.getRawY() - lastY;
int newX = (int) (paramX + dx);
int newY = (int) (paramY + dy);
newX = Math.max(0, Math.min(newX, screenWidth - view.getWidth()));
newY = Math.max(0, Math.min(newY, screenHeight - view.getHeight()));
params.x = newX;
params.y = newY;
windowManager.updateViewLayout(view, params);
if (callback != null) {
callback.onPositionChanged(newX, newY);
}
return true;
case MotionEvent.ACTION_UP:
if (!isDragging) { // 如果没有拖动才视为点击
v.performClick();
}
return true;
}
return false;
}
};
}
// --- 新增方法统一控制所有触摸点的拖动状态 ---
public static void setAllTouchPointsDraggable(boolean draggable) {
for (Map.Entry<View, View.OnTouchListener> entry : activeDragListeners.entrySet()) {
View view = entry.getKey();
View.OnTouchListener listener = entry.getValue();
if (draggable) {
// 启用拖动重新设置保存的监听器
view.setOnTouchListener(listener);
} else {
// 禁用拖动将监听器设置为 null阻止触摸事件
view.setOnTouchListener(null);
}
}
}
// --- 新增方法移除不再需要的视图及其监听器 ---
public static void removeBoundView(WindowManager windowManager, View view) {
if (view != null) {
try {
windowManager.removeView(view);
activeDragListeners.remove(view); // Map 中移除
Log.d("EventViewBinder", "移除视图并清理监听器: " + view.getTag());
} catch (IllegalArgumentException e) {
Log.e("EventViewBinder", "尝试移除不存在的视图: " + e.getMessage());
}
}
}
// --- 辅助方法 (保持不变) ---
public static TextView createTouchPointView(Context context, String label) { public static TextView createTouchPointView(Context context, String label) {
TextView touchPointView = new TextView(context); TextView touchPointView = new TextView(context);
touchPointView.setBackgroundResource(R.drawable.ring_has_bg); touchPointView.setBackgroundResource(R.drawable.ring_has_bg);
touchPointView.setGravity(Gravity.CENTER); touchPointView.setGravity(Gravity.CENTER);
touchPointView.setText(label); touchPointView.setText(label);
touchPointView.setTextColor(Color.WHITE); touchPointView.setTextColor(Color.WHITE);
touchPointView.setTag(label); // 添加一个Tag方便日志识别
return touchPointView; return touchPointView;
} }
@ -144,7 +245,7 @@ public class EventViewBinder {
overlayType, overlayType,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, // 线条通常不可触摸
PixelFormat.TRANSLUCENT PixelFormat.TRANSLUCENT
); );
params.gravity = Gravity.TOP | Gravity.START; params.gravity = Gravity.TOP | Gravity.START;
@ -168,4 +269,3 @@ public class EventViewBinder {
lineView.setPoints(startCenterX, startCenterY, endCenterX, endCenterY); lineView.setPoints(startCenterX, startCenterY, endCenterX, endCenterY);
} }
} }

View File

@ -86,6 +86,8 @@ public class FloatingViewManager {
private static final int DEFAULT_TOUCH_POINT_SIZE = 100; private static final int DEFAULT_TOUCH_POINT_SIZE = 100;
private static final int DEFAULT_CONTROL_BAR_WIDTH_DP = 38; private static final int DEFAULT_CONTROL_BAR_WIDTH_DP = 38;
private ImageView playButton;
public FloatingViewManager(Context context) { public FloatingViewManager(Context context) {
this.context = context; this.context = context;
this.windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); this.windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@ -223,7 +225,7 @@ public class FloatingViewManager {
} }
private void setupControlButtons(LinearLayout controlBar,int mode) { private void setupControlButtons(LinearLayout controlBar,int mode) {
ImageView playButton = controlBar.findViewById(R.id.play_button); playButton = controlBar.findViewById(R.id.play_button);
ImageView addButton = controlBar.findViewById(R.id.add_button); ImageView addButton = controlBar.findViewById(R.id.add_button);
ImageView removeButton = controlBar.findViewById(R.id.remove_button); ImageView removeButton = controlBar.findViewById(R.id.remove_button);
ImageView slideButton = controlBar.findViewById(R.id.slide_button); ImageView slideButton = controlBar.findViewById(R.id.slide_button);
@ -239,6 +241,10 @@ public class FloatingViewManager {
addPointEvent(); addPointEvent();
} }
AutoClickService service = AutoClickService.getInstance();
boolean serviceIsRunning = (service != null && service.isClicking());
updatePlayButtonImage(serviceIsRunning);
playButton.setOnClickListener(v -> toggleMultipleClicking()); playButton.setOnClickListener(v -> toggleMultipleClicking());
addButton.setOnClickListener(v -> addPointEvent()); addButton.setOnClickListener(v -> addPointEvent());
removeButton.setOnClickListener(v -> removeLastEvent()); removeButton.setOnClickListener(v -> removeLastEvent());
@ -286,6 +292,8 @@ public class FloatingViewManager {
isMultipleRunning = !isMultipleRunning; isMultipleRunning = !isMultipleRunning;
Log.d(TAG, "多点点击服务状态: " + service.isClicking()); Log.d(TAG, "多点点击服务状态: " + service.isClicking());
updatePlayButtonImage(isMultipleRunning);
} }
private void addPointEvent() { private void addPointEvent() {
@ -906,4 +914,16 @@ public class FloatingViewManager {
public int getControlBarWidth() { public int getControlBarWidth() {
return controlBarWidth; return controlBarWidth;
} }
private void updatePlayButtonImage(boolean isRunning) {
if (playButton == null) {
return;
}
if (isRunning) {
playButton.setImageResource(R.drawable.pause);
} else {
playButton.setImageResource(R.drawable.play);
}
}
} }

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M2,0L12,0A2,2 0,0 1,14 2L14,12A2,2 0,0 1,12 14L2,14A2,2 0,0 1,0 12L0,2A2,2 0,0 1,2 0z"
android:fillColor="#E83434"/>
</vector>