优化单点点击实现
This commit is contained in:
parent
60d264e131
commit
84e4871838
@ -151,10 +151,8 @@ public class AutoClickService extends AccessibilityService {
|
||||
}
|
||||
|
||||
private void flashTouchFeedback() {
|
||||
FloatingViewManager manager = FloatingViewManager.getInstance();
|
||||
if (manager != null) {
|
||||
manager.flashTouchPoint();
|
||||
}
|
||||
Intent intent = new Intent("com.auto.autoclicker.FLASH_TOUCH_POINT");
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -3,9 +3,10 @@ package com.auto.autoclicker;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.os.Build;
|
||||
@ -18,12 +19,14 @@ import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.auto.autoclicker.util.PrefUtils;
|
||||
import com.auto.autoclicker.util.ScreenUtils;
|
||||
import com.auto.autoclicker.util.ViewUtils;
|
||||
|
||||
@ -31,8 +34,6 @@ public class FloatingViewManager {
|
||||
private static final String TAG = "FloatingViewManager";
|
||||
private static final long DEBOUNCE_INTERVAL = 500;
|
||||
|
||||
private static FloatingViewManager instance;
|
||||
|
||||
private final Context context;
|
||||
private final WindowManager windowManager;
|
||||
private View touchPointView;
|
||||
@ -46,22 +47,17 @@ public class FloatingViewManager {
|
||||
private long lastToggleTime = 0;
|
||||
private final int screenWidth;
|
||||
private final int screenHeight;
|
||||
private final AutoClickService service = AutoClickService.getInstance();
|
||||
|
||||
public FloatingViewManager(Context context) {
|
||||
this.context = context;
|
||||
instance = this;
|
||||
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);
|
||||
}
|
||||
|
||||
public static FloatingViewManager getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void showFloatingViews() throws SecurityException {
|
||||
if (!Settings.canDrawOverlays(context)) {
|
||||
throw new SecurityException("需要悬浮窗权限");
|
||||
@ -146,7 +142,7 @@ public class FloatingViewManager {
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private void initializeControlBarView() {
|
||||
controlBarView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.control_bar, null);
|
||||
controlBarView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.single_control_bar, null);
|
||||
controlBarParams = new WindowManager.LayoutParams(
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
@ -194,6 +190,8 @@ public class FloatingViewManager {
|
||||
play.setOnClickListener(v -> {
|
||||
if (!isDebounced()) return;
|
||||
|
||||
AutoClickService service = AutoClickService.getInstance();
|
||||
|
||||
if (service == null) {
|
||||
Log.e(TAG, "AutoClickService 未初始化");
|
||||
Toast.makeText(context, "请在设置中启用无障碍服务", Toast.LENGTH_LONG).show();
|
||||
@ -221,9 +219,26 @@ public class FloatingViewManager {
|
||||
});
|
||||
|
||||
close.setOnClickListener(v -> {
|
||||
service.stopClicking();
|
||||
AutoClickService service = AutoClickService.getInstance();
|
||||
|
||||
if (service != null) {
|
||||
service.stopClicking();
|
||||
} else {
|
||||
logDebug("AutoClickService 未初始化");
|
||||
Toast.makeText(context, "请启用无障碍服务", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
touchPointView.setBackgroundResource(R.drawable.un_touch_point);
|
||||
removeFloatingViews();
|
||||
|
||||
context.stopService(new Intent(context, ForegroundService.class));
|
||||
|
||||
PrefUtils.setFloatingShown(context, false);
|
||||
|
||||
Intent intent = new Intent("com.auto.autoclicker.FLOATING_WINDOW_STATE_CHANGED");
|
||||
intent.putExtra("isShown", false);
|
||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
||||
|
||||
});
|
||||
|
||||
setting.setOnClickListener(v -> showInputDialog());
|
||||
@ -276,7 +291,6 @@ public class FloatingViewManager {
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
|
||||
// 设置弹窗的类型,允许在悬浮窗中显示输入框
|
||||
if (!(context instanceof Activity)) {
|
||||
if (dialog.getWindow() != null) {
|
||||
dialog.getWindow().setType(
|
||||
@ -314,6 +328,17 @@ public class FloatingViewManager {
|
||||
.start();
|
||||
}
|
||||
|
||||
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())) {
|
||||
flashTouchPoint();
|
||||
}
|
||||
}
|
||||
}, new IntentFilter("com.auto.autoclicker.FLASH_TOUCH_POINT"));
|
||||
}
|
||||
|
||||
private boolean isDebounced() {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - lastToggleTime < DEBOUNCE_INTERVAL) {
|
||||
|
||||
@ -1,28 +1,42 @@
|
||||
package com.auto.autoclicker;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.auto.autoclicker.databinding.ActivityMainBinding;
|
||||
|
||||
import com.auto.autoclicker.util.PrefUtils;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final String TAG = "MainActivity";
|
||||
private ActivityMainBinding binding;
|
||||
private ActivityResultLauncher<Intent> permissionLauncher;
|
||||
private boolean isFloatingShown = false;
|
||||
private long lastClickTime = 0;
|
||||
private static final long DEBOUNCE_INTERVAL = 500;
|
||||
private boolean isFloatingShown;
|
||||
private static final String ACTION_FLOATING_STATE_CHANGED = "com.auto.autoclicker.FLOATING_WINDOW_STATE_CHANGED";
|
||||
|
||||
private final BroadcastReceiver floatingReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
isFloatingShown = intent.getBooleanExtra("isShown", false);
|
||||
updateButtonText();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -31,7 +45,13 @@ public class MainActivity extends AppCompatActivity {
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
binding.startButton.setOnClickListener(v -> toggleFloatingWindow());
|
||||
isFloatingShown = PrefUtils.isFloatingShown(this);
|
||||
updateButtonText();
|
||||
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(
|
||||
floatingReceiver, new IntentFilter(ACTION_FLOATING_STATE_CHANGED));
|
||||
|
||||
binding.singleButton.setOnClickListener(v -> onToggleFloatingWindowClicked());
|
||||
|
||||
permissionLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> checkPermissions());
|
||||
|
||||
@ -77,7 +97,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
binding.startButton.setEnabled(allPermissionsGranted);
|
||||
binding.singleButton.setEnabled(allPermissionsGranted);
|
||||
updateButtonText();
|
||||
}
|
||||
|
||||
@ -114,9 +134,10 @@ public class MainActivity extends AppCompatActivity {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void toggleFloatingWindow() {
|
||||
public void onToggleFloatingWindowClicked() {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - lastClickTime < DEBOUNCE_INTERVAL) {
|
||||
Toast.makeText(this, "点击太频繁", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
lastClickTime = currentTime;
|
||||
@ -127,7 +148,12 @@ public class MainActivity extends AppCompatActivity {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isFloatingShown) {
|
||||
if (isFloatingShown) {
|
||||
stopService(new Intent(this, ForegroundService.class));
|
||||
AutoClickService.getInstance().stopClicking();
|
||||
isFloatingShown = false;
|
||||
logDebug("悬浮窗已经隐藏");
|
||||
} else {
|
||||
Intent serviceIntent = new Intent(this, ForegroundService.class);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForegroundService(serviceIntent);
|
||||
@ -135,18 +161,31 @@ public class MainActivity extends AppCompatActivity {
|
||||
startService(serviceIntent);
|
||||
}
|
||||
isFloatingShown = true;
|
||||
Toast.makeText(this, "悬浮窗已显示", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
AutoClickService service = AutoClickService.getInstance();
|
||||
stopService(new Intent(this, ForegroundService.class));
|
||||
service.stopClicking();
|
||||
isFloatingShown = false;
|
||||
Toast.makeText(this, "悬浮窗已隐藏", Toast.LENGTH_SHORT).show();
|
||||
logDebug("悬浮窗已经显示");
|
||||
}
|
||||
|
||||
PrefUtils.setFloatingShown(this, isFloatingShown);
|
||||
broadcastFloatingState(isFloatingShown);
|
||||
updateButtonText();
|
||||
}
|
||||
|
||||
private void broadcastFloatingState(boolean isShown) {
|
||||
Intent intent = new Intent(ACTION_FLOATING_STATE_CHANGED);
|
||||
intent.putExtra("isShown", isShown);
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
|
||||
}
|
||||
|
||||
private void updateButtonText() {
|
||||
binding.startButton.setText(isFloatingShown ? R.string.hide_floating_window : R.string.show_floating_window);
|
||||
binding.singleButton.setText(isFloatingShown ? "隐藏悬浮窗" : "显示悬浮窗");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(floatingReceiver);
|
||||
}
|
||||
|
||||
private void logDebug(String message) {
|
||||
Log.d(TAG, message);
|
||||
}
|
||||
}
|
||||
18
app/src/main/java/com/auto/autoclicker/util/PrefUtils.java
Normal file
18
app/src/main/java/com/auto/autoclicker/util/PrefUtils.java
Normal file
@ -0,0 +1,18 @@
|
||||
package com.auto.autoclicker.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class PrefUtils {
|
||||
private static final String PREF_NAME = "app_prefs";
|
||||
private static final String KEY_FLOATING_SHOWN = "floating_window_shown";
|
||||
|
||||
public static void setFloatingShown(Context context, boolean shown) {
|
||||
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||
.edit().putBoolean(KEY_FLOATING_SHOWN, shown).apply();
|
||||
}
|
||||
|
||||
public static boolean isFloatingShown(Context context) {
|
||||
return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||
.getBoolean(KEY_FLOATING_SHOWN, false);
|
||||
}
|
||||
}
|
||||
@ -4,8 +4,18 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<Button
|
||||
android:id="@+id/start_Button"
|
||||
= <TextView
|
||||
android:id="@+id/single_hint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="启动单点连点器"
|
||||
app:layout_constraintBottom_toTopOf="@+id/single_button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
= <Button
|
||||
android:id="@+id/single_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/start_button"
|
||||
@ -14,4 +24,24 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
= <TextView
|
||||
android:id="@+id/more_hint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="25dp"
|
||||
android:text="启动多点连点器"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/single_button" />
|
||||
|
||||
= <Button
|
||||
android:id="@+id/more_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/start_button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/more_hint" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
45
app/src/main/res/layout/single_control_bar.xml
Normal file
45
app/src/main/res/layout/single_control_bar.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/rounded_background"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/play_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:src="@drawable/play" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/file_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:src="@drawable/save" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/eye_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:src="@drawable/eye" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/settings_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:src="@drawable/setting" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/close_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:src="@drawable/cancel" />
|
||||
|
||||
</LinearLayout>
|
||||
Loading…
Reference in New Issue
Block a user