├── AndroidManifest.xml
├── README.md
├── java
└── com
│ └── example
│ └── android
│ └── autoclick
│ ├── AutoService.java
│ ├── FloatingManager.java
│ ├── FloatingView.java
│ └── MainActivity.java
└── res
├── drawable-v24
└── ic_launcher_foreground.xml
├── drawable
└── ic_launcher_background.xml
├── layout
├── activity_main.xml
└── floating_view.xml
├── mipmap-anydpi-v26
├── ic_launcher.xml
└── ic_launcher_round.xml
├── mipmap-hdpi
├── ic_launcher.png
└── ic_launcher_round.png
├── mipmap-mdpi
├── ic_launcher.png
└── ic_launcher_round.png
├── mipmap-xhdpi
├── ic_launcher.png
└── ic_launcher_round.png
├── mipmap-xxhdpi
├── ic_launcher.png
└── ic_launcher_round.png
├── mipmap-xxxhdpi
├── ic_launcher.png
└── ic_launcher_round.png
├── values
├── colors.xml
├── strings.xml
└── styles.xml
└── xml
└── global_action_bar_service.xml
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
25 |
26 |
29 |
30 |
31 |
32 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AutoClicker
2 | An auto clicker app made using android studio accessibility service
3 | Upon the pressing of "start" button on the draggable floating window,
4 | the app will "tap" the screen on the user's behalf at the current location of the floating window
5 |
--------------------------------------------------------------------------------
/java/com/example/android/autoclick/AutoService.java:
--------------------------------------------------------------------------------
1 | package com.example.android.autoclick;
2 |
3 | import android.accessibilityservice.AccessibilityService;
4 | import android.accessibilityservice.GestureDescription;
5 | import android.content.Intent;
6 | import android.graphics.Path;
7 | import android.os.Handler;
8 | import android.os.HandlerThread;
9 | import android.util.Log;
10 | import android.view.accessibility.AccessibilityEvent;
11 | import android.widget.Toast;
12 |
13 | import androidx.annotation.RequiresApi;
14 |
15 | public class AutoService extends AccessibilityService {
16 | private Handler mHandler;
17 | private int mX;
18 | private int mY;
19 |
20 |
21 | @Override
22 | public void onCreate() {
23 | super.onCreate();
24 | HandlerThread handlerThread = new HandlerThread("auto-handler");
25 | handlerThread.start();
26 | mHandler = new Handler(handlerThread.getLooper());
27 | }
28 |
29 | @Override
30 | protected void onServiceConnected() {
31 |
32 | }
33 |
34 | @Override
35 | public int onStartCommand(Intent intent, int flags, int startId) {
36 | Log.d("Service","SERVICE STARTED");
37 | if(intent!=null){
38 | String action = intent.getStringExtra("action");
39 | if (action.equals("play")) {
40 | mX = intent.getIntExtra("x", 0);
41 | //Log.d("x_value",Integer.toString(mX));
42 | mY = intent.getIntExtra("y", 0);
43 | if (mRunnable == null) {
44 | mRunnable = new IntervalRunnable();
45 | }
46 | //playTap(mX,mY);
47 | //mHandler.postDelayed(mRunnable, 1000);
48 | mHandler.post(mRunnable);
49 | Toast.makeText(getBaseContext(), "Started", Toast.LENGTH_SHORT).show();
50 | }
51 | else if(action.equals("stop")){
52 | mHandler.removeCallbacksAndMessages(null);
53 | }
54 | }
55 | return super.onStartCommand(intent, flags, startId);
56 | }
57 |
58 | //@RequiresApi(api = Build.VERSION_CODES.N)
59 | private void playTap(int x, int y) {
60 | //Log.d("TAPPED","STARTED TAPpING");
61 | Path swipePath = new Path();
62 | swipePath.moveTo(x, y);
63 | swipePath.lineTo(x, y);
64 | GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
65 | gestureBuilder.addStroke(new GestureDescription.StrokeDescription(swipePath, 0, 10));
66 | //dispatchGesture(gestureBuilder.build(), null, null);
67 | //Log.d("hello","hello?");
68 | dispatchGesture(gestureBuilder.build(), new GestureResultCallback() {
69 | @Override
70 | public void onCompleted(GestureDescription gestureDescription) {
71 | Log.d("Gesture Completed","Gesture Completed");
72 | super.onCompleted(gestureDescription);
73 | //mHandler.postDelayed(mRunnable, 1);
74 | mHandler.post(mRunnable);
75 | }
76 |
77 | @Override
78 | public void onCancelled(GestureDescription gestureDescription) {
79 | //Log.d("Gesture Cancelled","Gesture Cancelled");
80 | super.onCancelled(gestureDescription);
81 | }
82 | }, null);
83 | //Log.d("hi","hi?");
84 | }
85 |
86 | @Override
87 | public void onAccessibilityEvent(AccessibilityEvent event) {
88 |
89 | }
90 |
91 |
92 | @Override
93 | public void onInterrupt() {
94 | }
95 |
96 |
97 | private IntervalRunnable mRunnable;
98 |
99 | private class IntervalRunnable implements Runnable {
100 | @Override
101 | public void run() {
102 | //Log.d("clicked","click");
103 | playTap(mX, mY);
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/java/com/example/android/autoclick/FloatingManager.java:
--------------------------------------------------------------------------------
1 | package com.example.android.autoclick;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.WindowManager;
6 |
7 |
8 | public class FloatingManager {
9 | private WindowManager mWindowManager;
10 | private static FloatingManager mInstance;
11 | private Context mContext;
12 |
13 | public static FloatingManager getInstance(Context context) {
14 | if (mInstance == null) {
15 | mInstance = new FloatingManager(context);
16 | }
17 | return mInstance;
18 | }
19 |
20 | private FloatingManager(Context context) {
21 | mContext = context;
22 | mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);//获得WindowManager对象
23 | }
24 |
25 | /**
26 | * adds floating view
27 | *
28 | * @param view
29 | * @param params
30 | * @return
31 | */
32 | protected boolean addView(View view, WindowManager.LayoutParams params) {
33 | try {
34 | mWindowManager.addView(view, params);
35 | return true;
36 | } catch (Exception e) {
37 | e.printStackTrace();
38 | }
39 | return false;
40 | }
41 |
42 | /**
43 | * removes floating view
44 | *
45 | * @param view
46 | * @return
47 | */
48 | protected boolean removeView(View view) {
49 | try {
50 | mWindowManager.removeView(view);
51 | return true;
52 | } catch (Exception e) {
53 | e.printStackTrace();
54 | }
55 | return false;
56 | }
57 |
58 | /**
59 | *
60 | *
61 | * @param view
62 | * @param params
63 | * @return
64 | */
65 | protected boolean updateView(View view, WindowManager.LayoutParams params) {
66 | try {
67 | mWindowManager.updateViewLayout(view, params);
68 | return true;
69 | } catch (Exception e) {
70 | e.printStackTrace();
71 | }
72 | return false;
73 | }
74 | }
--------------------------------------------------------------------------------
/java/com/example/android/autoclick/FloatingView.java:
--------------------------------------------------------------------------------
1 | package com.example.android.autoclick;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.graphics.PixelFormat;
6 | import android.os.Build;
7 | import android.os.IBinder;
8 | import android.util.Log;
9 | import android.view.LayoutInflater;
10 | import android.view.MotionEvent;
11 | import android.view.View;
12 | import android.view.WindowManager;
13 | import android.widget.Button;
14 |
15 | import com.example.android.autoclick.R;
16 |
17 |
18 | public class FloatingView extends Service implements View.OnClickListener {
19 | private WindowManager mWindowManager;
20 | private View myFloatingView;
21 |
22 | @Override
23 | public IBinder onBind(Intent intent) {
24 | return null;
25 | }
26 |
27 |
28 | @Override
29 | public void onCreate() {
30 | super.onCreate();
31 |
32 |
33 | //getting the widget layout from xml using layout inflater
34 | myFloatingView = LayoutInflater.from(this).inflate(R.layout.floating_view, null);
35 |
36 |
37 | int layout_parms;
38 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
39 |
40 | {
41 | layout_parms = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
42 |
43 | }
44 |
45 | else {
46 |
47 | layout_parms = WindowManager.LayoutParams.TYPE_PHONE;
48 |
49 | }
50 |
51 | //setting the layout parameters
52 | final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
53 | WindowManager.LayoutParams.WRAP_CONTENT,
54 | WindowManager.LayoutParams.WRAP_CONTENT,
55 | layout_parms,
56 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
57 | PixelFormat.TRANSLUCENT);
58 |
59 |
60 | //getting windows services and adding the floating view to it
61 | mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
62 | mWindowManager.addView(myFloatingView, params);
63 |
64 |
65 |
66 | //adding an touchlistener to make drag movement of the floating widget
67 | myFloatingView.findViewById(R.id.thisIsAnID).setOnTouchListener(new View.OnTouchListener() {
68 | private int initialX;
69 | private int initialY;
70 | private float initialTouchX;
71 | private float initialTouchY;
72 | @Override
73 | public boolean onTouch(View v, MotionEvent event) {
74 | Log.d("TOUCH","THIS IS TOUCHED");
75 | switch (event.getAction()) {
76 | case MotionEvent.ACTION_DOWN:
77 | initialX = params.x;
78 | initialY = params.y;
79 | initialTouchX = event.getRawX();
80 | initialTouchY = event.getRawY();
81 | return true;
82 |
83 | case MotionEvent.ACTION_UP:
84 |
85 | return true;
86 |
87 | case MotionEvent.ACTION_MOVE:
88 | //this code is helping the widget to move around the screen with fingers
89 | params.x = initialX + (int) (event.getRawX() - initialTouchX);
90 | params.y = initialY + (int) (event.getRawY() - initialTouchY);
91 | mWindowManager.updateViewLayout(myFloatingView, params);
92 | return true;
93 | }
94 | return false;
95 | }
96 | });
97 |
98 | Button startButton = (Button) myFloatingView.findViewById(R.id.start);
99 | startButton.setOnClickListener(this);
100 | Button stopButton = (Button) myFloatingView.findViewById(R.id.stop);
101 | stopButton.setOnClickListener(this);
102 |
103 | }
104 |
105 | @Override
106 | public void onDestroy() {
107 | super.onDestroy();
108 | if (myFloatingView != null) mWindowManager.removeView(myFloatingView);
109 | }
110 |
111 |
112 | @Override
113 | public void onClick(View v) {
114 | //Log.d("onClick","THIS IS CLICKED");
115 | Intent intent = new Intent(getApplicationContext(), AutoService.class);
116 | switch (v.getId()) {
117 | case R.id.start:
118 | //Log.d("START","THIS IS STARTED");
119 | int[] location = new int[2];
120 | myFloatingView.getLocationOnScreen(location);
121 | intent.putExtra("action", "play");
122 | intent.putExtra("x", location[0] - 1);
123 | intent.putExtra("y", location[1] - 1);
124 | break;
125 | case R.id.stop:
126 | intent.putExtra("action", "stop");
127 | mWindowManager.removeView(myFloatingView);
128 | Intent appMain = new Intent(getApplicationContext(), MainActivity.class);
129 |
130 | //getApplication().startActivity(appMain);
131 | //requires the FLAG_ACTIVITY_NEW_TASK flag
132 | }
133 | getApplication().startService(intent);
134 | }
135 |
136 | }
--------------------------------------------------------------------------------
/java/com/example/android/autoclick/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.android.autoclick;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.content.Intent;
6 | import android.net.Uri;
7 | import android.os.Build;
8 | import android.os.Bundle;
9 | import android.provider.Settings;
10 | import android.view.View;
11 | import android.widget.Toast;
12 |
13 | import com.example.android.autoclick.R;
14 |
15 | public class MainActivity extends AppCompatActivity implements View.OnClickListener{
16 | //FrameLayout mLayout;
17 | private static final int SYSTEM_ALERT_WINDOW_PERMISSION = 2084;
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_main);
23 |
24 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
25 | askPermission();
26 | }
27 | findViewById(R.id.startFloat).setOnClickListener(this);
28 | }
29 |
30 |
31 |
32 | private void askPermission() {
33 | Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
34 | Uri.parse("package:" + getPackageName()));
35 | startActivityForResult(intent, SYSTEM_ALERT_WINDOW_PERMISSION);
36 | }
37 |
38 |
39 | @Override
40 | public void onClick(View v) {
41 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
42 | startService(new Intent(MainActivity.this, FloatingView.class));
43 | finish();
44 | } else if (Settings.canDrawOverlays(this)) {
45 | startService(new Intent(MainActivity.this, FloatingView.class));
46 | finish();
47 | } else {
48 | askPermission();
49 | Toast.makeText(this, "You need System Alert Window Permission to do this", Toast.LENGTH_SHORT).show();
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
19 |
20 |
--------------------------------------------------------------------------------
/res/layout/floating_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
14 |
19 |
20 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/z54deng/AutoClicker/e18c3cbf5e13d792c5af014f212775aab0ccc9a1/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 | #800080
7 |
8 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ClickedApp
3 |
4 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/res/xml/global_action_bar_service.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------