├── .gitignore
├── README.md
├── abllib
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── levine
│ │ │ └── abllib
│ │ │ ├── AblConfig.java
│ │ │ ├── AblService.java
│ │ │ ├── AblStepBase.java
│ │ │ ├── AblStepHandler.java
│ │ │ ├── AblSteps.java
│ │ │ ├── FindViewCountDown.java
│ │ │ ├── callback
│ │ │ ├── AniCallBack.java
│ │ │ ├── AnisCallBack.java
│ │ │ └── GestureCallBack.java
│ │ │ └── utils
│ │ │ ├── AblUtil.java
│ │ │ └── AblViewUtil.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.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
│ │ └── xml
│ │ └── abl_service.xml
│ └── test
│ └── java
│ └── com
│ └── levine
│ └── abllib
│ └── ExampleUnitTest.java
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── luoyi
│ │ └── android
│ │ └── com
│ │ └── abldemo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── luoyi
│ │ │ └── android
│ │ │ └── com
│ │ │ └── abldemo
│ │ │ ├── MainActivity.java
│ │ │ ├── TestAblStep1.java
│ │ │ └── TestAblStep2.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ └── view_test.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
│ └── test
│ └── java
│ └── luoyi
│ └── android
│ └── com
│ └── abldemo
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── resource
├── 20230303100049.jpg
├── 20230303103749.jpg
└── 微信图片_20230403143012.jpg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 |
19 | # Local configuration file (sdk path, etc)
20 | local.properties
21 |
22 | # Proguard folder generated by Eclipse
23 | proguard/
24 |
25 |
26 | # Android Studio project files
27 | *.iml
28 | .gradle
29 | .idea
30 | build
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Abllib (此开源库已不再维护,已重新开发更加易用稳定的库[Assists](https://github.com/ven-coder/assists))
2 |
3 | [Demo:https://github.com/Levine1992/Abllib](https://github.com/Levine1992/Abllib)
4 |
5 | **AccessibilityService无障碍服务库,一行代码启用,快速开发复杂的自动操作业务**
6 |
7 | **AccessibilityService可以帮助我们做一些自动操作手机的动作,像微信自动抢红包、各种应用市场的自动安装功能就是利用的AccessibilityService服务,
8 | 利用这个服务我们可以做更多有意思的事,但是直接继承这个服务,要实现一些复杂点的业务逻辑就很麻烦,所以写了这个库。**
9 |
10 | ### 引用
11 | project build.gradle中添加
12 |
13 | ```
14 | allprojects {
15 | repositories {
16 | ...
17 | maven { url 'https://jitpack.io' }
18 | }
19 | }
20 | ```
21 | app build.gradle中添加
22 |
23 | ```
24 | dependencies {
25 | ...
26 | implementation 'com.github.Levine1992:Abllib:V1.0'
27 | }
28 | ```
29 |
30 | ### 初始化一些配置
31 |
32 | ```
33 | AblConfig.Builder()
34 | .setLogTag("123456")//logtag,不设置默认是abllib
35 | .setStepMsgDelayMillis(2000)//步骤延迟时间
36 | .setFindViewMillisInFuture(10000)//寻找界面超时时间
37 | .setFindViewCountDownInterval(200)//寻找界面间隔时间
38 | .build().init();
39 | ```
40 | ### 使用说明
41 | 新建具体的自动操作的步骤器继承AblStepBase,如果自动操作业务多可以分开多建几个,区分开便于维护,但是步骤的id最好不要重复
42 |
43 | ```
44 | public class TestAblStep1 extends AblStepBase {
45 | @Override
46 | public void onStep(int step, Message msg) {
47 | switch (step) {
48 | case AblSteps.STEP_1://步骤1
49 | AblViewUtil.findById(
50 | "luoyi.android.com.abldemo:id/btn_3",//传入需要获取抓取的界面的id
51 | 0,//由于抓到的界面有可能有多个所以传入要获取第几个,一般0就可以
52 | new AniCallBack() {//回调
53 | @Override
54 | public void succ(AccessibilityNodeInfo info) {
55 | info.performAction(AccessibilityNodeInfo.ACTION_CLICK);//抓到后执行点击界面操作
56 | AblStepHandler.sendMsg(AblSteps.STEP_2);//执行步骤2
57 | }
58 |
59 | @Override
60 | public void fail() {//处理抓取失败逻辑
61 |
62 | }
63 | }
64 | );
65 | break;
66 | case AblSteps.STEP_2://步骤2
67 | AblViewUtil.back();//返回
68 | AblStepHandler.sendMsg(AblSteps.STEP_1);
69 | break;
70 | }
71 | }
72 | ```
73 |
74 | ```
75 | public class TestAblStep2 extends AblStepBase {
76 | @Override
77 | public void onStep(int step, Message msg) {
78 | switch (step) {
79 | case AblSteps.STEP_3://步骤3
80 |
81 | break;
82 | case AblSteps.STEP_4://步骤4
83 |
84 | break;
85 | }
86 | }
87 | ```
88 |
89 |
90 | 初始化这些步骤器
91 |
92 | ```
93 | AblStepHandler.getInstance().initStepClass(new TestAblStep1(),new TestAblStep2());
94 | ```
95 |
96 | 执行
97 |
98 | ```
99 | AblStepHandler.getInstance().setStop(false);//开启步骤器
100 | AblStepHandler.sendMsg(AblSteps.STEP_1);//执行步骤,如果设置步骤间隔时间为2000,则会延迟两秒执行
101 | ```
102 |
103 | ***
104 |
105 | **AccessibilityService技术交流群**
106 |
107 |
108 | 如果群二维码失效可直接加我**Wechat:1483232332**拉进群
109 |
110 |
--------------------------------------------------------------------------------
/abllib/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 |
19 | # Local configuration file (sdk path, etc)
20 | local.properties
21 |
22 | # Proguard folder generated by Eclipse
23 | proguard/
24 |
25 |
26 | # Android Studio project files
27 | *.iml
28 | .gradle
29 | .idea
30 | build
--------------------------------------------------------------------------------
/abllib/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | minSdkVersion 20
7 | targetSdkVersion 28
8 | }
9 | compileOptions {
10 | sourceCompatibility = '1.8'
11 | targetCompatibility = '1.8'
12 | }
13 | }
14 |
15 | dependencies {
16 | implementation 'com.android.support:appcompat-v7:28.0.0'
17 | api 'com.blankj:utilcode:1.23.7'
18 | }
19 |
--------------------------------------------------------------------------------
/abllib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/abllib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/AblConfig.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib;
2 |
3 | import com.blankj.utilcode.util.LogUtils;
4 |
5 | /**
6 | * 2019/4/21
7 | * 17:49
8 | * Levine
9 | * wechat 1483232332
10 | */
11 | public class AblConfig {
12 |
13 | private String mLogTag;
14 | private boolean mIsLog;
15 | private long mStepMsgDelayMillis;//消息延迟发送时间
16 | private long findViewMillisInFuture;//查找view倒计时总时长
17 | private long findViewCountDownInterval;//查找view检查间隔时间
18 | /**
19 | * 所监测的APP包名,如果不设置将会监听整个系统的界面变化,如果设置后只会监听指定包名的APP
20 | * 【暂时不用】
21 | */
22 | public static String[] sMonitoringPackageNames;
23 |
24 | private AblConfig(Builder builder) {
25 | mLogTag = builder.mLogTag;
26 | mIsLog = builder.mIsLog;
27 | sMonitoringPackageNames = builder.mMonitoringPackageNames;
28 | mStepMsgDelayMillis = builder.mStepMsgDelayMillis;
29 | findViewCountDownInterval = builder.findViewCountDownInterval;
30 | findViewMillisInFuture = builder.findViewMillisInFuture;
31 | }
32 |
33 | public void init() {
34 | LogUtils.getConfig().setGlobalTag(mLogTag);
35 | LogUtils.getConfig().setLogSwitch(mIsLog);
36 | AblStepHandler.getInstance().setStepMsgDelayMillis(mStepMsgDelayMillis);
37 | FindViewCountDown.countDownInterval = findViewCountDownInterval;
38 | FindViewCountDown.millisInFuture = findViewMillisInFuture;
39 | }
40 |
41 | public static Builder Builder() {
42 | return new Builder();
43 | }
44 |
45 | public static class Builder {
46 | private String mLogTag = "abllib";
47 | private boolean mIsLog = true;
48 | private String[] mMonitoringPackageNames;
49 | private long mStepMsgDelayMillis = 2000;//步骤延迟发送时间
50 | private long findViewMillisInFuture = 10000;//查找view倒计时总时长
51 | private long findViewCountDownInterval = 500;//查找view检查间隔时间
52 |
53 | public Builder setLogTag(String logTag) {
54 | mLogTag = logTag;
55 | return this;
56 | }
57 |
58 | public Builder setLog(boolean log) {
59 | mIsLog = log;
60 | return this;
61 | }
62 |
63 | public Builder setMonitoringPackageNames(String... monitoringPackageNames) {
64 | mMonitoringPackageNames = monitoringPackageNames;
65 | return this;
66 | }
67 |
68 | public Builder setStepMsgDelayMillis(long stepMsgDelayMillis) {
69 | mStepMsgDelayMillis = stepMsgDelayMillis;
70 | return this;
71 | }
72 |
73 | public Builder setFindViewMillisInFuture(long findViewMillisInFuture) {
74 | this.findViewMillisInFuture = findViewMillisInFuture;
75 | return this;
76 | }
77 |
78 | public Builder setFindViewCountDownInterval(long findViewCountDownInterval) {
79 | this.findViewCountDownInterval = findViewCountDownInterval;
80 | return this;
81 | }
82 |
83 | public AblConfig build() {
84 | return new AblConfig(this);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/AblService.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib;
2 |
3 | import android.accessibilityservice.AccessibilityService;
4 | import android.accessibilityservice.AccessibilityServiceInfo;
5 | import android.view.accessibility.AccessibilityEvent;
6 |
7 | import com.blankj.utilcode.util.LogUtils;
8 |
9 | /**
10 | * 2019/4/21
11 | * 11:29
12 | * Levine
13 | * wechat 1483232332
14 | */
15 | public class AblService extends AccessibilityService {
16 |
17 | private static AblService mAblService;
18 |
19 | public static AblService getInstance() {
20 | if (mAblService == null) {
21 | throw new NullPointerException("AblService辅助服务未开启");
22 | }
23 | return mAblService;
24 | }
25 |
26 | @Override
27 | public void onCreate() {
28 | super.onCreate();
29 | mAblService = this;
30 | init();
31 | }
32 |
33 | private void init() {
34 |
35 | }
36 |
37 | @Override
38 | protected boolean onGesture(int gestureId) {
39 | return super.onGesture(gestureId);
40 | }
41 |
42 |
43 | @Override
44 | protected void onServiceConnected() {
45 | super.onServiceConnected();
46 | LogUtils.v("onServiceConnected");
47 | AccessibilityServiceInfo config = new AccessibilityServiceInfo();
48 | //配置监听的事件类型为界面变化|点击事件
49 | config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED | AccessibilityEvent.TYPE_VIEW_CLICKED;
50 | config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
51 | config.flags = AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY;
52 | setServiceInfo(config);
53 | }
54 |
55 | @Override
56 | public void onAccessibilityEvent(AccessibilityEvent event) {
57 | // LogUtils.v(event.getPackageName() + "");
58 | }
59 |
60 | @Override
61 | public void onInterrupt() {
62 |
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/AblStepBase.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib;
2 |
3 | /**
4 | * 2019/4/21
5 | * 16:44
6 | * Levine
7 | * wechat 1483232332
8 | */
9 | public abstract class AblStepBase implements AblStepHandler.StepListener {
10 | }
11 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/AblStepHandler.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib;
2 |
3 |
4 | import android.os.Handler;
5 | import android.os.Looper;
6 | import android.os.Message;
7 | import android.support.annotation.NonNull;
8 |
9 | import com.blankj.utilcode.util.LogUtils;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | /**
15 | * 2019/4/21
16 | * 14:36
17 | * Levine
18 | * wechat 1483232332
19 | */
20 | public class AblStepHandler extends Handler {
21 |
22 | private static AblStepHandler instance;
23 | private List mStepListeners = new ArrayList<>();
24 | private boolean isStop = true;//是否停止
25 | private String[] mDatas;//数据
26 | private long mStepMsgDelayMillis = 2000;//消息延迟发送时间
27 | private List mInitializedSteps = new ArrayList<>();//已经初始化过的步骤
28 |
29 | private AblStepHandler() {
30 | super(Looper.getMainLooper());
31 | }
32 |
33 | public static AblStepHandler getInstance() {
34 | if (instance == null) {
35 | synchronized (AblStepHandler.class) {
36 | if (instance == null) {
37 | instance = new AblStepHandler();
38 | }
39 | }
40 | }
41 | return instance;
42 | }
43 |
44 | /**
45 | * 发送handler执行消息
46 | *
47 | * @param step 步骤
48 | * @param delayMillis 延迟时间
49 | * @param datas 数据
50 | */
51 | public static void sendMsg(int step, long delayMillis, String... datas) {
52 | AblStepHandler ablStepHandler = AblStepHandler.getInstance();
53 | if (datas != null && datas.length > 0) {
54 | ablStepHandler.setDatas(datas);
55 | }
56 | ablStepHandler.sendEmptyMessageDelayed(step, delayMillis);
57 | }
58 |
59 | /**
60 | * 发送handler执行消息
61 | *
62 | * @param step 步骤
63 | * @param delayMillis 延迟时间
64 | */
65 | public static void sendMsg(int step, long delayMillis) {
66 | sendMsg(step, delayMillis, new String[]{});
67 | }
68 |
69 | /**
70 | * 发送handler执行消息
71 | *
72 | * @param step 步骤
73 | * @param datas 数据
74 | */
75 | public static void sendMsg(int step, String... datas) {
76 | sendMsg(step, AblStepHandler.getInstance().getStepMsgDelayMillis(), datas);
77 | }
78 |
79 | /**
80 | * 发送handler执行消息
81 | *
82 | * @param step 步骤
83 | */
84 | public static void sendMsg(int step) {
85 | sendMsg(step, AblStepHandler.getInstance().getStepMsgDelayMillis(), new String[]{});
86 | }
87 |
88 | /**
89 | * 根据viewid或文字发送执行消息
90 | *
91 | * @param millisInFuture view查找超时时间
92 | * @param countDownInterval 查找间隔时间
93 | * @param step 步骤
94 | */
95 | public static void sendMsgByView(
96 | long millisInFuture,
97 | long countDownInterval,
98 | int step,
99 | String... nextMsgViewIdOrText
100 | ) {
101 | FindViewCountDown.start(millisInFuture, countDownInterval, step, nextMsgViewIdOrText);
102 | }
103 |
104 | /**
105 | * 根据viewid或文字发送执行消息
106 | *
107 | * @param millisInFuture view查找超时时间
108 | * @param countDownInterval 查找间隔时间
109 | * @param callBack 回调,注:如果回调不为空将不发送消息,要发送消息就自己在成功的回调里发送
110 | * @param viewIdOrText viewid或者文字内容
111 | */
112 | public static void sendMsgByView(
113 | long millisInFuture,
114 | long countDownInterval,
115 | @NonNull FindViewCountDown.CallBack callBack,
116 | String... viewIdOrText
117 | ) {
118 | FindViewCountDown.start(millisInFuture, countDownInterval, callBack, viewIdOrText);
119 | }
120 |
121 | /**
122 | * 根据viewid或文字发送执行消息
123 | *
124 | * @param step 步骤
125 | * @param viewIdOrText viewid或者文字内容
126 | */
127 | public static void sendMsgByView(
128 | int step,
129 | String... viewIdOrText
130 | ) {
131 | FindViewCountDown.start(step, viewIdOrText);
132 | }
133 |
134 | /**
135 | * 根据viewid或文字发送执行消息
136 | *
137 | * @param callBack 回调,注:如果回调不为空将不发送消息,要发送消息就自己在成功的回调里发送
138 | * @param viewIdOrText viewid或者文字内容
139 | */
140 | public static void sendMsgByView(
141 | @NonNull FindViewCountDown.CallBack callBack,
142 | String... viewIdOrText
143 | ) {
144 | FindViewCountDown.start(callBack, viewIdOrText);
145 | }
146 |
147 |
148 | public String[] getDatas() {
149 | return mDatas;
150 | }
151 |
152 | public void setDatas(String... datas) {
153 | mDatas = datas;
154 | }
155 |
156 | public long getStepMsgDelayMillis() {
157 | return mStepMsgDelayMillis;
158 | }
159 |
160 | public void setStepMsgDelayMillis(long msgDelayMillis) {
161 | mStepMsgDelayMillis = msgDelayMillis;
162 | }
163 |
164 | public boolean isStop() {
165 |
166 | return isStop;
167 | }
168 |
169 | public void setStop(boolean stop) {
170 | isStop = stop;
171 | }
172 |
173 | @Override
174 | public void handleMessage(Message msg) {
175 | super.handleMessage(msg);
176 | if (isStop) return;
177 | LogUtils.v("step", msg.what);
178 | for (StepListener stepListener : mStepListeners) {
179 | stepListener.onStep(msg.what, msg);
180 | }
181 | }
182 |
183 | private void addStepListener(StepListener handleMessageListener) {
184 | mStepListeners.add(handleMessageListener);
185 | }
186 |
187 | public void removeStepListener(StepListener handleMessageListener) {
188 | mStepListeners.remove(handleMessageListener);
189 | }
190 |
191 | /**
192 | * 初始化步骤实现类
193 | *
194 | * @param ablStepBases 继承了StepBase的实现类
195 | */
196 | public void initStepClass(AblStepBase... ablStepBases) {
197 | for (AblStepBase ablStepBase : ablStepBases) {
198 | if (mInitializedSteps.contains(ablStepBase.getClass().getName())) {
199 | LogUtils.e(ablStepBase.getClass().getName() + "已经初始化,请勿重复初始化");
200 | continue;
201 | }
202 | addStepListener(ablStepBase);
203 | mInitializedSteps.add(ablStepBase.getClass().getName());
204 | }
205 | }
206 |
207 | public interface StepListener {
208 | void onStep(int step, Message msg);
209 | }
210 |
211 | }
212 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/AblSteps.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib;
2 |
3 | /**
4 | * 2019/4/21
5 | * 18:33
6 | * Levine
7 | * wechat 1483232332
8 | */
9 | public class AblSteps {
10 | /**
11 | * 全局静态常量步骤标识1~200,不够自己再加,从200开始加,基本应该都是够的了
12 | */
13 | public final static int STEP_1 = 1;
14 | public final static int STEP_2 = 2;
15 | public final static int STEP_3 = 3;
16 | public final static int STEP_4 = 4;
17 | public final static int STEP_5 = 5;
18 | public final static int STEP_6 = 6;
19 | public final static int STEP_7 = 7;
20 | public final static int STEP_8 = 8;
21 | public final static int STEP_9 = 9;
22 | /*****************************************/
23 | public final static int STEP_10 = 10;
24 | public final static int STEP_11 = 11;
25 | public final static int STEP_12 = 12;
26 | public final static int STEP_13 = 13;
27 | public final static int STEP_14 = 14;
28 | public final static int STEP_15 = 15;
29 | public final static int STEP_16 = 16;
30 | public final static int STEP_17 = 17;
31 | public final static int STEP_18 = 18;
32 | public final static int STEP_19 = 19;
33 | /*****************************************/
34 | public final static int STEP_20 = 20;
35 | public final static int STEP_21 = 21;
36 | public final static int STEP_22 = 22;
37 | public final static int STEP_23 = 23;
38 | public final static int STEP_24 = 24;
39 | public final static int STEP_25 = 25;
40 | public final static int STEP_26 = 26;
41 | public final static int STEP_27 = 27;
42 | public final static int STEP_28 = 28;
43 | public final static int STEP_29 = 29;
44 | /*****************************************/
45 | public final static int STEP_30 = 30;
46 | public final static int STEP_31 = 31;
47 | public final static int STEP_32 = 32;
48 | public final static int STEP_33 = 33;
49 | public final static int STEP_34 = 34;
50 | public final static int STEP_35 = 35;
51 | public final static int STEP_36 = 36;
52 | public final static int STEP_37 = 37;
53 | public final static int STEP_38 = 38;
54 | public final static int STEP_39 = 39;
55 | /*****************************************/
56 | public final static int STEP_40 = 40;
57 | public final static int STEP_41 = 41;
58 | public final static int STEP_42 = 42;
59 | public final static int STEP_43 = 43;
60 | public final static int STEP_44 = 44;
61 | public final static int STEP_45 = 45;
62 | public final static int STEP_46 = 46;
63 | public final static int STEP_47 = 47;
64 | public final static int STEP_48 = 48;
65 | public final static int STEP_49 = 49;
66 | /*****************************************/
67 | public final static int STEP_50 = 50;
68 | public final static int STEP_51 = 51;
69 | public final static int STEP_52 = 52;
70 | public final static int STEP_53 = 53;
71 | public final static int STEP_54 = 54;
72 | public final static int STEP_55 = 55;
73 | public final static int STEP_56 = 56;
74 | public final static int STEP_57 = 57;
75 | public final static int STEP_58 = 58;
76 | public final static int STEP_59 = 59;
77 | /*****************************************/
78 | public final static int STEP_60 = 60;
79 | public final static int STEP_61 = 61;
80 | public final static int STEP_62 = 62;
81 | public final static int STEP_63 = 63;
82 | public final static int STEP_64 = 64;
83 | public final static int STEP_65 = 65;
84 | public final static int STEP_66 = 66;
85 | public final static int STEP_67 = 67;
86 | public final static int STEP_68 = 68;
87 | public final static int STEP_69 = 69;
88 | /*****************************************/
89 | public final static int STEP_70 = 70;
90 | public final static int STEP_71 = 71;
91 | public final static int STEP_72 = 72;
92 | public final static int STEP_73 = 73;
93 | public final static int STEP_74 = 74;
94 | public final static int STEP_75 = 75;
95 | public final static int STEP_76 = 76;
96 | public final static int STEP_77 = 77;
97 | public final static int STEP_78 = 78;
98 | public final static int STEP_79 = 79;
99 | /*****************************************/
100 | public final static int STEP_80 = 80;
101 | public final static int STEP_81 = 81;
102 | public final static int STEP_82 = 82;
103 | public final static int STEP_83 = 83;
104 | public final static int STEP_84 = 84;
105 | public final static int STEP_85 = 85;
106 | public final static int STEP_86 = 86;
107 | public final static int STEP_87 = 87;
108 | public final static int STEP_88 = 88;
109 | public final static int STEP_89 = 89;
110 | /*****************************************/
111 | public final static int STEP_90 = 90;
112 | public final static int STEP_91 = 91;
113 | public final static int STEP_92 = 92;
114 | public final static int STEP_93 = 93;
115 | public final static int STEP_94 = 94;
116 | public final static int STEP_95 = 95;
117 | public final static int STEP_96 = 96;
118 | public final static int STEP_97 = 97;
119 | public final static int STEP_98 = 98;
120 | public final static int STEP_99 = 99;
121 | /*****************************************/
122 | public final static int STEP_100 = 100;
123 | public final static int STEP_101 = 101;
124 | public final static int STEP_102 = 102;
125 | public final static int STEP_103 = 103;
126 | public final static int STEP_104 = 104;
127 | public final static int STEP_105 = 105;
128 | public final static int STEP_106 = 106;
129 | public final static int STEP_107 = 107;
130 | public final static int STEP_108 = 108;
131 | public final static int STEP_109 = 109;
132 | /*****************************************/
133 | public final static int STEP_110 = 110;
134 | public final static int STEP_111 = 111;
135 | public final static int STEP_112 = 112;
136 | public final static int STEP_113 = 113;
137 | public final static int STEP_114 = 114;
138 | public final static int STEP_115 = 115;
139 | public final static int STEP_116 = 116;
140 | public final static int STEP_117 = 117;
141 | public final static int STEP_118 = 118;
142 | public final static int STEP_119 = 119;
143 | /*****************************************/
144 | public final static int STEP_120 = 120;
145 | public final static int STEP_121 = 121;
146 | public final static int STEP_122 = 122;
147 | public final static int STEP_123 = 123;
148 | public final static int STEP_124 = 124;
149 | public final static int STEP_125 = 125;
150 | public final static int STEP_126 = 126;
151 | public final static int STEP_127 = 127;
152 | public final static int STEP_128 = 128;
153 | public final static int STEP_129 = 129;
154 | /*****************************************/
155 | public final static int STEP_130 = 130;
156 | public final static int STEP_131 = 131;
157 | public final static int STEP_132 = 132;
158 | public final static int STEP_133 = 133;
159 | public final static int STEP_134 = 134;
160 | public final static int STEP_135 = 135;
161 | public final static int STEP_136 = 136;
162 | public final static int STEP_137 = 137;
163 | public final static int STEP_138 = 138;
164 | public final static int STEP_139 = 139;
165 | /*****************************************/
166 | public final static int STEP_140 = 140;
167 | public final static int STEP_141 = 141;
168 | public final static int STEP_142 = 142;
169 | public final static int STEP_143 = 143;
170 | public final static int STEP_144 = 144;
171 | public final static int STEP_145 = 145;
172 | public final static int STEP_146 = 146;
173 | public final static int STEP_147 = 147;
174 | public final static int STEP_148 = 148;
175 | public final static int STEP_149 = 149;
176 | /*****************************************/
177 | public final static int STEP_150 = 150;
178 | public final static int STEP_151 = 151;
179 | public final static int STEP_152 = 152;
180 | public final static int STEP_153 = 153;
181 | public final static int STEP_154 = 154;
182 | public final static int STEP_155 = 155;
183 | public final static int STEP_156 = 156;
184 | public final static int STEP_157 = 157;
185 | public final static int STEP_158 = 158;
186 | public final static int STEP_159 = 159;
187 | /*****************************************/
188 | public final static int STEP_160 = 160;
189 | public final static int STEP_161 = 161;
190 | public final static int STEP_162 = 162;
191 | public final static int STEP_163 = 163;
192 | public final static int STEP_164 = 164;
193 | public final static int STEP_165 = 165;
194 | public final static int STEP_166 = 166;
195 | public final static int STEP_167 = 167;
196 | public final static int STEP_168 = 168;
197 | public final static int STEP_169 = 169;
198 | /*****************************************/
199 | public final static int STEP_170 = 170;
200 | public final static int STEP_171 = 171;
201 | public final static int STEP_172 = 172;
202 | public final static int STEP_173 = 173;
203 | public final static int STEP_174 = 174;
204 | public final static int STEP_175 = 175;
205 | public final static int STEP_176 = 176;
206 | public final static int STEP_177 = 177;
207 | public final static int STEP_178 = 178;
208 | public final static int STEP_179 = 179;
209 | /*****************************************/
210 | public final static int STEP_180 = 180;
211 | public final static int STEP_181 = 181;
212 | public final static int STEP_182 = 182;
213 | public final static int STEP_183 = 183;
214 | public final static int STEP_184 = 184;
215 | public final static int STEP_185 = 185;
216 | public final static int STEP_186 = 186;
217 | public final static int STEP_187 = 187;
218 | public final static int STEP_188 = 188;
219 | public final static int STEP_189 = 189;
220 | /*****************************************/
221 | public final static int STEP_190 = 190;
222 | public final static int STEP_191 = 191;
223 | public final static int STEP_192 = 192;
224 | public final static int STEP_193 = 193;
225 | public final static int STEP_194 = 194;
226 | public final static int STEP_195 = 195;
227 | public final static int STEP_196 = 196;
228 | public final static int STEP_197 = 197;
229 | public final static int STEP_198 = 198;
230 | public final static int STEP_199 = 199;
231 | public final static int STEP_200 = 200;
232 | }
233 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/FindViewCountDown.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib;
2 |
3 | import android.os.CountDownTimer;
4 | import android.support.annotation.NonNull;
5 | import android.view.accessibility.AccessibilityNodeInfo;
6 |
7 | import com.levine.abllib.utils.AblViewUtil;
8 |
9 | /**
10 | * 寻找界面倒计时
11 | * 2019/4/21
12 | * 15:21
13 | * Levine
14 | * wechat 1483232332
15 | */
16 | public class FindViewCountDown {
17 |
18 | private static DownTimer mDownTimer;
19 | public static long millisInFuture = 10000;//默认倒计时总时长
20 | public static long countDownInterval = 500;//间隔时间
21 |
22 | private static class DownTimer extends CountDownTimer {
23 |
24 | private String[] mMsgViewIdOrText;
25 | private int mStep;
26 | private CallBack mCallback;
27 |
28 | public DownTimer(
29 | long millisInFuture,
30 | long countDownInterval,
31 | int step, CallBack callback,
32 | String... viewIdOrText
33 | ) {
34 | super(millisInFuture, countDownInterval);
35 | mMsgViewIdOrText = viewIdOrText.clone();
36 | mStep = step;
37 | mCallback = callback;
38 | }
39 |
40 | @Override
41 | public void onTick(long l) {
42 | if (AblStepHandler.getInstance().isStop()) {
43 | cancel();
44 | return;
45 | }
46 | for (String string : mMsgViewIdOrText) {
47 | AccessibilityNodeInfo fromId = AblViewUtil.findById(string, 0);
48 | AccessibilityNodeInfo fromText = AblViewUtil.findByText(string, 0);
49 | if (fromId != null || fromText != null) {
50 | cancel();
51 | if (mCallback != null) {
52 | mCallback.succ();
53 | } else {
54 | AblStepHandler.sendMsg(mStep);
55 | }
56 | return;
57 | }
58 | }
59 | }
60 |
61 | @Override
62 | public void onFinish() {
63 | if (mCallback != null) mCallback.fail();
64 | }
65 | }
66 |
67 | public interface CallBack {
68 | void succ();
69 |
70 | default void fail() {
71 | }
72 | }
73 |
74 | /**
75 | * 根据viewid或文字发送执行消息
76 | *
77 | * @param millisInFuture view查找超时时间
78 | * @param countDownInterval 查找间隔时间
79 | * @param step 步骤
80 | * @param viewIdOrText viewid或者文字内容
81 | */
82 | public static void start(
83 | long millisInFuture,
84 | long countDownInterval,
85 | int step,
86 | String... viewIdOrText
87 | ) {
88 | start(millisInFuture, countDownInterval, step, null, viewIdOrText);
89 | }
90 |
91 | /**
92 | * 根据viewid或文字发送执行消息
93 | *
94 | * @param millisInFuture view查找超时时间
95 | * @param countDownInterval 查找间隔时间
96 | * @param callBack 回调,注:如果回调不为空将不发送消息,要发送消息就自己在成功的回调里发送
97 | * @param viewIdOrText viewid或者文字内容
98 | */
99 | public static void start(
100 | long millisInFuture,
101 | long countDownInterval,
102 | @NonNull CallBack callBack,
103 | String... viewIdOrText
104 | ) {
105 | start(millisInFuture, countDownInterval, 0, callBack, viewIdOrText);
106 | }
107 |
108 | /**
109 | * 根据viewid或文字发送执行消息
110 | *
111 | * @param callBack 回调,注:如果回调不为空将不发送消息,要发送消息就自己在成功的回调里发送
112 | * @param viewIdOrText viewid或者文字内容
113 | */
114 | public static void start(
115 | @NonNull CallBack callBack,
116 | String... viewIdOrText
117 | ) {
118 | start(millisInFuture, countDownInterval, 0, callBack, viewIdOrText);
119 | }
120 |
121 | /**
122 | * 根据viewid或文字发送执行消息
123 | *
124 | * @param step 步骤
125 | * @param viewIdOrText viewid或者文字内容
126 | */
127 | public static void start(
128 | int step,
129 | String... viewIdOrText
130 | ) {
131 | start(millisInFuture, countDownInterval, step, null, viewIdOrText);
132 | }
133 |
134 | /**
135 | * 根据viewid或文字发送执行消息
136 | *
137 | * @param millisInFuture view查找超时时间
138 | * @param countDownInterval 查找间隔时间
139 | * @param step 步骤
140 | * @param callBack 回调,注:如果回调不为空将不发送消息,要发送消息就自己在成功的回调里发送
141 | * @param viewIdOrText viewid或者文字内容
142 | */
143 | private static void start(
144 | long millisInFuture,
145 | long countDownInterval,
146 | int step,
147 | CallBack callBack,
148 | String... viewIdOrText
149 | ) {
150 | if (mDownTimer != null) mDownTimer.cancel();
151 | mDownTimer = new DownTimer(millisInFuture, countDownInterval, step, callBack, viewIdOrText);
152 | mDownTimer.start();
153 | }
154 |
155 | public static DownTimer getDownTimer() {
156 | return mDownTimer;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/callback/AniCallBack.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib.callback;
2 |
3 | import android.view.accessibility.AccessibilityNodeInfo;
4 |
5 | /**
6 | * 2019/4/21
7 | * 13:05
8 | * Levine
9 | * wechat 1483232332
10 | */
11 | public interface AniCallBack {
12 | void succ(AccessibilityNodeInfo info);
13 |
14 | default void fail() {
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/callback/AnisCallBack.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib.callback;
2 |
3 | import android.view.accessibility.AccessibilityNodeInfo;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 2019/4/21
9 | * 13:04
10 | * Levine
11 | * wechat 1483232332
12 | */
13 | public interface AnisCallBack {
14 | void succ(List infos);
15 |
16 | default void fail() {
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/callback/GestureCallBack.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib.callback;
2 |
3 | import android.accessibilityservice.GestureDescription;
4 |
5 | /**
6 | * 2019/4/21
7 | * 13:20
8 | * Levine
9 | * wechat 1483232332
10 | */
11 | public interface GestureCallBack {
12 | void succ(GestureDescription gestureDescription);
13 |
14 | void fail(GestureDescription gestureDescription);
15 | }
16 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/utils/AblUtil.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib.utils;
2 |
3 | import android.app.ActivityManager;
4 | import android.app.AppOpsManager;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.graphics.PixelFormat;
8 | import android.net.Uri;
9 | import android.os.Binder;
10 | import android.os.Build;
11 | import android.provider.Settings;
12 | import android.view.Gravity;
13 | import android.view.View;
14 | import android.view.ViewGroup;
15 | import android.view.WindowManager;
16 |
17 | import com.blankj.utilcode.util.LogUtils;
18 | import com.blankj.utilcode.util.ToastUtils;
19 | import com.levine.abllib.AblConfig;
20 | import com.levine.abllib.AblService;
21 |
22 | import java.lang.reflect.Field;
23 | import java.lang.reflect.Method;
24 | import java.util.List;
25 |
26 | import static com.blankj.utilcode.util.ActivityUtils.startActivity;
27 |
28 | /**
29 | * 2019/4/21
30 | * 18:21
31 | * Levine
32 | * wechat 1483232332
33 | */
34 | public class AblUtil {
35 |
36 | /***
37 | * 检查悬浮窗开启权限
38 | * @param context
39 | * @return
40 | */
41 | public static boolean checkFloatPermission(Context context) {
42 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
43 | return true;
44 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
45 | try {
46 | Class cls = Class.forName("android.content.Context");
47 | Field declaredField = cls.getDeclaredField("APP_OPS_SERVICE");
48 | declaredField.setAccessible(true);
49 | Object obj = declaredField.get(cls);
50 | if (!(obj instanceof String)) {
51 | return false;
52 | }
53 | String str2 = (String) obj;
54 | obj = cls.getMethod("getSystemService", String.class).invoke(context, str2);
55 | cls = Class.forName("android.app.AppOpsManager");
56 | Field declaredField2 = cls.getDeclaredField("MODE_ALLOWED");
57 | declaredField2.setAccessible(true);
58 | Method checkOp = cls.getMethod("checkOp", Integer.TYPE, Integer.TYPE, String.class);
59 | int result = (Integer) checkOp.invoke(obj, 24, Binder.getCallingUid(), context.getPackageName());
60 | return result == declaredField2.getInt(cls);
61 | } catch (Exception e) {
62 | return false;
63 | }
64 | } else {
65 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
66 | AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
67 | if (appOpsMgr == null)
68 | return false;
69 | int mode = appOpsMgr.checkOpNoThrow("android:system_alert_window", android.os.Process.myUid(), context
70 | .getPackageName());
71 | return Settings.canDrawOverlays(context) || mode == AppOpsManager.MODE_ALLOWED || mode == AppOpsManager.MODE_IGNORED;
72 | } else {
73 | return Settings.canDrawOverlays(context);
74 | }
75 | }
76 | }
77 |
78 | /**
79 | * 添加悬浮界面
80 | *
81 | * @param context
82 | * @param view
83 | */
84 | public static void addSuspensionWindowView(Context context, View view) {
85 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
86 | if (Settings.canDrawOverlays(context)) {
87 | addSuspensionView(context, view);
88 | } else {
89 | ToastUtils.showShort("请先开启允许显示在其他应用上权限");
90 | }
91 | } else {
92 | addSuspensionView(context, view);
93 | }
94 | }
95 |
96 | public static void removeSuspensionWindowView(Context context, View view) {
97 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
98 | windowManager.removeView(view);
99 | }
100 |
101 | /**
102 | * 添加悬浮界面
103 | *
104 | * @param context
105 | * @param view
106 | */
107 | private static void addSuspensionView(Context context, View view) {
108 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
109 | WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
110 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
111 | layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
112 | } else {
113 | layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
114 | }
115 | layoutParams.format = PixelFormat.TRANSLUCENT;// 支持透明
116 | // layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;// 焦点
117 | layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;//窗口的宽和高
118 | layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
119 | layoutParams.x = 0;//窗口位置的偏移量
120 | layoutParams.y = 0;
121 | layoutParams.gravity = Gravity.CENTER;
122 | windowManager.addView(view, layoutParams);//添加窗口
123 | }
124 |
125 | /**
126 | * 打开悬浮窗授权界面
127 | *
128 | * @param context
129 | */
130 | public static void openDrawOverlaysAnth(Context context) {
131 | Intent intent = new Intent(
132 | Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
133 | Uri.parse("package:" + context.getPackageName())
134 | );
135 | context.startActivity(intent);
136 | }
137 |
138 | /**
139 | * 检查是否是需要监听的APP包名
140 | *
141 | * @param thisPackageName APP包名
142 | * @return
143 | */
144 | public static boolean checkPackageName(String thisPackageName) {
145 | if (AblConfig.sMonitoringPackageNames != null && AblConfig.sMonitoringPackageNames.length > 0) {
146 | for (String packageName : AblConfig.sMonitoringPackageNames) {
147 | if (packageName.contentEquals(thisPackageName)) {
148 | return true;
149 | }
150 | }
151 | return false;
152 | }
153 | return true;
154 | }
155 |
156 | /**
157 | * 打开无障碍服务设置
158 | */
159 | public static void openAccessibilitySettings() {
160 | Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
161 | startActivity(intent);
162 | }
163 |
164 | /**
165 | * 辅助服务是否开启
166 | *
167 | * @return
168 | */
169 | public static boolean isAccessibilityServiceOpen(Context context) {
170 | ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
171 | List services = am.getRunningServices(Short.MAX_VALUE);
172 | for (ActivityManager.RunningServiceInfo info : services) {
173 | LogUtils.v(info.service.getClassName());
174 | if (info.service.getClassName().equals(AblService.class.getName())) {
175 | return true;
176 | }
177 | }
178 | return false;
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/abllib/src/main/java/com/levine/abllib/utils/AblViewUtil.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib.utils;
2 |
3 | import android.accessibilityservice.AccessibilityService;
4 | import android.accessibilityservice.GestureDescription;
5 | import android.annotation.TargetApi;
6 | import android.content.ClipData;
7 | import android.content.ClipboardManager;
8 | import android.content.Context;
9 | import android.graphics.Path;
10 | import android.os.Build;
11 | import android.support.annotation.Nullable;
12 | import android.view.accessibility.AccessibilityNodeInfo;
13 |
14 | import com.blankj.utilcode.util.ScreenUtils;
15 | import com.levine.abllib.AblService;
16 | import com.levine.abllib.callback.AniCallBack;
17 | import com.levine.abllib.callback.AnisCallBack;
18 | import com.levine.abllib.callback.GestureCallBack;
19 |
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | /**
24 | * 界面操作工具类
25 | * wechat 1483232332
26 | */
27 | public class AblViewUtil {
28 |
29 | /**
30 | * 根据id获取view
31 | *
32 | * @param parent
33 | * @param id 界面id
34 | * @param position
35 | * @return
36 | */
37 | public static AccessibilityNodeInfo findById(
38 | AccessibilityNodeInfo parent,
39 | String id,
40 | int position,
41 | @Nullable AniCallBack callBack
42 | ) {
43 | if (parent != null) {
44 | List accessibilityNodeInfos =
45 | parent.findAccessibilityNodeInfosByViewId(id);
46 | if (accessibilityNodeInfos != null &&
47 | !accessibilityNodeInfos.isEmpty() &&
48 | position < accessibilityNodeInfos.size()) {
49 | if (callBack != null) {
50 | callBack.succ(accessibilityNodeInfos.get(position));
51 | }
52 | return accessibilityNodeInfos.get(position);
53 | }
54 | }
55 | if (callBack != null) {
56 | callBack.fail();
57 | }
58 | return null;
59 | }
60 |
61 | public static AccessibilityNodeInfo findById(
62 | AccessibilityNodeInfo parent,
63 | String id,
64 | int position
65 | ) {
66 | return findById(parent, id, position, null);
67 | }
68 |
69 | public static AccessibilityNodeInfo findById(String id, int position) {
70 | return findById(AblService.getInstance().getRootInActiveWindow(), id, position, null);
71 | }
72 |
73 | public static AccessibilityNodeInfo findById(String id, int position, AniCallBack callBack) {
74 | return findById(AblService.getInstance().getRootInActiveWindow(), id, position, callBack);
75 | }
76 |
77 | public static List findById(
78 | AccessibilityNodeInfo parent,
79 | String id,
80 | @Nullable AnisCallBack anisCallBack
81 | ) {
82 | if (parent != null) {
83 | List accessibilityNodeInfos =
84 | parent.findAccessibilityNodeInfosByViewId(id);
85 | if (accessibilityNodeInfos != null &&
86 | !accessibilityNodeInfos.isEmpty()) {
87 | if (anisCallBack != null) anisCallBack.succ(accessibilityNodeInfos);
88 | return accessibilityNodeInfos;
89 | }
90 | }
91 | if (anisCallBack != null) anisCallBack.fail();
92 | return new ArrayList<>();
93 | }
94 |
95 | public static List findById(
96 | AccessibilityNodeInfo parent,
97 | String id
98 | ) {
99 | return findById(parent, id, null);
100 | }
101 |
102 | public static List findById(String id) {
103 | return findById(AblService.getInstance().getRootInActiveWindow(), id, null);
104 | }
105 |
106 | public static List findById(String id, AnisCallBack anisCallBack) {
107 | return findById(AblService.getInstance().getRootInActiveWindow(), id, anisCallBack);
108 | }
109 |
110 | /**
111 | * 根据文本获取view
112 | *
113 | * @param parent
114 | * @param text
115 | * @param position
116 | * @return
117 | */
118 | public static AccessibilityNodeInfo findByText(AccessibilityNodeInfo parent, String text, int position) {
119 | if (parent != null) {
120 | List accessibilityNodeInfos =
121 | parent.findAccessibilityNodeInfosByText(text);
122 | if (accessibilityNodeInfos != null &&
123 | !accessibilityNodeInfos.isEmpty() &&
124 | position < accessibilityNodeInfos.size()) {
125 | return accessibilityNodeInfos.get(position);
126 | }
127 | }
128 | return null;
129 | }
130 |
131 | public static AccessibilityNodeInfo findByText(String text, int position) {
132 | return findByText(AblService.getInstance().getRootInActiveWindow(), text, position);
133 | }
134 |
135 | public static List findByText(AccessibilityNodeInfo parent, String text) {
136 | if (parent != null) {
137 | List accessibilityNodeInfos =
138 | parent.findAccessibilityNodeInfosByText(text);
139 | if (accessibilityNodeInfos != null &&
140 | !accessibilityNodeInfos.isEmpty()) {
141 | return accessibilityNodeInfos;
142 | }
143 | }
144 | return new ArrayList<>();
145 | }
146 |
147 | public static List findByText(String text) {
148 | return findByText(AblService.getInstance().getRootInActiveWindow(), text);
149 | }
150 |
151 | /**
152 | * 手势模拟
153 | *
154 | * @param start_position 开始位置,长度为2的数组,下标0为x轴,下标1为y轴
155 | * @param end_position
156 | * @param startTime 开始间隔时间
157 | * @param duration 持续时间
158 | * @param callback 回调
159 | */
160 | @TargetApi(Build.VERSION_CODES.N)
161 | public static void dispatch_gesture(
162 | float[] start_position,
163 | float[] end_position,
164 | long startTime,
165 | long duration,
166 | @Nullable GestureCallBack callback
167 | ) {
168 | Path path = new Path();
169 | path.moveTo(start_position[0], start_position[1]);
170 | path.lineTo(end_position[0], end_position[1]);
171 | GestureDescription.Builder builder = new GestureDescription.Builder();
172 | GestureDescription.StrokeDescription strokeDescription =
173 | new GestureDescription.StrokeDescription(path, startTime, duration);
174 | GestureDescription gestureDescription = builder.addStroke(strokeDescription).build();
175 | AblService.getInstance().dispatchGesture(gestureDescription, new AccessibilityService.GestureResultCallback() {
176 | @Override
177 | public void onCompleted(GestureDescription gestureDescription) {
178 | if (callback != null) callback.succ(gestureDescription);
179 | }
180 |
181 | @Override
182 | public void onCancelled(GestureDescription gestureDescription) {
183 | if (callback != null) callback.fail(gestureDescription);
184 | }
185 | }, null);
186 | }
187 |
188 | /**
189 | * x轴居中竖直滑动屏幕
190 | *
191 | * @param yRatio y轴份数
192 | * @param startSlideRatio y轴开始的份数
193 | * @param stopSlideRatio y轴结束的份数
194 | */
195 | public static void scrollVertical(
196 | int yRatio,
197 | int startSlideRatio,
198 | int stopSlideRatio,
199 | long startTime,
200 | long duration,
201 | @Nullable GestureCallBack callback
202 | ) {
203 | int screenHeight = ScreenUtils.getScreenHeight();
204 | int screenWidth = ScreenUtils.getScreenWidth();
205 | int start = (screenHeight / yRatio) * startSlideRatio;
206 | int stop = (screenHeight / yRatio) * stopSlideRatio;
207 | dispatch_gesture(
208 | new float[]{screenWidth >> 1, start},
209 | new float[]{screenWidth >> 1, stop},
210 | startTime,
211 | duration,
212 | callback
213 | );
214 |
215 | }
216 |
217 | /**
218 | * 竖直滑动,y轴分为20份
219 | *
220 | * @param startSlideRatio 开始份数
221 | * @param stopSlideRatio 结束份数
222 | */
223 | public static void scrollVertical(
224 | int startSlideRatio,
225 | int stopSlideRatio
226 | ) {
227 | int screenHeight = ScreenUtils.getScreenHeight();
228 | int screenWidth = ScreenUtils.getScreenWidth();
229 | int start = (screenHeight / 20) * startSlideRatio;
230 | int stop = (screenHeight / 20) * stopSlideRatio;
231 | dispatch_gesture(
232 | new float[]{screenWidth >> 1, start},
233 | new float[]{screenWidth >> 1, stop},
234 | 50,
235 | 500,
236 | null
237 | );
238 |
239 | }
240 |
241 | /**
242 | * x轴居中竖直滑动屏幕
243 | *
244 | * @param startY y轴开始位置
245 | * @param stopY y轴结束位置
246 | */
247 | public static void scrollVertical(
248 | float startY,
249 | float stopY,
250 | long startTime,
251 | long duration,
252 | @Nullable GestureCallBack callback
253 | ) {
254 | int screenWidth = ScreenUtils.getScreenWidth();
255 | dispatch_gesture(
256 | new float[]{screenWidth >> 1, startY},
257 | new float[]{screenWidth >> 1, stopY},
258 | startTime,
259 | duration,
260 | callback
261 | );
262 |
263 | }
264 |
265 |
266 | /**
267 | * y轴居中横向滑动
268 | *
269 | * @param xRatio x轴份数
270 | * @param startSlideRatio x轴开始滑动份数
271 | * @param stopSlideRatio x轴结束滑动份数
272 | * @param startTime 开始延迟时间
273 | * @param duration 滑动持续时间
274 | * @param callback 回调
275 | */
276 | public void scrollHorizontal(
277 | int xRatio,
278 | int startSlideRatio,
279 | int stopSlideRatio,
280 | long startTime,
281 | long duration,
282 | @Nullable GestureCallBack callback
283 | ) {
284 | int screenHeight = ScreenUtils.getScreenHeight();
285 | int screenWidth = ScreenUtils.getScreenWidth();
286 | int start = (screenWidth / xRatio) * startSlideRatio;
287 | int stop = (screenWidth / xRatio) * stopSlideRatio;
288 | dispatch_gesture(
289 | new float[]{start, screenHeight >> 1},
290 | new float[]{stop, screenHeight >> 1},
291 | startTime,
292 | duration,
293 | callback
294 | );
295 | }
296 |
297 | /**
298 | * y轴居中横向滑动
299 | *
300 | * @param startX x轴开始位置
301 | * @param stopX x轴结束位置
302 | * @param startTime 开始延迟时间
303 | * @param duration 滑动持续时间
304 | * @param callback 回调
305 | */
306 | public void scrollHorizontal(
307 | int startX,
308 | int stopX,
309 | long startTime,
310 | long duration,
311 | @Nullable GestureCallBack callback
312 | ) {
313 | int screenHeight = ScreenUtils.getScreenHeight();
314 | dispatch_gesture(
315 | new float[]{startX, screenHeight >> 1},
316 | new float[]{stopX, screenHeight >> 1},
317 | startTime,
318 | duration,
319 | callback
320 | );
321 | }
322 |
323 | /**
324 | * 点击屏幕
325 | *
326 | * @param ratio 屏幕长宽份数
327 | * @param xRatio 屏幕宽ratio份的比例
328 | * @param yRatio
329 | */
330 | public static void clickScreen(
331 | int ratio,
332 | int xRatio,
333 | int yRatio,
334 | @Nullable GestureCallBack callback
335 | ) {
336 | int screenHeight = ScreenUtils.getScreenHeight();
337 | int screenWidth = ScreenUtils.getScreenWidth();
338 | int y = (screenHeight / ratio) * yRatio;
339 | int x = (screenWidth / ratio) * xRatio;
340 | dispatch_gesture(
341 | new float[]{x, y},
342 | new float[]{x, y},
343 | 100,
344 | 50,
345 | callback
346 | );
347 | }
348 |
349 | /**
350 | * 点击屏幕
351 | */
352 | public static void clickScreen(
353 | int xRatio,
354 | int yRatio
355 | ) {
356 | int screenHeight = ScreenUtils.getScreenHeight();
357 | int screenWidth = ScreenUtils.getScreenWidth();
358 | int y = (screenHeight / 20) * yRatio;
359 | int x = (screenWidth / 20) * xRatio;
360 | dispatch_gesture(
361 | new float[]{x, y},
362 | new float[]{x, y},
363 | 100,
364 | 50,
365 | null
366 | );
367 | }
368 |
369 | public static void clickScreen(
370 | float x,
371 | float y
372 | ) {
373 | dispatch_gesture(
374 | new float[]{x, y},
375 | new float[]{x, y},
376 | 100,
377 | 2000,
378 | null
379 | );
380 | }
381 |
382 | public static void clickScreen(
383 | float x,
384 | float y,
385 | long duration
386 | ) {
387 | dispatch_gesture(
388 | new float[]{x, y},
389 | new float[]{x, y},
390 | 100,
391 | duration,
392 | null
393 | );
394 | }
395 |
396 | /**
397 | * 点击屏幕
398 | *
399 | * @param x x轴像素
400 | * @param y
401 | * @param startTime 开始间隔时间
402 | * @param duration 持续时间
403 | */
404 | public static void clickScreen(
405 | float x,
406 | float y,
407 | long startTime,
408 | long duration,
409 | @Nullable GestureCallBack callback
410 | ) {
411 | dispatch_gesture(
412 | new float[]{x, y},
413 | new float[]{x, y},
414 | startTime,
415 | duration,
416 | callback
417 | );
418 | }
419 |
420 | /**
421 | * 返回
422 | */
423 | public static void back() {
424 | AblService.getInstance().performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
425 | }
426 |
427 | /**
428 | * 黏贴文本至view
429 | *
430 | * @param info
431 | * @param text
432 | */
433 | public static void paste(AccessibilityNodeInfo info, String text) {
434 | ClipData clip = ClipData.newPlainText(System.currentTimeMillis() + "", text);
435 | ClipboardManager clipboardManager = (ClipboardManager) AblService.getInstance().getSystemService(Context.CLIPBOARD_SERVICE);
436 | assert clipboardManager != null;
437 | clipboardManager.setPrimaryClip(clip);
438 | ClipData abc = clipboardManager.getPrimaryClip();
439 | if (info != null) info.performAction(AccessibilityNodeInfo.ACTION_PASTE);
440 | }
441 | }
442 |
--------------------------------------------------------------------------------
/abllib/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/abllib/src/main/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 |
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/abllib/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/abllib/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/abllib/src/main/res/xml/abl_service.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/abllib/src/test/java/com/levine/abllib/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.levine.abllib;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "luoyi.android.com.abldemo"
7 | minSdkVersion 20
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 |
20 | compileOptions {
21 | sourceCompatibility = '1.8'
22 | targetCompatibility = '1.8'
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(include: ['*.jar'], dir: 'libs')
29 | implementation 'com.android.support:appcompat-v7:28.0.0'
30 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | implementation project(':abllib')
35 | // implementation 'com.github.Levine1992:Abllib:V1.0'
36 | }
37 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/luoyi/android/com/abldemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package luoyi.android.com.abldemo;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("luoyi.android.com.abldemo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/java/luoyi/android/com/abldemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package luoyi.android.com.abldemo;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.os.Bundle;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 | import android.view.WindowManager;
10 |
11 | import com.blankj.utilcode.util.ToastUtils;
12 | import com.levine.abllib.AblConfig;
13 | import com.levine.abllib.AblService;
14 | import com.levine.abllib.AblStepHandler;
15 | import com.levine.abllib.AblSteps;
16 | import com.levine.abllib.utils.AblUtil;
17 |
18 | public class MainActivity extends AppCompatActivity {
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_main);
24 | AblConfig.Builder()
25 | .setLogTag("123456")
26 | .setStepMsgDelayMillis(2000)
27 | .setFindViewCountDownInterval(200)
28 | .setFindViewMillisInFuture(10000)
29 | .build().init();
30 | AblStepHandler.getInstance().initStepClass(new TestAblStep1());
31 | findViewById(R.id.btn_1).setOnClickListener(new View.OnClickListener() {
32 | @Override
33 | public void onClick(View v) {
34 | AblUtil.openDrawOverlaysAnth(MainActivity.this);
35 | }
36 | });
37 | findViewById(R.id.btn_2).setOnClickListener(new View.OnClickListener() {
38 | @Override
39 | public void onClick(View v) {
40 | AblUtil.addSuspensionWindowView(MainActivity.this, initWindowView());
41 | }
42 | });
43 | findViewById(R.id.btn_3).setOnClickListener(new View.OnClickListener() {
44 | @Override
45 | public void onClick(View v) {
46 | AblUtil.openAccessibilitySettings();
47 | }
48 | });
49 | findViewById(R.id.btn_4).setOnClickListener(new View.OnClickListener() {
50 | @Override
51 | public void onClick(View v) {
52 | if (AblUtil.isAccessibilityServiceOpen(MainActivity.this)) {
53 | AblStepHandler.getInstance().setStop(false);
54 | AblStepHandler.sendMsg(AblSteps.STEP_1);
55 | } else {
56 | ToastUtils.showShort("请先开启辅助服务");
57 | }
58 |
59 | }
60 | });
61 | findViewById(R.id.btn_5).setOnClickListener(new View.OnClickListener() {
62 | @Override
63 | public void onClick(View v) {
64 | AblStepHandler.getInstance().setStop(true);
65 | }
66 | });
67 | findViewById(R.id.btn_6).setOnClickListener(new View.OnClickListener() {
68 | @TargetApi(Build.VERSION_CODES.N)
69 | @Override
70 | public void onClick(View v) {
71 | AblService.getInstance().disableSelf();
72 | }
73 | });
74 | }
75 |
76 | private View initWindowView() {
77 | View view = View.inflate(this, R.layout.view_test, null);
78 | view.findViewById(R.id.btn_1).setOnClickListener(new View.OnClickListener() {
79 | @Override
80 | public void onClick(View v) {
81 | if (AblUtil.isAccessibilityServiceOpen(MainActivity.this)) {
82 | AblStepHandler.getInstance().setStop(false);
83 | AblStepHandler.sendMsg(AblSteps.STEP_1);
84 | } else {
85 | ToastUtils.showShort("请先开启辅助服务");
86 | }
87 | }
88 | });
89 | view.findViewById(R.id.btn_2).setOnClickListener(new View.OnClickListener() {
90 | @Override
91 | public void onClick(View v) {
92 | AblStepHandler.getInstance().setStop(true);
93 | }
94 | });
95 | view.findViewById(R.id.btn_3).setOnClickListener(new View.OnClickListener() {
96 | @TargetApi(Build.VERSION_CODES.N)
97 | @Override
98 | public void onClick(View v) {
99 | AblService.getInstance().disableSelf();
100 | }
101 | });
102 | view.findViewById(R.id.btn_4).setOnClickListener(new View.OnClickListener() {
103 | @Override
104 | public void onClick(View v) {
105 | WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
106 | windowManager.removeView(view);
107 | }
108 | });
109 | return view;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/app/src/main/java/luoyi/android/com/abldemo/TestAblStep1.java:
--------------------------------------------------------------------------------
1 | package luoyi.android.com.abldemo;
2 |
3 | import android.os.Message;
4 | import android.view.accessibility.AccessibilityNodeInfo;
5 |
6 | import com.levine.abllib.AblStepHandler;
7 | import com.levine.abllib.AblSteps;
8 | import com.levine.abllib.utils.AblViewUtil;
9 | import com.levine.abllib.AblStepBase;
10 | import com.levine.abllib.callback.AniCallBack;
11 |
12 | /**
13 | * 2019/4/21
14 | * 17:01
15 | * Levine
16 | * wechat 1483232332
17 | */
18 | public class TestAblStep1 extends AblStepBase {
19 | @Override
20 | public void onStep(int step, Message msg) {
21 | switch (step) {
22 | case AblSteps.STEP_1:
23 | AblViewUtil.findById(
24 | "luoyi.android.com.abldemo:id/btn_3",
25 | 0,
26 | new AniCallBack() {
27 | @Override
28 | public void succ(AccessibilityNodeInfo info) {
29 | info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
30 | AblStepHandler.sendMsg(AblSteps.STEP_2);
31 | }
32 | }
33 | );
34 | break;
35 | case AblSteps.STEP_2:
36 | AblViewUtil.back();
37 | AblStepHandler.sendMsg(AblSteps.STEP_1);
38 | break;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/luoyi/android/com/abldemo/TestAblStep2.java:
--------------------------------------------------------------------------------
1 | package luoyi.android.com.abldemo;
2 |
3 | import android.os.Message;
4 |
5 | import com.levine.abllib.AblStepBase;
6 |
7 | /**
8 | * 2019/4/21
9 | * 17:01
10 | * Levine
11 | * wechat 1483232332
12 | */
13 | public class TestAblStep2 extends AblStepBase {
14 | @Override
15 | public void onStep(int step, Message msg) {
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/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 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
19 |
20 |
25 |
26 |
31 |
32 |
33 |
38 |
39 |
44 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
21 |
22 |
27 |
28 |
34 |
35 |
41 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AblDemo
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/luoyi/android/com/abldemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package luoyi.android.com.abldemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 |
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.3.2'
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 | maven { url 'https://jitpack.io' }
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Apr 21 11:07:43 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/resource/20230303100049.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/resource/20230303100049.jpg
--------------------------------------------------------------------------------
/resource/20230303103749.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/resource/20230303103749.jpg
--------------------------------------------------------------------------------
/resource/微信图片_20230403143012.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ven-coder/Abllib/2c99ecaf4835ffc1e0278bd2acdc5b7e97c18b8b/resource/微信图片_20230403143012.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':abllib'
2 |
--------------------------------------------------------------------------------