diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index 285f37a..6fa7b7b 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -1,19 +1,27 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5cae96e..5b8485e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -73,11 +73,6 @@ android:theme="@style/AppTheme"> - - - - diff --git a/app/src/main/java/com/fisherbone/fuzhu/FuzhuApplication.java b/app/src/main/java/com/fisherbone/fuzhu/FuzhuApplication.java index 91578f4..0940d61 100644 --- a/app/src/main/java/com/fisherbone/fuzhu/FuzhuApplication.java +++ b/app/src/main/java/com/fisherbone/fuzhu/FuzhuApplication.java @@ -16,6 +16,8 @@ import com.lzy.okgo.interceptor.HttpLoggingInterceptor; import com.lzy.okgo.model.HttpHeaders; import com.lzy.okgo.model.HttpParams; import com.blankj.utilcode.util.Utils; +import com.fisherbone.fuzhu.utils.LiveEventBusFix; +import com.jeremyliao.liveeventbus.LiveEventBus; import com.tencent.bugly.crashreport.CrashReport; import com.xiangxue.common.network.base.NetworkApi; @@ -74,6 +76,12 @@ public class FuzhuApplication extends Application { DeviceID.register(this); privacyPolicyAgreed = true; } + + // 修复 LiveEventBus 在 Android 12+ 上的 BroadcastReceiver 注册问题 + // 必须在 LiveEventBus 初始化之前调用 + // 注意:此修复可能无法完全解决问题,因为 LiveEventBus 在静态初始化时会崩溃 + // 如果修复失败,MainActivity 中的 try-catch 会捕获异常,应用仍可继续运行 + LiveEventBusFix.fix(this); } diff --git a/app/src/main/java/com/fisherbone/fuzhu/MainActivityy.java b/app/src/main/java/com/fisherbone/fuzhu/MainActivityy.java deleted file mode 100644 index 0b1b794..0000000 --- a/app/src/main/java/com/fisherbone/fuzhu/MainActivityy.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.fisherbone.fuzhu; - -import androidx.appcompat.app.AppCompatActivity; - -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.widget.ImageView; - -import com.xiangxue.arouter_annotation.ARouter; -import com.xiangxue.arouter_annotation.Parameter; -import com.xiangxue.arouter_api.ParameterManager; -import com.xiangxue.arouter_api.RouterManager; -import com.xiangxue.common.bean.Student; -import com.xiangxue.common.order.OrderDrawable; -import com.xiangxue.common.order.user.IUser; -import com.xiangxue.common.utils.Cons; - -@ARouter(path = "/app/MainActivityy") -public class MainActivityy extends AppCompatActivity { - - @Parameter(name = "/order/getDrawable") - OrderDrawable orderDrawable; // 公共基础库common - - @Parameter(name = "/order/getUserInfo") - IUser iUser; // 公共基础库common - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main1); - - if (BuildConfig.isRelease) { - Log.e(Cons.TAG, "当前为:集成化模式,除app可运行,其他子模块都是Android Library"); - } else { - Log.e(Cons.TAG, "当前为:组件化模式,app/order/personal子模块都可独立运行"); - } - - // 懒加载方式,跳到哪加载哪个类 - ParameterManager.getInstance().loadParameter(this); - - // app模块本来就可以直接加载其他模块的资源 personal - // 拿到 order模块的图片 在app模块展示 - int drawableId = orderDrawable.getDrawable(); - ImageView img = findViewById(R.id.img); - img.setImageResource(drawableId); - - // 我输出 order模块的Bean休息 - Log.d(Cons.TAG, "order的Bean onCreate: " + iUser.getUserInfo().toString()); - } - - public void jumpOrder(View view) { - /*Intent intent = new Intent(this, Order_MainActivity.class); - intent.putExtra("name", "derry"); - startActivity(intent);*/ - - // 使用我们自己写的路由 跳转交互 - RouterManager.getInstance() - .build("/order/Order_MainActivity") - .withString("name", "杜子腾") - .navigation(this); // 组件和组件通信 - } - - public void jumpPersonal(View view) { - // 以前是这样跳转 - /*Intent intent = new Intent(this, Personal_MainActivity.class); - intent.putExtra("name", "derry"); - startActivity(intent);*/ - - // 现在是这样跳转 目前还要写这么多代码,是不是非常累 - - // TODO 最终的成效:用户 一行代码搞定,同时还可以传递参数,同时还可以懒加载 - /*ARouter$$Group$$personal group$$personal = new ARouter$$Group$$personal(); - Map> groupMap = group$$personal.getGroupMap(); - Class myClass = groupMap.get("personal"); - - try { - ARouter$$Path$$personal path = (ARouter$$Path$$personal) myClass.newInstance(); - Map pathMap = path.getPathMap(); - RouterBean bean = pathMap.get("/personal/Personal_MainActivity"); - - if (bean != null) { - Intent intent = new Intent(this, bean.getMyClass()); - startActivity(intent); - } - - } catch (Exception e) { - e.printStackTrace(); - }*/ - - Student student = new Student("Derry大大", "男", 99); - - // 使用我们自己写的路由 跳转交互 - RouterManager.getInstance() - .build("/personal/Personal_MainActivity") - .withString("name", "史甄湘") - .withString("sex", "男") - .withInt("age", 99) - .withSerializable("student", student) - .navigation(this); - } -} diff --git a/app/src/main/java/com/fisherbone/fuzhu/abllib/AblService.java b/app/src/main/java/com/fisherbone/fuzhu/abllib/AblService.java index e934a63..018301b 100644 --- a/app/src/main/java/com/fisherbone/fuzhu/abllib/AblService.java +++ b/app/src/main/java/com/fisherbone/fuzhu/abllib/AblService.java @@ -1,586 +1,616 @@ -package com.fisherbone.fuzhu.abllib; - -import android.accessibilityservice.AccessibilityService; -import android.accessibilityservice.GestureDescription; -import android.annotation.TargetApi; -import android.content.Intent; -import android.graphics.Path; -import android.graphics.Rect; -import android.os.Build; -import android.text.TextUtils; -import android.util.Log; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; - -import androidx.annotation.RequiresApi; - -import com.blankj.utilcode.util.LogUtils; -import com.fisherbone.fuzhu.ChangLiang; -import com.fisherbone.fuzhu.FuzhuApplication; -import com.fisherbone.fuzhu.abllib.utils.AblViewUtil; -import com.fisherbone.fuzhu.db.CommentBeanData; -import com.fisherbone.fuzhu.db.dao.CommentDao; -import com.fisherbone.fuzhu.entity.SixEvent; -import com.jeremyliao.liveeventbus.LiveEventBus; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import de.greenrobot.event.EventBus; -import io.reactivex.disposables.Disposable; - -/** - * 2019/4/21 - * 11:29 - * Levine - * wechat 1483232332 - */ -public class AblService extends AccessibilityService { - - private static AblService mAblService; - private Disposable mdDisposable; - private String TAG = "commongendan"; - public String SHEBEITIPE_VILUETHREE = "3"; - - public static AblService getInstance() { - if (mAblService == null) { - throw new NullPointerException("AblService辅助服务未开启"); - } - return mAblService; - } - - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) - public void inputClickId(String clickId) { - AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); - if (nodeInfo != null) { - List list = nodeInfo.findAccessibilityNodeInfosByText(clickId); - for (AccessibilityNodeInfo item : list) { - clickcommontwo(item, clickId); - } - } - } - - - @Override - public void onCreate() { - super.onCreate(); - mAblService = this; - init(); - } - - private void init() { - Log.e("TIAOSHI", "无障碍服务初始化"); - } - - /** - * 系统成功绑定该服务时被触发,也就是当你在设置中开启相应的服务, - * 系统成功的绑定了该服务时会触发,通常我们可以在这里做一些初始化操作 - */ - @Override - protected void onServiceConnected() { - super.onServiceConnected(); - LogUtils.v("onServiceConnected"); - Log.e("TIAOSHI", "无障碍服务开启"); - LiveEventBus.get("ablservice").post("无障碍服务开启"); - } - - private ArrayList objects = new ArrayList<>(); - - @Override - public void onAccessibilityEvent(AccessibilityEvent event) { -// if("2".equals(ChangLiang.phonetype)) { -// if ("T".equals(ChangLiang.qidong)) { -// ChangLiang.qidong = "F"; -// AblViewUtil.startApplication(); -// AblViewUtil.mySleep(10); -// DianSou(); -// AblViewUtil.mySleep(3); -// AccessibilityNodeInfo findcomentt = findEditText(); -// String content = "178421572"; -// Log.e("TIAOSHI###", "获得的关键词内容" + content); -// AblViewUtil.mySleep(1); -// if ("0".equals(ChangLiang.phonetype)) { -// AblViewUtil.sayInput(content, findcomentt); -// } else { -// //华为畅享20 -// AblViewUtil.sayInput(content, findcomentt); -// } -// AblViewUtil.mySleep(3); -// DianSou(); -// AblViewUtil.mySleep(5); -// //进入直播间 -// if ("0".equals(ChangLiang.phonetype) || "1".equals(ChangLiang.phonetype)) { -// AblService.getInstance().clickPoint(705, 198, 300); -// } else { -// AblService.getInstance().clickPoint(1058, 300, 300); -// } -// AblViewUtil.mySleep(3); -// if ("0".equals(ChangLiang.phonetype)) { -// AblService.getInstance().clickPoint(100, 300, 300); -// } else { -// //华为畅享20 -// AblService.getInstance().clickPoint(200, 400, 300); -// } -// AblViewUtil.mySleep(1); -// ansy(); -// } -// } - - -// LogUtils.v(event.getPackageName() + ""); -// if (ChangLiang.gendanopen == 1) { -// scroll2PositionClick(this, "6"); -// } - - - int eventType = event.getEventType(); - - switch (eventType) { - //当通知栏发生改变的时候 - case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: - Log.w("TIAOSHI", "有弹出======11111" + "==classname=="); - break; - //当窗口状态发生改变的时候 - case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: - String classname = event.getClassName().toString(); - Log.e("TIAOSHI", "有弹出==22222" + "==classname==" + classname); - List text = event.getText(); - if (text.size() > 0) { - CharSequence charSequence = text.get(0); - String str = charSequence.toString(); - // Log.w("TIAOSHI", "有弹出==" + str + "==classname==" + classname); - String s = charSequence.toString(); - Log.e("TIAOSHI", "有弹出==55555" + s + "==classname==" + classname); - if (!TextUtils.isEmpty(s)) { - EventBus.getDefault().post(new SixEvent("success", s)); - } - if (classname.equals("android.app.AlertDialog")) { - - } else if (classname.equals("com.android.packageinstaller.permission.ui.GrantPermissionsActivity")) { - //点击安装 -// AblViewUtil.mySleep(2); -// inputClickId("始终允许"); - } else if (classname.equals("com.android.packageinstaller.PackageInstallerActivity")) { - //点击安装 - inputClickId("安装"); - } else if (classname.equals("com.android.packageinstaller.InstallAppProgress")) { - //点击打开 - AblViewUtil.mySleep(5); - inputClickId("打开"); - } else if (classname.equals("android.app.Dialog")) {//测试可以用 - if (str.contains("朋友推荐")) { - AblViewUtil.mySleep(2); - performGlobalAction(GLOBAL_ACTION_BACK); // 返回安装页面 - Log.e("TIAOSHI###", "关闭了好友推荐的弹框"); - } - } else if (classname.equals("androidx.appcompat.app.AlertDialog")) { - if (str.contains("为呵护未成")) { - AblViewUtil.mySleep(2); - performGlobalAction(GLOBAL_ACTION_BACK); - // 返回安装页面 - Log.e("TIAOSHI###", "关闭了为呵护未成年人健康成长的弹框"); - } - } else if (str.contains("检测到更新")) {//测试可以用 - LiveEventBus.get("runningstate").post("0"); - AblViewUtil.mySleep(2); - inputClickId("以后再说"); - Log.e("TIAOSHI###", "关闭了检测到更新的弹框"); - } else if (str.contains("发现通讯录朋友")) {//测试可以用 - LiveEventBus.get("runningstate").post("0"); - AblViewUtil.mySleep(2); - inputClickId("暂时不要"); - Log.e("TIAOSHI###", "AblService关闭了发现通讯录好友的弹框"); - } else if (str.contains("由于该用户隐私设置")) { - - } else if (str.contains("个人信息保护指引")) { - LiveEventBus.get("runningstate").post("0"); - } else if (str.contains("欢迎体验抖音浅色模式")) { - LiveEventBus.get("runningstate").post("0"); - } else if (str.contains("朋友推荐")) { - LiveEventBus.get("runningstate").post("0"); - } else if (str.contains("设置抖音号")) { - LiveEventBus.get("runningstate").post("0"); - } - AblViewUtil.Close(); - break; - } - default: - } - } - - - public void scroll2PositionClick(AccessibilityService service, String text) { - try { - Thread.sleep(5000); - //隔200 ms 滚动一次 - } catch (InterruptedException e) { - e.printStackTrace(); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - //必须android4.3以上的版本 - getdouyindsf(); - } - } - - private void getdouyindsf() { - AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); - for (int i = 0; i < root.getChildCount(); i++) { - AccessibilityNodeInfo child = root.getChild(i); - Log.e("TIAOSHI###跟", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); - for (int y = 0; y < child.getChildCount(); y++) { - AccessibilityNodeInfo child1 = child.getChild(y); - Log.e("TIAOSHI###", "----twoNode:" + child1.getClassName() + ":" + child1.getText() + ":" + child1.getContentDescription()); - if ("androidx.recyclerview.widget.RecyclerView".equals(child1.getClassName())) { - for (int j = 0; j < child1.getChildCount(); j++) { - AccessibilityNodeInfo child2 = child1.getChild(j); - Log.e("TIAOSHI###", "----threeNode:" + child2.getClassName() + ":" + child2.getText() + ":" + child1.getContentDescription()); - for (int x = 0; x < child2.getChildCount(); x++) { - AccessibilityNodeInfo child3 = child2.getChild(x); - Log.e("TIAOSHI###", "----fourNode:" + child3.getClassName() + ":" + child3.getText() + ":" + child1.getContentDescription()); - if ("android.widget.TextView".equals(child3.getClassName())) { - String content = child3.getText().toString(); - if (!TextUtils.isEmpty(content)) { - //检索内容里面是否有数字 - String[] buff = content.split(":"); - String sdfsd = buff[buff.length - 1]; - Log.e("获得结果----", sdfsd + ""); - fasongpinglun(sdfsd); - if (sdfsd.length() == 1) { - Log.e("获得结果----", sdfsd + ""); - if (Compliance(sdfsd)) { - ChangLiang.genfaneirong = sdfsd; - ChangLiang.gendanopen = 0; - Log.d(TAG, "获得结果----有数字=====" + content); - //跟发数字 - fasongpinglun(ChangLiang.genfaneirong); - break; - } else { - Log.d(TAG, "获得结果----中没有数字"); - } - } - } - } - } - } - break; - } - } - } - } - - public boolean Compliance(String substring) { - if (substring.contains("0") || substring.contains("1") || substring.contains("2") || substring.contains("3") || substring.contains("4") || substring.contains("5") || substring.contains("6") || substring.contains("7") || substring.contains("8") || substring.contains("9")) { - return true; - } else { - return false; - } - } - - - private void fasongpinglun(String conment) { - //直播间话术 - AblViewUtil.mySleep(2); - clickmoreli("1"); - AblViewUtil.mySleep(2); - //复制文本粘贴在留言板 - AccessibilityNodeInfo getedittext = getedittext(); - Log.e("TIAOSHI###", "获得的关键词内容" + conment); - AblViewUtil.mySleep(2); - AblViewUtil.sayInput(conment, getedittext); - AblViewUtil.mySleep(1); - AccessibilityNodeInfo geouyintdd = geouyintdd(); - AblService.getInstance().clickcommontwo(geouyintdd, "点击发送"); - AblViewUtil.mySleep(2); - } - - /** - * 输入框 - * - * @return - */ - public AccessibilityNodeInfo getedittext() { - AccessibilityNodeInfo nodeinfo = null; - AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); - for (int i = 0; i < root.getChildCount(); i++) { - AccessibilityNodeInfo child = root.getChild(i); - Log.e("TIAOSHI###", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); - if ("android.widget.EditText".equals(child.getClassName())) { - nodeinfo = child; - } - } - return nodeinfo; - } - - /** - * 发送节点 - * - * @return - */ - public AccessibilityNodeInfo geouyintdd() { - AccessibilityNodeInfo nodeinfo = null; - AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); - for (int i = 0; i < root.getChildCount(); i++) { - AccessibilityNodeInfo child = root.getChild(i); - // Log.e("TIAOSHI###", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); - if ("android.widget.Button".equals(child.getClassName())) { - if (child.getContentDescription() != null) { - if (child.getContentDescription().toString().equals("发送")) { - nodeinfo = child; - } - } - } - } - return nodeinfo; - } - - /** - * 点击直播间下方的更多按钮(备注:通过搜索点击直播进去的可用) - * 1.说点什么 - * 2.更多 - * 3.礼物 - */ - public void clickmoreli(String type) { - AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); - for (int i = 0; i < root.getChildCount(); i++) { - AccessibilityNodeInfo child = root.getChild(i); - // Log.e("TIAOSHI###", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); - for (int y = 0; y < child.getChildCount(); y++) { - AccessibilityNodeInfo child1 = child.getChild(y); - // Log.e("TIAOSHI###", "----twoNode:" + child1.getClassName() + ":" + child1.getText() + ":" + child1.getContentDescription()); - for (int j = 0; j < child1.getChildCount(); j++) { - AccessibilityNodeInfo child2 = child1.getChild(j); - // Log.e("TIAOSHI###", "----threeNode:" + child2.getClassName() + ":" + child2.getText() + ":" + child1.getContentDescription()); - for (int x = 0; x < child2.getChildCount(); x++) { - AccessibilityNodeInfo child3 = child2.getChild(x); - // Log.e("TIAOSHI###", "----fourNode:" + child3.getClassName() + ":" + child3.getText() + ":" + child1.getContentDescription()); - for (int r = 0; r < child3.getChildCount(); r++) { - AccessibilityNodeInfo child4 = child3.getChild(r); - // Log.e("TIAOSHI###", "----5Node:" + child4.getClassName() + ":" + child4.getText() + ":" + child4.getContentDescription()); - switch (type) { - case "1"://说点什么 - if ("android.widget.TextView".equals(child4.getClassName())) { - if (child4.getText() != null) { - if (child4.getText().toString().equals("说点什么...")) { - AblService.getInstance().clickcommontwo(child4, ""); - } - } - } - break; - case "2"://更多 - if ("android.widget.Button".equals(child4.getClassName())) { - if (child4.getContentDescription().equals("更多")) { - AblService.getInstance().clickcommontwo(child4, "点击了更多"); - } - } - break; - case "3"://礼物 - if ("android.widget.Button".equals(child4.getClassName())) { - if (child4.getContentDescription().equals("礼物")) { - AblService.getInstance().clickcommontwo(child4, ""); - } - } - break; - default: - } - } - } - } - } - } - } - - - @Override - public void onDestroy() { - super.onDestroy(); - Log.e("TIAOSHI###", "无障碍服务被销毁"); - LiveEventBus.get("ablservice").post("无障碍服务被销毁"); - // sendAction(false); - } - -// private void sendAction(boolean state) { -// intent.putExtra("state", state); -// sendBroadcast(intent); -// } - - - /** - * 当服务要被中断时调用.会被调用多次 - */ - @Override - public void onInterrupt() { - Log.e("TIAOSHI###", "无障碍服务被中断"); - LiveEventBus.get("ablservice").post("无障碍服务被中断"); - } - - @Override - public boolean onUnbind(Intent intent) { - Log.e("TIAOSHI###", "无障碍服务关闭"); - LiveEventBus.get("ablservice").post("无障碍服务关闭"); - return super.onUnbind(intent); - } - - - @RequiresApi(api = Build.VERSION_CODES.N) - public void clickPoint(float x1, float y1, long duration) { - - Path path = new Path(); - path.moveTo(x1, y1); - GestureDescription.Builder builder = new GestureDescription.Builder(); - GestureDescription gestureDescription = builder - .addStroke(new GestureDescription.StrokeDescription(path, 0, duration)) - .build(); - boolean b = dispatchGesture(gestureDescription, new GestureResultCallback() { - @Override - public void onCompleted(GestureDescription gestureDescription) { - super.onCompleted(gestureDescription); - // Log.e("TIAOSHI###", "点击结束..." + gestureDescription.getStrokeCount()); - } - - @Override - public void onCancelled(GestureDescription gestureDescription) { - super.onCancelled(gestureDescription); - Log.e("TIAOSHI###", "点击取消"); - } - }, null); - } - - @RequiresApi(api = Build.VERSION_CODES.N) - public void clickcommon(List idsd, String s) { - if (idsd.size() > 0) { - AccessibilityNodeInfo accessibilityNodeInfo = idsd.get(0); - Rect rect = new Rect(); - accessibilityNodeInfo.getBoundsInScreen(rect); - this.clickPoint((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 300); - Log.e("TIAOSHI###", "点击" + s + "按钮" + "(" + (rect.left + rect.right) / 2 + "," + (rect.top + rect.bottom) / 2 + ")"); - } else { - Log.e("TIAOSHI###", "没有找到" + s + "按钮,直接退出了。。。。"); - return; - } - } - - - @RequiresApi(api = Build.VERSION_CODES.N) - public void clickcommontwo(AccessibilityNodeInfo accessibilityNodeInfo, String s) { - if (accessibilityNodeInfo != null) { - Rect rect = new Rect(); - accessibilityNodeInfo.getBoundsInScreen(rect); - this.clickPoint((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 300); - Log.e("TIAOSHI###", "点击" + s + "按钮" + "(" + (rect.left + rect.right) / 2 + "," + (rect.top + rect.bottom) / 2 + ")"); - } else { - Log.e("TIAOSHI###", "没有找到" + s + "按钮,直接退出了。。。。"); - } - } - - @RequiresApi(api = Build.VERSION_CODES.N) - public void clickcommonthree(AccessibilityNodeInfo accessibilityNodeInfo, String s) { - if (accessibilityNodeInfo != null) { - Rect rect = new Rect(); - accessibilityNodeInfo.getBoundsInScreen(rect); - this.clickPoint((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 300); - Log.e("TIAOSHI###", "点击" + s + "按钮" + "(" + (rect.left + rect.right) / 2 + "," + (rect.top + rect.bottom) / 2 + ")"); - // ToastUtils.showShort("点击"+s+"按钮"+ "("+ (rect.left + rect.right) / 2 + "," + (rect.top + rect.bottom) / 2 + ")"); - } else { - Log.e("TIAOSHI###", "没有找到" + s + "按钮,直接退出了。。。。"); - AblViewUtil.back(); - return; - } - } - - - @RequiresApi(api = Build.VERSION_CODES.N) - public void randomSwipe() { - int a = 270 + RandumInt.getRandumInt4() * 8; - int b = 270 - RandumInt.getRandumInt4() * 10; -// int c=1700-RandumInt.getRandumInt4()*8; // 1920分辨率起步的滑动方式,原为1800 - int c = 1200 - RandumInt.getRandumInt4() * 8; // 1280分辨率起步的滑动方式 -// int c=1250-RandumInt.getRandumInt4()*8; // 1440分辨率的滑动方式:红米6A的方式,感觉屏幕没有1440高 - - int d = 300 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 - // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 - swipe(a, c, b, d, 320); //延迟330毫秒 -// mySleep(200); -// swipe(c,b,a,d,50); - } - - @RequiresApi(api = Build.VERSION_CODES.N) - public void randomSwipetwo() { - if (SHEBEITIPE_VILUETHREE.equals(ChangLiang.phonetype)) { - int a = 700 + RandumInt.getRandumInt4() * 8; - int b = 700 - RandumInt.getRandumInt4() * 10; - int c = 1700 - RandumInt.getRandumInt4() * 8; // 1920分辨率起步的滑动方式,原为1800 - int d = 500 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 - // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 - swipe(a, c, b, d, 500); //延迟330毫秒 - } else { - int a = 270 + RandumInt.getRandumInt4() * 8; - int b = 270 - RandumInt.getRandumInt4() * 10; -// int c=1700-RandumInt.getRandumInt4()*8; // 1920分辨率起步的滑动方式,原为1800 - int c = 1200 - RandumInt.getRandumInt4() * 8; // 1280分辨率起步的滑动方式 -// int c=1250-RandumInt.getRandumInt4()*8; // 1440分辨率的滑动方式:红米6A的方式,感觉屏幕没有1440高 - int d = 200 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 - // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 - swipe(a, c, b, d, 500); //延迟330毫秒 - } - } - - @RequiresApi(api = Build.VERSION_CODES.N) - public void randomSwipethree() { - if (SHEBEITIPE_VILUETHREE.equals(ChangLiang.phonetype)) { - int a = 700 + RandumInt.getRandumInt4() * 8; - int b = 700 - RandumInt.getRandumInt4() * 10; - int c = 1700 - RandumInt.getRandumInt4() * 8; // 1920分辨率起步的滑动方式,原为1800 - int d = 500 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 - // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 - swipe(b, d, a, c, 500); //延迟330毫秒 - } else { - int a = 270 + RandumInt.getRandumInt4() * 8; - int b = 270 - RandumInt.getRandumInt4() * 10; -// int c=1700-RandumInt.getRandumInt4()*8; // 1920分辨率起步的滑动方式,原为1800 - int c = 1200 - RandumInt.getRandumInt4() * 8; // 1280分辨率起步的滑动方式 -// int c=1250-RandumInt.getRandumInt4()*8; // 1440分辨率的滑动方式:红米6A的方式,感觉屏幕没有1440高 - int d = 200 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 - // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 - swipe(b, d, a, c, 500); //延迟330毫秒 - - } - } - - @RequiresApi(api = Build.VERSION_CODES.N) - public void randomSwipefour() { - int a = 700 + RandumInt.getRandumInt4() * 8; - int b = 700 - RandumInt.getRandumInt4() * 10; - int c = 1700 - RandumInt.getRandumInt4() * 8; // 1920分辨率起步的滑动方式,原为1800 - int d = 500 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 - // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 - swipe(540, 1800, 540, 1596, 500); //延迟330毫秒 - - } - @RequiresApi(api = Build.VERSION_CODES.N) - public void swipe(float x1, float y1, float x2, float y2, long duration) { - Path path = new Path(); - path.moveTo(x1, y1); - path.lineTo(x2, y2); - - Log.e("TIAOSHI###", "MyAccessibilityService中滑动swipe()方法滑动点,reset:(" + x1 + "," + y1 + "),(" + x2 + "," + y2 + ")" + "滑动的时长是:" + duration); - GestureDescription.Builder builder = new GestureDescription.Builder(); - GestureDescription gestureDescription = builder - .addStroke(new GestureDescription.StrokeDescription(path, 0, duration)) - .build(); - boolean b = dispatchGesture(gestureDescription, new GestureResultCallback() { - @Override - public void onCompleted(GestureDescription gestureDescription) { - super.onCompleted(gestureDescription); - Log.e("TIAOSHI###", "滑动结束..." + gestureDescription.getStrokeCount()); - } - - @Override - public void onCancelled(GestureDescription gestureDescription) { - super.onCancelled(gestureDescription); - Log.e("TIAOSHI###", "滑动取消"); - } - }, null); - } - -} +package com.fisherbone.fuzhu.abllib; + +import android.accessibilityservice.AccessibilityService; +import android.accessibilityservice.GestureDescription; +import android.annotation.TargetApi; +import android.content.Intent; +import android.graphics.Path; +import android.graphics.Rect; +import android.os.Build; +import android.text.TextUtils; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; + +import androidx.annotation.RequiresApi; + +import com.blankj.utilcode.util.LogUtils; +import com.fisherbone.fuzhu.ChangLiang; +import com.fisherbone.fuzhu.FuzhuApplication; +import com.fisherbone.fuzhu.abllib.utils.AblViewUtil; +import com.fisherbone.fuzhu.db.CommentBeanData; +import com.fisherbone.fuzhu.db.dao.CommentDao; +import com.fisherbone.fuzhu.entity.SixEvent; +import com.jeremyliao.liveeventbus.LiveEventBus; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import de.greenrobot.event.EventBus; +import io.reactivex.disposables.Disposable; + +/** + * 2019/4/21 + * 11:29 + * Levine + * wechat 1483232332 + */ +public class AblService extends AccessibilityService { + + private static AblService mAblService; + private Disposable mdDisposable; + private String TAG = "commongendan"; + public String SHEBEITIPE_VILUETHREE = "3"; + + public static AblService getInstance() { + if (mAblService == null) { + throw new NullPointerException("AblService辅助服务未开启"); + } + return mAblService; + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) + public void inputClickId(String clickId) { + AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); + if (nodeInfo != null) { + List list = nodeInfo.findAccessibilityNodeInfosByText(clickId); + for (AccessibilityNodeInfo item : list) { + clickcommontwo(item, clickId); + } + } + } + + + @Override + public void onCreate() { + super.onCreate(); + mAblService = this; + init(); + } + + private void init() { + Log.e("TIAOSHI", "无障碍服务初始化"); + } + + /** + * 系统成功绑定该服务时被触发,也就是当你在设置中开启相应的服务, + * 系统成功的绑定了该服务时会触发,通常我们可以在这里做一些初始化操作 + */ + @Override + protected void onServiceConnected() { + super.onServiceConnected(); + LogUtils.v("onServiceConnected"); + Log.e("TIAOSHI", "无障碍服务开启"); + // Android 12+ 上禁用 LiveEventBus,避免静态初始化崩溃 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("ablservice").post("无障碍服务开启"); + } + } + + private ArrayList objects = new ArrayList<>(); + + @Override + public void onAccessibilityEvent(AccessibilityEvent event) { +// if("2".equals(ChangLiang.phonetype)) { +// if ("T".equals(ChangLiang.qidong)) { +// ChangLiang.qidong = "F"; +// AblViewUtil.startApplication(); +// AblViewUtil.mySleep(10); +// DianSou(); +// AblViewUtil.mySleep(3); +// AccessibilityNodeInfo findcomentt = findEditText(); +// String content = "178421572"; +// Log.e("TIAOSHI###", "获得的关键词内容" + content); +// AblViewUtil.mySleep(1); +// if ("0".equals(ChangLiang.phonetype)) { +// AblViewUtil.sayInput(content, findcomentt); +// } else { +// //华为畅享20 +// AblViewUtil.sayInput(content, findcomentt); +// } +// AblViewUtil.mySleep(3); +// DianSou(); +// AblViewUtil.mySleep(5); +// //进入直播间 +// if ("0".equals(ChangLiang.phonetype) || "1".equals(ChangLiang.phonetype)) { +// AblService.getInstance().clickPoint(705, 198, 300); +// } else { +// AblService.getInstance().clickPoint(1058, 300, 300); +// } +// AblViewUtil.mySleep(3); +// if ("0".equals(ChangLiang.phonetype)) { +// AblService.getInstance().clickPoint(100, 300, 300); +// } else { +// //华为畅享20 +// AblService.getInstance().clickPoint(200, 400, 300); +// } +// AblViewUtil.mySleep(1); +// ansy(); +// } +// } + + +// LogUtils.v(event.getPackageName() + ""); +// if (ChangLiang.gendanopen == 1) { +// scroll2PositionClick(this, "6"); +// } + + + int eventType = event.getEventType(); + + switch (eventType) { + //当通知栏发生改变的时候 + case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: + Log.w("TIAOSHI", "有弹出======11111" + "==classname=="); + break; + //当窗口状态发生改变的时候 + case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: + String classname = event.getClassName().toString(); + Log.e("TIAOSHI", "有弹出==22222" + "==classname==" + classname); + List text = event.getText(); + if (text.size() > 0) { + CharSequence charSequence = text.get(0); + String str = charSequence.toString(); + // Log.w("TIAOSHI", "有弹出==" + str + "==classname==" + classname); + String s = charSequence.toString(); + Log.e("TIAOSHI", "有弹出==55555" + s + "==classname==" + classname); + if (!TextUtils.isEmpty(s)) { + EventBus.getDefault().post(new SixEvent("success", s)); + } + if (classname.equals("android.app.AlertDialog")) { + + } else if (classname.equals("com.android.packageinstaller.permission.ui.GrantPermissionsActivity")) { + //点击安装 +// AblViewUtil.mySleep(2); +// inputClickId("始终允许"); + } else if (classname.equals("com.android.packageinstaller.PackageInstallerActivity")) { + //点击安装 + inputClickId("安装"); + } else if (classname.equals("com.android.packageinstaller.InstallAppProgress")) { + //点击打开 + AblViewUtil.mySleep(5); + inputClickId("打开"); + } else if (classname.equals("android.app.Dialog")) {//测试可以用 + if (str.contains("朋友推荐")) { + AblViewUtil.mySleep(2); + performGlobalAction(GLOBAL_ACTION_BACK); // 返回安装页面 + Log.e("TIAOSHI###", "关闭了好友推荐的弹框"); + } + } else if (classname.equals("androidx.appcompat.app.AlertDialog")) { + if (str.contains("为呵护未成")) { + AblViewUtil.mySleep(2); + performGlobalAction(GLOBAL_ACTION_BACK); + // 返回安装页面 + Log.e("TIAOSHI###", "关闭了为呵护未成年人健康成长的弹框"); + } + } else if (str.contains("检测到更新")) {//测试可以用 + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("runningstate").post("0"); + } + AblViewUtil.mySleep(2); + inputClickId("以后再说"); + Log.e("TIAOSHI###", "关闭了检测到更新的弹框"); + } else if (str.contains("发现通讯录朋友")) {//测试可以用 + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("runningstate").post("0"); + } + AblViewUtil.mySleep(2); + inputClickId("暂时不要"); + Log.e("TIAOSHI###", "AblService关闭了发现通讯录好友的弹框"); + } else if (str.contains("由于该用户隐私设置")) { + + } else if (str.contains("个人信息保护指引")) { + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("runningstate").post("0"); + } + } else if (str.contains("欢迎体验抖音浅色模式")) { + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("runningstate").post("0"); + } + } else if (str.contains("朋友推荐")) { + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("runningstate").post("0"); + } + } else if (str.contains("设置抖音号")) { + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("runningstate").post("0"); + } + } + AblViewUtil.Close(); + break; + } + default: + } + } + + + public void scroll2PositionClick(AccessibilityService service, String text) { + try { + Thread.sleep(5000); + //隔200 ms 滚动一次 + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + //必须android4.3以上的版本 + getdouyindsf(); + } + } + + private void getdouyindsf() { + AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); + for (int i = 0; i < root.getChildCount(); i++) { + AccessibilityNodeInfo child = root.getChild(i); + Log.e("TIAOSHI###跟", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); + for (int y = 0; y < child.getChildCount(); y++) { + AccessibilityNodeInfo child1 = child.getChild(y); + Log.e("TIAOSHI###", "----twoNode:" + child1.getClassName() + ":" + child1.getText() + ":" + child1.getContentDescription()); + if ("androidx.recyclerview.widget.RecyclerView".equals(child1.getClassName())) { + for (int j = 0; j < child1.getChildCount(); j++) { + AccessibilityNodeInfo child2 = child1.getChild(j); + Log.e("TIAOSHI###", "----threeNode:" + child2.getClassName() + ":" + child2.getText() + ":" + child1.getContentDescription()); + for (int x = 0; x < child2.getChildCount(); x++) { + AccessibilityNodeInfo child3 = child2.getChild(x); + Log.e("TIAOSHI###", "----fourNode:" + child3.getClassName() + ":" + child3.getText() + ":" + child1.getContentDescription()); + if ("android.widget.TextView".equals(child3.getClassName())) { + String content = child3.getText().toString(); + if (!TextUtils.isEmpty(content)) { + //检索内容里面是否有数字 + String[] buff = content.split(":"); + String sdfsd = buff[buff.length - 1]; + Log.e("获得结果----", sdfsd + ""); + fasongpinglun(sdfsd); + if (sdfsd.length() == 1) { + Log.e("获得结果----", sdfsd + ""); + if (Compliance(sdfsd)) { + ChangLiang.genfaneirong = sdfsd; + ChangLiang.gendanopen = 0; + Log.d(TAG, "获得结果----有数字=====" + content); + //跟发数字 + fasongpinglun(ChangLiang.genfaneirong); + break; + } else { + Log.d(TAG, "获得结果----中没有数字"); + } + } + } + } + } + } + break; + } + } + } + } + + public boolean Compliance(String substring) { + if (substring.contains("0") || substring.contains("1") || substring.contains("2") || substring.contains("3") || substring.contains("4") || substring.contains("5") || substring.contains("6") || substring.contains("7") || substring.contains("8") || substring.contains("9")) { + return true; + } else { + return false; + } + } + + + private void fasongpinglun(String conment) { + //直播间话术 + AblViewUtil.mySleep(2); + clickmoreli("1"); + AblViewUtil.mySleep(2); + //复制文本粘贴在留言板 + AccessibilityNodeInfo getedittext = getedittext(); + Log.e("TIAOSHI###", "获得的关键词内容" + conment); + AblViewUtil.mySleep(2); + AblViewUtil.sayInput(conment, getedittext); + AblViewUtil.mySleep(1); + AccessibilityNodeInfo geouyintdd = geouyintdd(); + AblService.getInstance().clickcommontwo(geouyintdd, "点击发送"); + AblViewUtil.mySleep(2); + } + + /** + * 输入框 + * + * @return + */ + public AccessibilityNodeInfo getedittext() { + AccessibilityNodeInfo nodeinfo = null; + AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); + for (int i = 0; i < root.getChildCount(); i++) { + AccessibilityNodeInfo child = root.getChild(i); + Log.e("TIAOSHI###", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); + if ("android.widget.EditText".equals(child.getClassName())) { + nodeinfo = child; + } + } + return nodeinfo; + } + + /** + * 发送节点 + * + * @return + */ + public AccessibilityNodeInfo geouyintdd() { + AccessibilityNodeInfo nodeinfo = null; + AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); + for (int i = 0; i < root.getChildCount(); i++) { + AccessibilityNodeInfo child = root.getChild(i); + // Log.e("TIAOSHI###", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); + if ("android.widget.Button".equals(child.getClassName())) { + if (child.getContentDescription() != null) { + if (child.getContentDescription().toString().equals("发送")) { + nodeinfo = child; + } + } + } + } + return nodeinfo; + } + + /** + * 点击直播间下方的更多按钮(备注:通过搜索点击直播进去的可用) + * 1.说点什么 + * 2.更多 + * 3.礼物 + */ + public void clickmoreli(String type) { + AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); + for (int i = 0; i < root.getChildCount(); i++) { + AccessibilityNodeInfo child = root.getChild(i); + // Log.e("TIAOSHI###", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); + for (int y = 0; y < child.getChildCount(); y++) { + AccessibilityNodeInfo child1 = child.getChild(y); + // Log.e("TIAOSHI###", "----twoNode:" + child1.getClassName() + ":" + child1.getText() + ":" + child1.getContentDescription()); + for (int j = 0; j < child1.getChildCount(); j++) { + AccessibilityNodeInfo child2 = child1.getChild(j); + // Log.e("TIAOSHI###", "----threeNode:" + child2.getClassName() + ":" + child2.getText() + ":" + child1.getContentDescription()); + for (int x = 0; x < child2.getChildCount(); x++) { + AccessibilityNodeInfo child3 = child2.getChild(x); + // Log.e("TIAOSHI###", "----fourNode:" + child3.getClassName() + ":" + child3.getText() + ":" + child1.getContentDescription()); + for (int r = 0; r < child3.getChildCount(); r++) { + AccessibilityNodeInfo child4 = child3.getChild(r); + // Log.e("TIAOSHI###", "----5Node:" + child4.getClassName() + ":" + child4.getText() + ":" + child4.getContentDescription()); + switch (type) { + case "1"://说点什么 + if ("android.widget.TextView".equals(child4.getClassName())) { + if (child4.getText() != null) { + if (child4.getText().toString().equals("说点什么...")) { + AblService.getInstance().clickcommontwo(child4, ""); + } + } + } + break; + case "2"://更多 + if ("android.widget.Button".equals(child4.getClassName())) { + if (child4.getContentDescription().equals("更多")) { + AblService.getInstance().clickcommontwo(child4, "点击了更多"); + } + } + break; + case "3"://礼物 + if ("android.widget.Button".equals(child4.getClassName())) { + if (child4.getContentDescription().equals("礼物")) { + AblService.getInstance().clickcommontwo(child4, ""); + } + } + break; + default: + } + } + } + } + } + } + } + + + @Override + public void onDestroy() { + super.onDestroy(); + Log.e("TIAOSHI###", "无障碍服务被销毁"); + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("ablservice").post("无障碍服务被销毁"); + } + // sendAction(false); + } + +// private void sendAction(boolean state) { +// intent.putExtra("state", state); +// sendBroadcast(intent); +// } + + + /** + * 当服务要被中断时调用.会被调用多次 + */ + @Override + public void onInterrupt() { + Log.e("TIAOSHI###", "无障碍服务被中断"); + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("ablservice").post("无障碍服务被中断"); + } + } + + @Override + public boolean onUnbind(Intent intent) { + Log.e("TIAOSHI###", "无障碍服务关闭"); + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("ablservice").post("无障碍服务关闭"); + } + return super.onUnbind(intent); + } + + + @RequiresApi(api = Build.VERSION_CODES.N) + public void clickPoint(float x1, float y1, long duration) { + + Path path = new Path(); + path.moveTo(x1, y1); + GestureDescription.Builder builder = new GestureDescription.Builder(); + GestureDescription gestureDescription = builder + .addStroke(new GestureDescription.StrokeDescription(path, 0, duration)) + .build(); + boolean b = dispatchGesture(gestureDescription, new GestureResultCallback() { + @Override + public void onCompleted(GestureDescription gestureDescription) { + super.onCompleted(gestureDescription); + // Log.e("TIAOSHI###", "点击结束..." + gestureDescription.getStrokeCount()); + } + + @Override + public void onCancelled(GestureDescription gestureDescription) { + super.onCancelled(gestureDescription); + Log.e("TIAOSHI###", "点击取消"); + } + }, null); + } + + @RequiresApi(api = Build.VERSION_CODES.N) + public void clickcommon(List idsd, String s) { + if (idsd.size() > 0) { + AccessibilityNodeInfo accessibilityNodeInfo = idsd.get(0); + Rect rect = new Rect(); + accessibilityNodeInfo.getBoundsInScreen(rect); + this.clickPoint((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 300); + Log.e("TIAOSHI###", "点击" + s + "按钮" + "(" + (rect.left + rect.right) / 2 + "," + (rect.top + rect.bottom) / 2 + ")"); + } else { + Log.e("TIAOSHI###", "没有找到" + s + "按钮,直接退出了。。。。"); + return; + } + } + + + @RequiresApi(api = Build.VERSION_CODES.N) + public void clickcommontwo(AccessibilityNodeInfo accessibilityNodeInfo, String s) { + if (accessibilityNodeInfo != null) { + Rect rect = new Rect(); + accessibilityNodeInfo.getBoundsInScreen(rect); + this.clickPoint((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 300); + Log.e("TIAOSHI###", "点击" + s + "按钮" + "(" + (rect.left + rect.right) / 2 + "," + (rect.top + rect.bottom) / 2 + ")"); + } else { + Log.e("TIAOSHI###", "没有找到" + s + "按钮,直接退出了。。。。"); + } + } + + @RequiresApi(api = Build.VERSION_CODES.N) + public void clickcommonthree(AccessibilityNodeInfo accessibilityNodeInfo, String s) { + if (accessibilityNodeInfo != null) { + Rect rect = new Rect(); + accessibilityNodeInfo.getBoundsInScreen(rect); + this.clickPoint((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 300); + Log.e("TIAOSHI###", "点击" + s + "按钮" + "(" + (rect.left + rect.right) / 2 + "," + (rect.top + rect.bottom) / 2 + ")"); + // ToastUtils.showShort("点击"+s+"按钮"+ "("+ (rect.left + rect.right) / 2 + "," + (rect.top + rect.bottom) / 2 + ")"); + } else { + Log.e("TIAOSHI###", "没有找到" + s + "按钮,直接退出了。。。。"); + AblViewUtil.back(); + return; + } + } + + + @RequiresApi(api = Build.VERSION_CODES.N) + public void randomSwipe() { + int a = 270 + RandumInt.getRandumInt4() * 8; + int b = 270 - RandumInt.getRandumInt4() * 10; +// int c=1700-RandumInt.getRandumInt4()*8; // 1920分辨率起步的滑动方式,原为1800 + int c = 1200 - RandumInt.getRandumInt4() * 8; // 1280分辨率起步的滑动方式 +// int c=1250-RandumInt.getRandumInt4()*8; // 1440分辨率的滑动方式:红米6A的方式,感觉屏幕没有1440高 + + int d = 300 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 + // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 + swipe(a, c, b, d, 320); //延迟330毫秒 +// mySleep(200); +// swipe(c,b,a,d,50); + } + + @RequiresApi(api = Build.VERSION_CODES.N) + public void randomSwipetwo() { + if (SHEBEITIPE_VILUETHREE.equals(ChangLiang.phonetype)) { + int a = 700 + RandumInt.getRandumInt4() * 8; + int b = 700 - RandumInt.getRandumInt4() * 10; + int c = 1700 - RandumInt.getRandumInt4() * 8; // 1920分辨率起步的滑动方式,原为1800 + int d = 500 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 + // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 + swipe(a, c, b, d, 500); //延迟330毫秒 + } else { + int a = 270 + RandumInt.getRandumInt4() * 8; + int b = 270 - RandumInt.getRandumInt4() * 10; +// int c=1700-RandumInt.getRandumInt4()*8; // 1920分辨率起步的滑动方式,原为1800 + int c = 1200 - RandumInt.getRandumInt4() * 8; // 1280分辨率起步的滑动方式 +// int c=1250-RandumInt.getRandumInt4()*8; // 1440分辨率的滑动方式:红米6A的方式,感觉屏幕没有1440高 + int d = 200 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 + // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 + swipe(a, c, b, d, 500); //延迟330毫秒 + } + } + + @RequiresApi(api = Build.VERSION_CODES.N) + public void randomSwipethree() { + if (SHEBEITIPE_VILUETHREE.equals(ChangLiang.phonetype)) { + int a = 700 + RandumInt.getRandumInt4() * 8; + int b = 700 - RandumInt.getRandumInt4() * 10; + int c = 1700 - RandumInt.getRandumInt4() * 8; // 1920分辨率起步的滑动方式,原为1800 + int d = 500 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 + // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 + swipe(b, d, a, c, 500); //延迟330毫秒 + } else { + int a = 270 + RandumInt.getRandumInt4() * 8; + int b = 270 - RandumInt.getRandumInt4() * 10; +// int c=1700-RandumInt.getRandumInt4()*8; // 1920分辨率起步的滑动方式,原为1800 + int c = 1200 - RandumInt.getRandumInt4() * 8; // 1280分辨率起步的滑动方式 +// int c=1250-RandumInt.getRandumInt4()*8; // 1440分辨率的滑动方式:红米6A的方式,感觉屏幕没有1440高 + int d = 200 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 + // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 + swipe(b, d, a, c, 500); //延迟330毫秒 + + } + } + + @RequiresApi(api = Build.VERSION_CODES.N) + public void randomSwipefour() { + int a = 700 + RandumInt.getRandumInt4() * 8; + int b = 700 - RandumInt.getRandumInt4() * 10; + int c = 1700 - RandumInt.getRandumInt4() * 8; // 1920分辨率起步的滑动方式,原为1800 + int d = 500 - RandumInt.getRandumInt4() * 9; // 刚才是300, 延迟350~400 + // 800毫秒的时候,有时候有点卡,但是能用,再试试其他的 + swipe(540, 1800, 540, 1596, 500); //延迟330毫秒 + + } + @RequiresApi(api = Build.VERSION_CODES.N) + public void swipe(float x1, float y1, float x2, float y2, long duration) { + Path path = new Path(); + path.moveTo(x1, y1); + path.lineTo(x2, y2); + + Log.e("TIAOSHI###", "MyAccessibilityService中滑动swipe()方法滑动点,reset:(" + x1 + "," + y1 + "),(" + x2 + "," + y2 + ")" + "滑动的时长是:" + duration); + GestureDescription.Builder builder = new GestureDescription.Builder(); + GestureDescription gestureDescription = builder + .addStroke(new GestureDescription.StrokeDescription(path, 0, duration)) + .build(); + boolean b = dispatchGesture(gestureDescription, new GestureResultCallback() { + @Override + public void onCompleted(GestureDescription gestureDescription) { + super.onCompleted(gestureDescription); + Log.e("TIAOSHI###", "滑动结束..." + gestureDescription.getStrokeCount()); + } + + @Override + public void onCancelled(GestureDescription gestureDescription) { + super.onCancelled(gestureDescription); + Log.e("TIAOSHI###", "滑动取消"); + } + }, null); + } + +} diff --git a/app/src/main/java/com/fisherbone/fuzhu/abllib/AblStepHandler.java b/app/src/main/java/com/fisherbone/fuzhu/abllib/AblStepHandler.java index 4e332c6..1747ac8 100644 --- a/app/src/main/java/com/fisherbone/fuzhu/abllib/AblStepHandler.java +++ b/app/src/main/java/com/fisherbone/fuzhu/abllib/AblStepHandler.java @@ -1,212 +1,230 @@ -package com.fisherbone.fuzhu.abllib; - - -import android.os.Handler; -import android.os.Looper; -import android.os.Message; - -import androidx.annotation.NonNull; - -import com.blankj.utilcode.util.LogUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * 2019/4/21 - * 14:36 - * Levine - * wechat 1483232332 - */ -public class AblStepHandler extends Handler { - - private static AblStepHandler instance; - private List mStepListeners = new ArrayList<>(); - private boolean isStop = true;//是否停止 - private String[] mDatas;//数据 - private long mStepMsgDelayMillis = 2000;//消息延迟发送时间 - private List mInitializedSteps = new ArrayList<>();//已经初始化过的步骤 - - private AblStepHandler() { - super(Looper.getMainLooper()); - } - - public static AblStepHandler getInstance() { - if (instance == null) { - synchronized (AblStepHandler.class) { - if (instance == null) { - instance = new AblStepHandler(); - } - } - } - return instance; - } - - /** - * 发送handler执行消息 - * - * @param step 步骤 - * @param delayMillis 延迟时间 - * @param datas 数据 - */ - public static void sendMsg(int step, long delayMillis, String... datas) { - AblStepHandler ablStepHandler = AblStepHandler.getInstance(); - if (datas != null && datas.length > 0) { - ablStepHandler.setDatas(datas); - } - ablStepHandler.sendEmptyMessageDelayed(step, delayMillis); - } - - /** - * 发送handler执行消息 - * - * @param step 步骤 - * @param delayMillis 延迟时间 - */ - public static void sendMsg(int step, long delayMillis) { - sendMsg(step, delayMillis, new String[]{}); - } - - /** - * 发送handler执行消息 - * - * @param step 步骤 - * @param datas 数据 - */ - public static void sendMsg(int step, String... datas) { - sendMsg(step, AblStepHandler.getInstance().getStepMsgDelayMillis(), datas); - } - - /** - * 发送handler执行消息 - * - * @param step 步骤 - */ - public static void sendMsg(int step) { - sendMsg(step, AblStepHandler.getInstance().getStepMsgDelayMillis(), new String[]{}); - } - - /** - * 根据viewid或文字发送执行消息 - * - * @param millisInFuture view查找超时时间 - * @param countDownInterval 查找间隔时间 - * @param step 步骤 - */ - public static void sendMsgByView( - long millisInFuture, - long countDownInterval, - int step, - String... nextMsgViewIdOrText - ) { - FindViewCountDown.start(millisInFuture, countDownInterval, step, nextMsgViewIdOrText); - } - - /** - * 根据viewid或文字发送执行消息 - * - * @param millisInFuture view查找超时时间 - * @param countDownInterval 查找间隔时间 - * @param callBack 回调,注:如果回调不为空将不发送消息,要发送消息就自己在成功的回调里发送 - * @param viewIdOrText viewid或者文字内容 - */ - public static void sendMsgByView( - long millisInFuture, - long countDownInterval, - @NonNull FindViewCountDown.CallBack callBack, - String... viewIdOrText - ) { - FindViewCountDown.start(millisInFuture, countDownInterval, callBack, viewIdOrText); - } - - /** - * 根据viewid或文字发送执行消息 - * - * @param step 步骤 - * @param viewIdOrText viewid或者文字内容 - */ - public static void sendMsgByView( - int step, - String... viewIdOrText - ) { - FindViewCountDown.start(step, viewIdOrText); - } - - /** - * 根据viewid或文字发送执行消息 - * - * @param callBack 回调,注:如果回调不为空将不发送消息,要发送消息就自己在成功的回调里发送 - * @param viewIdOrText viewid或者文字内容 - */ - public static void sendMsgByView( - @NonNull FindViewCountDown.CallBack callBack, - String... viewIdOrText - ) { - FindViewCountDown.start(callBack, viewIdOrText); - } - - - public String[] getDatas() { - return mDatas; - } - - public void setDatas(String... datas) { - mDatas = datas; - } - - public long getStepMsgDelayMillis() { - return mStepMsgDelayMillis; - } - - public void setStepMsgDelayMillis(long msgDelayMillis) { - mStepMsgDelayMillis = msgDelayMillis; - } - - public boolean isStop() { - - return isStop; - } - - public void setStop(boolean stop) { - isStop = stop; - } - - @Override - public void handleMessage(Message msg) { - super.handleMessage(msg); - if (isStop) return; - LogUtils.v("step", msg.what); - for (StepListener stepListener : mStepListeners) { - stepListener.onStep(msg.what, msg); - } - } - - private void addStepListener(StepListener handleMessageListener) { - mStepListeners.add(handleMessageListener); - } - - public void removeStepListener(StepListener handleMessageListener) { - mStepListeners.remove(handleMessageListener); - } - - /** - * 初始化步骤实现类 - * - * @param ablStepBases 继承了StepBase的实现类 - */ - public void initStepClass(BaseAblStep... ablStepBases) { - for (BaseAblStep ablStepBase : ablStepBases) { - if (mInitializedSteps.contains(ablStepBase.getClass().getName())) { - LogUtils.e(ablStepBase.getClass().getName() + "已经初始化,请勿重复初始化"); - continue; - } - addStepListener(ablStepBase); - mInitializedSteps.add(ablStepBase.getClass().getName()); - } - } - - public interface StepListener { - void onStep(int step, Message msg); - } - -} +package com.fisherbone.fuzhu.abllib; + + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import androidx.annotation.NonNull; + +import com.blankj.utilcode.util.LogUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * 2019/4/21 + * 14:36 + * Levine + * wechat 1483232332 + */ +public class AblStepHandler extends Handler { + + private static AblStepHandler instance; + private List mStepListeners = new ArrayList<>(); + private boolean isStop = true;//是否停止 + private String[] mDatas;//数据 + private long mStepMsgDelayMillis = 2000;//消息延迟发送时间 + private List mInitializedSteps = new ArrayList<>();//已经初始化过的步骤 + + private AblStepHandler() { + super(Looper.getMainLooper()); + } + + public static AblStepHandler getInstance() { + if (instance == null) { + synchronized (AblStepHandler.class) { + if (instance == null) { + instance = new AblStepHandler(); + } + } + } + return instance; + } + + /** + * 发送handler执行消息 + * + * @param step 步骤 + * @param delayMillis 延迟时间 + * @param datas 数据 + */ + public static void sendMsg(int step, long delayMillis, String... datas) { + AblStepHandler ablStepHandler = AblStepHandler.getInstance(); + if (datas != null && datas.length > 0) { + ablStepHandler.setDatas(datas); + } + android.util.Log.e("TIAOSHI###", "AblStepHandler.sendMsg: 发送消息 step=" + step + ", delay=" + delayMillis + "ms, isStop=" + ablStepHandler.isStop()); + boolean result = ablStepHandler.sendEmptyMessageDelayed(step, delayMillis); + android.util.Log.e("TIAOSHI###", "AblStepHandler.sendMsg: 消息已加入队列, sendEmptyMessageDelayed返回=" + result); + } + + /** + * 发送handler执行消息 + * + * @param step 步骤 + * @param delayMillis 延迟时间 + */ + public static void sendMsg(int step, long delayMillis) { + sendMsg(step, delayMillis, new String[]{}); + } + + /** + * 发送handler执行消息 + * + * @param step 步骤 + * @param datas 数据 + */ + public static void sendMsg(int step, String... datas) { + sendMsg(step, AblStepHandler.getInstance().getStepMsgDelayMillis(), datas); + } + + /** + * 发送handler执行消息 + * + * @param step 步骤 + */ + public static void sendMsg(int step) { + sendMsg(step, AblStepHandler.getInstance().getStepMsgDelayMillis(), new String[]{}); + } + + /** + * 根据viewid或文字发送执行消息 + * + * @param millisInFuture view查找超时时间 + * @param countDownInterval 查找间隔时间 + * @param step 步骤 + */ + public static void sendMsgByView( + long millisInFuture, + long countDownInterval, + int step, + String... nextMsgViewIdOrText + ) { + FindViewCountDown.start(millisInFuture, countDownInterval, step, nextMsgViewIdOrText); + } + + /** + * 根据viewid或文字发送执行消息 + * + * @param millisInFuture view查找超时时间 + * @param countDownInterval 查找间隔时间 + * @param callBack 回调,注:如果回调不为空将不发送消息,要发送消息就自己在成功的回调里发送 + * @param viewIdOrText viewid或者文字内容 + */ + public static void sendMsgByView( + long millisInFuture, + long countDownInterval, + @NonNull FindViewCountDown.CallBack callBack, + String... viewIdOrText + ) { + FindViewCountDown.start(millisInFuture, countDownInterval, callBack, viewIdOrText); + } + + /** + * 根据viewid或文字发送执行消息 + * + * @param step 步骤 + * @param viewIdOrText viewid或者文字内容 + */ + public static void sendMsgByView( + int step, + String... viewIdOrText + ) { + FindViewCountDown.start(step, viewIdOrText); + } + + /** + * 根据viewid或文字发送执行消息 + * + * @param callBack 回调,注:如果回调不为空将不发送消息,要发送消息就自己在成功的回调里发送 + * @param viewIdOrText viewid或者文字内容 + */ + public static void sendMsgByView( + @NonNull FindViewCountDown.CallBack callBack, + String... viewIdOrText + ) { + FindViewCountDown.start(callBack, viewIdOrText); + } + + + public String[] getDatas() { + return mDatas; + } + + public void setDatas(String... datas) { + mDatas = datas; + } + + public long getStepMsgDelayMillis() { + return mStepMsgDelayMillis; + } + + public void setStepMsgDelayMillis(long msgDelayMillis) { + mStepMsgDelayMillis = msgDelayMillis; + } + + public boolean isStop() { + + return isStop; + } + + public void setStop(boolean stop) { + android.util.Log.e("TIAOSHI###", "AblStepHandler.setStop: 设置 isStop=" + stop + ", 调用堆栈: " + android.util.Log.getStackTraceString(new Exception())); + isStop = stop; + } + + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + android.util.Log.e("TIAOSHI###", "AblStepHandler.handleMessage: 收到消息 step=" + msg.what + ", isStop=" + isStop + ", Thread=" + Thread.currentThread().getName() + ", Looper=" + (Looper.myLooper() != null ? Looper.myLooper().toString() : "null")); + if (isStop) { + android.util.Log.e("TIAOSHI###", "AblStepHandler: 收到消息 " + msg.what + " 但 isStop=true,忽略"); + return; + } + android.util.Log.e("TIAOSHI###", "AblStepHandler: 处理消息 step=" + msg.what + ", listeners=" + mStepListeners.size()); + LogUtils.v("step", msg.what); + try { + for (StepListener stepListener : mStepListeners) { + android.util.Log.e("TIAOSHI###", "AblStepHandler: 调用 listener.onStep, listener=" + stepListener.getClass().getName()); + try { + stepListener.onStep(msg.what, msg); + android.util.Log.e("TIAOSHI###", "AblStepHandler: listener.onStep 执行完成, listener=" + stepListener.getClass().getName()); + } catch (Exception e) { + android.util.Log.e("TIAOSHI###", "AblStepHandler: listener.onStep 执行异常, listener=" + stepListener.getClass().getName(), e); + } + } + } catch (Exception e) { + android.util.Log.e("TIAOSHI###", "AblStepHandler.handleMessage: 处理消息异常", e); + } + } + + private void addStepListener(StepListener handleMessageListener) { + mStepListeners.add(handleMessageListener); + } + + public void removeStepListener(StepListener handleMessageListener) { + mStepListeners.remove(handleMessageListener); + } + + /** + * 初始化步骤实现类 + * + * @param ablStepBases 继承了StepBase的实现类 + */ + public void initStepClass(BaseAblStep... ablStepBases) { + for (BaseAblStep ablStepBase : ablStepBases) { + if (mInitializedSteps.contains(ablStepBase.getClass().getName())) { + LogUtils.e(ablStepBase.getClass().getName() + "已经初始化,请勿重复初始化"); + continue; + } + addStepListener(ablStepBase); + mInitializedSteps.add(ablStepBase.getClass().getName()); + } + } + + public interface StepListener { + void onStep(int step, Message msg); + } + +} diff --git a/app/src/main/java/com/fisherbone/fuzhu/abllib/AblSteps.java b/app/src/main/java/com/fisherbone/fuzhu/abllib/AblSteps.java index 9aa89f5..694837c 100644 --- a/app/src/main/java/com/fisherbone/fuzhu/abllib/AblSteps.java +++ b/app/src/main/java/com/fisherbone/fuzhu/abllib/AblSteps.java @@ -1,319 +1,321 @@ -package com.fisherbone.fuzhu.abllib; - -/** - * 2019/4/21 - * 18:33 - * Levine - * wechat 1483232332 - */ -public class AblSteps { - - /** - * 全局静态常量步骤标识1~200,不够自己再加,从200开始加,基本应该都是够的了 - */ - public final static int STEP_1 = 1; - public final static int STEP_2 = 2; - public final static int STEP_3 = 3; - public final static int STEP_4 = 4; - public final static int STEP_5 = 5; - public final static int STEP_6 = 6; - public final static int STEP_7 = 7; - public final static int STEP_8 = 8; - public final static int STEP_9 = 9; - /*****************************************/ - public final static int STEP_10 = 10; - public final static int STEP_11 = 11; - public final static int STEP_12 = 12; - public final static int STEP_13 = 13; - public final static int STEP_14 = 14; - public final static int STEP_15 = 15; - public final static int STEP_16 = 16; - public final static int STEP_17 = 17; - public final static int STEP_18 = 18; - public final static int STEP_19 = 19; - /*****************************************/ - public final static int STEP_20 = 20; - public final static int STEP_21 = 21; - public final static int STEP_22 = 22; - public final static int STEP_23 = 23; - public final static int STEP_24 = 24; - public final static int STEP_25 = 25; - public final static int STEP_26 = 26; - public final static int STEP_27 = 27; - public final static int STEP_28 = 28; - public final static int STEP_29 = 29; - /*****************************************/ - public final static int STEP_30 = 30; - public final static int STEP_31 = 31; - public final static int STEP_32 = 32; - public final static int STEP_33 = 33; - public final static int STEP_34 = 34; - public final static int STEP_35 = 35; - public final static int STEP_36 = 36; - public final static int STEP_37 = 37; - public final static int STEP_38 = 38; - public final static int STEP_39 = 39; - /*****************************************/ - public final static int STEP_40 = 40; - public final static int STEP_41 = 41; - public final static int STEP_42 = 42; - public final static int STEP_43 = 43; - public final static int STEP_44 = 44; - public final static int STEP_45 = 45; - public final static int STEP_46 = 46; - public final static int STEP_47 = 47; - public final static int STEP_48 = 48; - public final static int STEP_49 = 49; - /*****************************************/ - public final static int STEP_50 = 50; - public final static int STEP_51 = 51; - public final static int STEP_52 = 52; - public final static int STEP_53 = 53; - public final static int STEP_54 = 54; - public final static int STEP_55 = 55; - public final static int STEP_56 = 56; - public final static int STEP_57 = 57; - public final static int STEP_58 = 58; - public final static int STEP_59 = 59; - /*****************************************/ - public final static int STEP_60 = 60; - public final static int STEP_61 = 61; - public final static int STEP_62 = 62; - public final static int STEP_63 = 63; - public final static int STEP_64 = 64; - public final static int STEP_65 = 65; - public final static int STEP_66 = 66; - public final static int STEP_67 = 67; - public final static int STEP_68 = 68; - public final static int STEP_69 = 69; - /*****************************************/ - public final static int STEP_70 = 70; - public final static int STEP_71 = 71; - public final static int STEP_72 = 72; - public final static int STEP_73 = 73; - public final static int STEP_74 = 74; - public final static int STEP_75 = 75; - public final static int STEP_76 = 76; - public final static int STEP_77 = 77; - public final static int STEP_78 = 78; - public final static int STEP_79 = 79; - /*****************************************/ - public final static int STEP_80 = 80; - public final static int STEP_81 = 81; - public final static int STEP_82 = 82; - public final static int STEP_83 = 83; - public final static int STEP_84 = 84; - public final static int STEP_85 = 85; - public final static int STEP_86 = 86; - public final static int STEP_87 = 87; - public final static int STEP_88 = 88; - public final static int STEP_89 = 89; - /*****************************************/ - public final static int STEP_90 = 90; - public final static int STEP_91 = 91; - public final static int STEP_92 = 92; - public final static int STEP_93 = 93; - public final static int STEP_94 = 94; - public final static int STEP_95 = 95; - public final static int STEP_96 = 96; - public final static int STEP_97 = 97; - public final static int STEP_98 = 98; - public final static int STEP_99 = 99; - /*****************************************/ - public final static int STEP_100 = 100; - public final static int STEP_101 = 101; - public final static int STEP_102 = 102; - public final static int STEP_103 = 103; - public final static int STEP_104 = 104; - public final static int STEP_105 = 105; - public final static int STEP_106 = 106; - public final static int STEP_107 = 107; - public final static int STEP_108 = 108; - public final static int STEP_109 = 109; - /*****************************************/ - public final static int STEP_110 = 110; - public final static int STEP_111 = 111; - public final static int STEP_112 = 112; - public final static int STEP_113 = 113; - public final static int STEP_114 = 114; - public final static int STEP_115 = 115; - public final static int STEP_116 = 116; - public final static int STEP_117 = 117; - public final static int STEP_118 = 118; - public final static int STEP_119 = 119; - /*****************************************/ - public final static int STEP_120 = 120; - public final static int STEP_121 = 121; - public final static int STEP_122 = 122; - public final static int STEP_123 = 123; - public final static int STEP_124 = 124; - public final static int STEP_125 = 125; - public final static int STEP_126 = 126; - public final static int STEP_127 = 127; - public final static int STEP_128 = 128; - public final static int STEP_129 = 129; - /*****************************************/ - public final static int STEP_130 = 130; - public final static int STEP_131 = 131; - public final static int STEP_132 = 132; - public final static int STEP_133 = 133; - public final static int STEP_134 = 134; - public final static int STEP_135 = 135; - public final static int STEP_136 = 136; - public final static int STEP_137 = 137; - public final static int STEP_138 = 138; - public final static int STEP_139 = 139; - /*****************************************/ - public final static int STEP_140 = 140; - public final static int STEP_141 = 141; - public final static int STEP_142 = 142; - public final static int STEP_143 = 143; - public final static int STEP_144 = 144; - public final static int STEP_145 = 145; - public final static int STEP_146 = 146; - public final static int STEP_147 = 147; - public final static int STEP_148 = 148; - public final static int STEP_149 = 149; - /*****************************************/ - public final static int STEP_150 = 150; - public final static int STEP_151 = 151; - public final static int STEP_152 = 152; - public final static int STEP_153 = 153; - public final static int STEP_154 = 154; - public final static int STEP_155 = 155; - public final static int STEP_156 = 156; - public final static int STEP_157 = 157; - public final static int STEP_158 = 158; - public final static int STEP_159 = 159; - /*****************************************/ - public final static int STEP_160 = 160; - public final static int STEP_161 = 161; - public final static int STEP_162 = 162; - public final static int STEP_163 = 163; - public final static int STEP_164 = 164; - public final static int STEP_165 = 165; - public final static int STEP_166 = 166; - public final static int STEP_167 = 167; - public final static int STEP_168 = 168; - public final static int STEP_169 = 169; - /*****************************************/ - public final static int STEP_170 = 170; - public final static int STEP_171 = 171; - public final static int STEP_172 = 172; - public final static int STEP_173 = 173; - public final static int STEP_174 = 174; - public final static int STEP_175 = 175; - public final static int STEP_176 = 176; - public final static int STEP_177 = 177; - public final static int STEP_178 = 178; - public final static int STEP_179 = 179; - /*****************************************/ - public final static int STEP_180 = 180; - public final static int STEP_181 = 181; - public final static int STEP_182 = 182; - public final static int STEP_183 = 183; - public final static int STEP_184 = 184; - public final static int STEP_185 = 185; - public final static int STEP_186 = 186; - public final static int STEP_187 = 187; - public final static int STEP_188 = 188; - public final static int STEP_189 = 189; - /*****************************************/ - public final static int STEP_190 = 190; - public final static int STEP_191 = 191; - public final static int STEP_192 = 192; - public final static int STEP_193 = 193; - public final static int STEP_194 = 194; - public final static int STEP_195 = 195; - public final static int STEP_196 = 196; - public final static int STEP_197 = 197; - public final static int STEP_198 = 198; - public final static int STEP_199 = 199; - public final static int STEP_200 = 200; - - /*****************************************/ - public final static int STEP_201 = 201; - public final static int STEP_202 = 202; - public final static int STEP_203 = 203; - public final static int STEP_204 = 24; - public final static int STEP_205 = 205; - public final static int STEP_206 = 206; - public final static int STEP_207 = 207; - public final static int STEP_208 = 208; - public final static int STEP_209 = 209; - public final static int STEP_210 = 210; - - /*****************************************/ - public final static int STEP_211 = 211; - public final static int STEP_212 = 212; - public final static int STEP_213 = 213; - public final static int STEP_214 = 214; - public final static int STEP_215 = 215; - public final static int STEP_216 = 216; - public final static int STEP_217 = 217; - public final static int STEP_218 = 218; - public final static int STEP_219 = 219; - public final static int STEP_220 = 220; - /*****************************************/ - - public final static int STEP_221 = 221; - public final static int STEP_222 = 222; - public final static int STEP_223 = 223; - public final static int STEP_224 = 224; - public final static int STEP_225 = 225; - public final static int STEP_226 = 226; - public final static int STEP_227 = 227; - public final static int STEP_228 = 228; - public final static int STEP_229 = 229; - public final static int STEP_230 = 230; - - /*****************************************/ - - public final static int STEP_231 = 231; - public final static int STEP_232 = 232; - public final static int STEP_233 = 233; - public final static int STEP_234 = 234; - public final static int STEP_235 = 235; - public final static int STEP_236 = 236; - public final static int STEP_237 = 237; - public final static int STEP_238 = 238; - public final static int STEP_239 = 239; - public final static int STEP_240 = 240; - /*****************************************/ - - public final static int STEP_241 = 241; - public final static int STEP_242 = 242; - public final static int STEP_243 = 243; - public final static int STEP_244 = 244; - public final static int STEP_245 = 245; - public final static int STEP_246 = 246; - public final static int STEP_247 = 247; - public final static int STEP_248 = 248; - public final static int STEP_249 = 249; - - /*****************************************/ - public final static int STEP_250 = 250; - public final static int STEP_251 = 251; - public final static int STEP_252 = 252; - public final static int STEP_253 = 253; - public final static int STEP_254 = 254; - public final static int STEP_255 = 255; - public final static int STEP_256 = 256; - public final static int STEP_257 = 257; - public final static int STEP_258 = 258; - public final static int STEP_259 = 259; - - /*****************************************/ - public final static int STEP_260 = 260; - public final static int STEP_261 = 261; - public final static int STEP_262 = 262; - public final static int STEP_263 = 263; - public final static int STEP_264 = 264; - public final static int STEP_265 = 265; - public final static int STEP_266 = 266; - public final static int STEP_267 = 267; - public final static int STEP_268 = 268; - public final static int STEP_269 = 269; - - -} +package com.fisherbone.fuzhu.abllib; + +/** + * 2019/4/21 + * 18:33 + * Levine + * wechat 1483232332 + */ +public class AblSteps { + + /** + * 全局静态常量步骤标识1~200,不够自己再加,从200开始加,基本应该都是够的了 + */ + public final static int STEP_1 = 1; + public final static int STEP_2 = 2; + public final static int STEP_3 = 3; + public final static int STEP_4 = 4; + public final static int STEP_5 = 5; + public final static int STEP_6 = 6; + public final static int STEP_7 = 7; + public final static int STEP_8 = 8; + public final static int STEP_9 = 9; + /*****************************************/ + public final static int STEP_10 = 10; + public final static int STEP_11 = 11; + public final static int STEP_12 = 12; + public final static int STEP_13 = 13; + public final static int STEP_14 = 14; + public final static int STEP_15 = 15; + public final static int STEP_16 = 16; + public final static int STEP_17 = 17; + public final static int STEP_18 = 18; + public final static int STEP_19 = 19; + /*****************************************/ + public final static int STEP_20 = 20; + public final static int STEP_21 = 21; + public final static int STEP_22 = 22; + public final static int STEP_23 = 23; + public final static int STEP_24 = 24; + public final static int STEP_25 = 25; + public final static int STEP_26 = 26; + public final static int STEP_27 = 27; + public final static int STEP_28 = 28; + public final static int STEP_29 = 29; + /*****************************************/ + public final static int STEP_30 = 30; + public final static int STEP_31 = 31; + public final static int STEP_32 = 32; + public final static int STEP_33 = 33; + public final static int STEP_34 = 34; + public final static int STEP_35 = 35; + public final static int STEP_36 = 36; + public final static int STEP_37 = 37; + public final static int STEP_38 = 38; + public final static int STEP_39 = 39; + /*****************************************/ + public final static int STEP_40 = 40; + public final static int STEP_41 = 41; + public final static int STEP_42 = 42; + public final static int STEP_43 = 43; + public final static int STEP_44 = 44; + public final static int STEP_45 = 45; + public final static int STEP_46 = 46; + public final static int STEP_47 = 47; + public final static int STEP_48 = 48; + public final static int STEP_49 = 49; + /*****************************************/ + public final static int STEP_50 = 50; + public final static int STEP_51 = 51; + public final static int STEP_52 = 52; + public final static int STEP_53 = 53; + public final static int STEP_54 = 54; + public final static int STEP_55 = 55; + public final static int STEP_56 = 56; + public final static int STEP_57 = 57; + public final static int STEP_58 = 58; + public final static int STEP_59 = 59; + /*****************************************/ + public final static int STEP_60 = 60; + public final static int STEP_61 = 61; + public final static int STEP_62 = 62; + public final static int STEP_63 = 63; + public final static int STEP_64 = 64; + public final static int STEP_65 = 65; + public final static int STEP_66 = 66; + public final static int STEP_67 = 67; + public final static int STEP_68 = 68; + public final static int STEP_69 = 69; + /*****************************************/ + public final static int STEP_70 = 70; + public final static int STEP_71 = 71; + public final static int STEP_72 = 72; + public final static int STEP_73 = 73; + public final static int STEP_74 = 74; + public final static int STEP_75 = 75; + public final static int STEP_76 = 76; + public final static int STEP_77 = 77; + public final static int STEP_78 = 78; + public final static int STEP_79 = 79; + /*****************************************/ + public final static int STEP_80 = 80; + public final static int STEP_81 = 81; + public final static int STEP_82 = 82; + public final static int STEP_83 = 83; + public final static int STEP_84 = 84; + public final static int STEP_85 = 85; + public final static int STEP_86 = 86; + public final static int STEP_87 = 87; + public final static int STEP_88 = 88; + public final static int STEP_89 = 89; + /*****************************************/ + public final static int STEP_90 = 90; + public final static int STEP_91 = 91; + public final static int STEP_92 = 92; + public final static int STEP_93 = 93; + public final static int STEP_94 = 94; + public final static int STEP_95 = 95; + public final static int STEP_96 = 96; + public final static int STEP_97 = 97; + public final static int STEP_98 = 98; + public final static int STEP_99 = 99; + /*****************************************/ + public final static int STEP_100 = 100; + public final static int STEP_101 = 101; + public final static int STEP_102 = 102; + public final static int STEP_103 = 103; + public final static int STEP_104 = 104; + public final static int STEP_105 = 105; + public final static int STEP_106 = 106; + public final static int STEP_107 = 107; + public final static int STEP_108 = 108; + public final static int STEP_109 = 109; + /*****************************************/ + public final static int STEP_110 = 110; + public final static int STEP_111 = 111; + public final static int STEP_112 = 112; + public final static int STEP_113 = 113; + public final static int STEP_114 = 114; + public final static int STEP_115 = 115; + public final static int STEP_116 = 116; + public final static int STEP_117 = 117; + public final static int STEP_118 = 118; + public final static int STEP_119 = 119; + /*****************************************/ + public final static int STEP_120 = 120; + public final static int STEP_121 = 121; + public final static int STEP_122 = 122; + public final static int STEP_123 = 123; + public final static int STEP_124 = 124; + public final static int STEP_125 = 125; + public final static int STEP_126 = 126; + public final static int STEP_127 = 127; + public final static int STEP_128 = 128; + public final static int STEP_129 = 129; + /*****************************************/ + public final static int STEP_130 = 130; + public final static int STEP_131 = 131; + public final static int STEP_132 = 132; + public final static int STEP_133 = 133; + public final static int STEP_134 = 134; + public final static int STEP_135 = 135; + public final static int STEP_136 = 136; + public final static int STEP_137 = 137; + public final static int STEP_138 = 138; + public final static int STEP_139 = 139; + /*****************************************/ + public final static int STEP_140 = 140; + public final static int STEP_141 = 141; + public final static int STEP_142 = 142; + public final static int STEP_143 = 143; + public final static int STEP_144 = 144; + public final static int STEP_145 = 145; + public final static int STEP_146 = 146; + public final static int STEP_147 = 147; + public final static int STEP_148 = 148; + public final static int STEP_149 = 149; + /*****************************************/ + public final static int STEP_150 = 150; + public final static int STEP_151 = 151; + public final static int STEP_152 = 152; + public final static int STEP_153 = 153; + public final static int STEP_154 = 154; + public final static int STEP_155 = 155; + public final static int STEP_156 = 156; + public final static int STEP_157 = 157; + public final static int STEP_158 = 158; + public final static int STEP_159 = 159; + /*****************************************/ + public final static int STEP_160 = 160; + public final static int STEP_161 = 161; + public final static int STEP_162 = 162; + public final static int STEP_163 = 163; + public final static int STEP_164 = 164; + public final static int STEP_165 = 165; + public final static int STEP_166 = 166; + public final static int STEP_167 = 167; + public final static int STEP_168 = 168; + public final static int STEP_169 = 169; + /*****************************************/ + public final static int STEP_170 = 170; + public final static int STEP_171 = 171; + public final static int STEP_172 = 172; + public final static int STEP_173 = 173; + public final static int STEP_174 = 174; + public final static int STEP_175 = 175; + public final static int STEP_176 = 176; + public final static int STEP_177 = 177; + public final static int STEP_178 = 178; + public final static int STEP_179 = 179; + /*****************************************/ + public final static int STEP_180 = 180; + public final static int STEP_181 = 181; + public final static int STEP_182 = 182; + public final static int STEP_183 = 183; + public final static int STEP_184 = 184; + public final static int STEP_185 = 185; + public final static int STEP_186 = 186; + public final static int STEP_187 = 187; + public final static int STEP_188 = 188; + public final static int STEP_189 = 189; + /*****************************************/ + public final static int STEP_190 = 190; + public final static int STEP_191 = 191; + public final static int STEP_192 = 192; + public final static int STEP_193 = 193; + public final static int STEP_194 = 194; + public final static int STEP_195 = 195; + public final static int STEP_196 = 196; + public final static int STEP_197 = 197; + public final static int STEP_198 = 198; + public final static int STEP_199 = 199; + public final static int STEP_200 = 200; + + /*****************************************/ + public final static int STEP_201 = 201; + public final static int STEP_202 = 202; + public final static int STEP_203 = 203; + public final static int STEP_204 = 24; + public final static int STEP_205 = 205; + public final static int STEP_206 = 206; + public final static int STEP_207 = 207; + public final static int STEP_208 = 208; + public final static int STEP_209 = 209; + public final static int STEP_210 = 210; + + /*****************************************/ + public final static int STEP_211 = 211; + public final static int STEP_212 = 212; + public final static int STEP_213 = 213; + public final static int STEP_214 = 214; + public final static int STEP_215 = 215; + public final static int STEP_216 = 216; + public final static int STEP_217 = 217; + public final static int STEP_218 = 218; + public final static int STEP_219 = 219; + public final static int STEP_220 = 220; + /*****************************************/ + + public final static int STEP_221 = 221; + public final static int STEP_222 = 222; + public final static int STEP_223 = 223; + public final static int STEP_224 = 224; + public final static int STEP_225 = 225; + public final static int STEP_226 = 226; + public final static int STEP_227 = 227; + public final static int STEP_228 = 228; + public final static int STEP_229 = 229; + public final static int STEP_230 = 230; + + /*****************************************/ + + public final static int STEP_231 = 231; + public final static int STEP_232 = 232; + public final static int STEP_233 = 233; + public final static int STEP_234 = 234; + public final static int STEP_235 = 235; + public final static int STEP_236 = 236; + public final static int STEP_237 = 237; + public final static int STEP_238 = 238; + public final static int STEP_239 = 239; + public final static int STEP_240 = 240; + /*****************************************/ + + public final static int STEP_241 = 241; + public final static int STEP_242 = 242; + public final static int STEP_243 = 243; + public final static int STEP_244 = 244; + public final static int STEP_245 = 245; + public final static int STEP_246 = 246; + public final static int STEP_247 = 247; + public final static int STEP_248 = 248; + public final static int STEP_249 = 249; + + /*****************************************/ + public final static int STEP_250 = 250; + public final static int STEP_251 = 251; + public final static int STEP_252 = 252; + public final static int STEP_253 = 253; + public final static int STEP_254 = 254; + public final static int STEP_255 = 255; + public final static int STEP_256 = 256; + public final static int STEP_257 = 257; + public final static int STEP_258 = 258; + public final static int STEP_259 = 259; + + /*****************************************/ + public final static int STEP_260 = 260; + public final static int STEP_261 = 261; + public final static int STEP_262 = 262; + public final static int STEP_263 = 263; + public final static int STEP_264 = 264; + public final static int STEP_265 = 265; + public final static int STEP_266 = 266; + public final static int STEP_267 = 267; + public final static int STEP_268 = 268; + public final static int STEP_269 = 269; + + public final static int STEP_270 = 270; + public final static int STEP_271 = 271; + public final static int STEP_272 = 272; +} diff --git a/app/src/main/java/com/fisherbone/fuzhu/abllib/utils/AblViewUtil.java b/app/src/main/java/com/fisherbone/fuzhu/abllib/utils/AblViewUtil.java index c9cc3bd..cb41be0 100644 --- a/app/src/main/java/com/fisherbone/fuzhu/abllib/utils/AblViewUtil.java +++ b/app/src/main/java/com/fisherbone/fuzhu/abllib/utils/AblViewUtil.java @@ -1,667 +1,675 @@ -package com.fisherbone.fuzhu.abllib.utils; - -import android.accessibilityservice.AccessibilityService; -import android.accessibilityservice.GestureDescription; -import android.annotation.TargetApi; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.graphics.Path; -import android.graphics.Rect; -import android.os.Build; -import android.os.Bundle; -import android.util.Log; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; - -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; - -import com.blankj.utilcode.util.ScreenUtils; -import com.fisherbone.fuzhu.FuzhuApplication; -import com.fisherbone.fuzhu.InfoMessage; -import com.fisherbone.fuzhu.abllib.AblService; -import com.fisherbone.fuzhu.abllib.callback.AniCallBack; -import com.fisherbone.fuzhu.abllib.callback.AnisCallBack; -import com.fisherbone.fuzhu.abllib.callback.GestureCallBack; - -import java.util.ArrayList; -import java.util.List; - -import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_BACK; -import static android.content.Context.CLIPBOARD_SERVICE; - -/** - * 界面操作工具类 - * wechat 1483232332 - */ -public class AblViewUtil { - private static InfoMessage infoMessag; - /** - * 根据id获取view - * - * @param parent - * @param id 界面id - * @param position - * @return - */ - public static AccessibilityNodeInfo findById( - AccessibilityNodeInfo parent, - String id, - int position, - @Nullable AniCallBack callBack - ) { - if (parent != null) { - List accessibilityNodeInfos = - parent.findAccessibilityNodeInfosByViewId(id); - if (accessibilityNodeInfos != null && - !accessibilityNodeInfos.isEmpty() && - position < accessibilityNodeInfos.size()) { - if (callBack != null) { - callBack.succ(accessibilityNodeInfos.get(position)); - } - return accessibilityNodeInfos.get(position); - } - } - if (callBack != null) { - callBack.fail(); - } - return null; - } - - public static AccessibilityNodeInfo findById( - AccessibilityNodeInfo parent, - String id, - int position - ) { - return findById(parent, id, position, null); - } - - public static AccessibilityNodeInfo findById(String id, int position) { - return findById(AblService.getInstance().getRootInActiveWindow(), id, position, null); - } - - public static AccessibilityNodeInfo findById(String id, int position, AniCallBack callBack) { - return findById(AblService.getInstance().getRootInActiveWindow(), id, position, callBack); - } - - public static List findById( - AccessibilityNodeInfo parent, - String id, - @Nullable AnisCallBack anisCallBack - ) { - if (parent != null) { - List accessibilityNodeInfos = - parent.findAccessibilityNodeInfosByViewId(id); - if (accessibilityNodeInfos != null && - !accessibilityNodeInfos.isEmpty()) { - if (anisCallBack != null) { - anisCallBack.succ(accessibilityNodeInfos); - } - return accessibilityNodeInfos; - } - } - if (anisCallBack != null) { - anisCallBack.fail(); - } - return new ArrayList<>(); - } - - public static List findById( - AccessibilityNodeInfo parent, - String id - ) { - return findById(parent, id, null); - } - - public static List findById(String id) { - return findById(AblService.getInstance().getRootInActiveWindow(), id, null); - } - - public static List findById(String id, AnisCallBack anisCallBack) { - return findById(AblService.getInstance().getRootInActiveWindow(), id, anisCallBack); - } - - /** - * 根据文本获取view - * - * @param parent - * @param text - * @param position - * @return - */ - public static AccessibilityNodeInfo findByText(AccessibilityNodeInfo parent, String text, int position) { - if (parent != null) { - List accessibilityNodeInfos = - parent.findAccessibilityNodeInfosByText(text); - if (accessibilityNodeInfos != null && - !accessibilityNodeInfos.isEmpty() && - position < accessibilityNodeInfos.size()) { - return accessibilityNodeInfos.get(position); - } - } - return null; - } - - public static AccessibilityNodeInfo findByText(String text, int position) { - return findByText(AblService.getInstance().getRootInActiveWindow(), text, position); - } - - public static List findByText(AccessibilityNodeInfo parent, String text) { - if (parent != null) { - List accessibilityNodeInfos = - parent.findAccessibilityNodeInfosByText(text); - if (accessibilityNodeInfos != null && - !accessibilityNodeInfos.isEmpty()) { - return accessibilityNodeInfos; - } - } - return new ArrayList<>(); - } - - public static List findByText(String text) { - return findByText(AblService.getInstance().getRootInActiveWindow(), text); - } - - /** - * 手势模拟 - * - * @param start_position 开始位置,长度为2的数组,下标0为x轴,下标1为y轴 - * @param end_position - * @param startTime 开始间隔时间 - * @param duration 持续时间 - * @param callback 回调 - */ - @TargetApi(Build.VERSION_CODES.N) - public static void dispatch_gesture( - float[] start_position, - float[] end_position, - long startTime, - long duration, - @Nullable GestureCallBack callback - ) { - Path path = new Path(); - path.moveTo(start_position[0], start_position[1]); - path.lineTo(end_position[0], end_position[1]); - GestureDescription.Builder builder = new GestureDescription.Builder(); - GestureDescription.StrokeDescription strokeDescription = - new GestureDescription.StrokeDescription(path, startTime, duration); - GestureDescription gestureDescription = builder.addStroke(strokeDescription).build(); - AblService.getInstance().dispatchGesture(gestureDescription, new AccessibilityService.GestureResultCallback() { - @Override - public void onCompleted(GestureDescription gestureDescription) { - if (callback != null) { - callback.succ(gestureDescription); - } - } - - @Override - public void onCancelled(GestureDescription gestureDescription) { - if (callback != null) { - callback.fail(gestureDescription); - } - } - }, null); - } - - /** - * x轴居中竖直滑动屏幕 - * - * @param yRatio y轴份数 - * @param startSlideRatio y轴开始的份数 - * @param stopSlideRatio y轴结束的份数 - */ - public static void scrollVertical( - int yRatio, - int startSlideRatio, - int stopSlideRatio, - long startTime, - long duration, - @Nullable GestureCallBack callback - ) { - int screenHeight = ScreenUtils.getScreenHeight(); - int screenWidth = ScreenUtils.getScreenWidth(); - int start = (screenHeight / yRatio) * startSlideRatio; - int stop = (screenHeight / yRatio) * stopSlideRatio; - dispatch_gesture( - new float[]{screenWidth >> 1, start}, - new float[]{screenWidth >> 1, stop}, - startTime, - duration, - callback - ); - - } - - /** - * 竖直滑动,y轴分为20份 - * - * @param startSlideRatio 开始份数 - * @param stopSlideRatio 结束份数 - */ - public static void scrollVertical( - int startSlideRatio, - int stopSlideRatio - ) { - int screenHeight = ScreenUtils.getScreenHeight(); - int screenWidth = ScreenUtils.getScreenWidth(); - int start = (screenHeight / 20) * startSlideRatio; - int stop = (screenHeight / 20) * stopSlideRatio; - dispatch_gesture( - new float[]{screenWidth >> 1, start}, - new float[]{screenWidth >> 1, stop}, - 50, - 500, - null - ); - - } - - - /** - * x轴居中竖直滑动屏幕 - * - * @param startY y轴开始位置 - * @param stopY y轴结束位置 - */ - public static void scrollVertical( - float startY, - float stopY, - long startTime, - long duration, - @Nullable GestureCallBack callback - ) { - int screenWidth = ScreenUtils.getScreenWidth(); - dispatch_gesture( - new float[]{screenWidth >> 1, startY}, - new float[]{screenWidth >> 1, stopY}, - startTime, - duration, - callback - ); - - } - - - /** - * y轴居中横向滑动 - * - * @param xRatio x轴份数 - * @param startSlideRatio x轴开始滑动份数 - * @param stopSlideRatio x轴结束滑动份数 - * @param startTime 开始延迟时间 - * @param duration 滑动持续时间 - * @param callback 回调 - */ - public void scrollHorizontal( - int xRatio, - int startSlideRatio, - int stopSlideRatio, - long startTime, - long duration, - @Nullable GestureCallBack callback - ) { - int screenHeight = ScreenUtils.getScreenHeight(); - int screenWidth = ScreenUtils.getScreenWidth(); - int start = (screenWidth / xRatio) * startSlideRatio; - int stop = (screenWidth / xRatio) * stopSlideRatio; - dispatch_gesture( - new float[]{start, screenHeight >> 1}, - new float[]{stop, screenHeight >> 1}, - startTime, - duration, - callback - ); - } - - /** - * y轴居中横向滑动 - * - * @param startX x轴开始位置 - * @param stopX x轴结束位置 - * @param startTime 开始延迟时间 - * @param duration 滑动持续时间 - * @param callback 回调 - */ - public static void scrollHorizontal( - int startX, - int stopX, - long startTime, - long duration, - @Nullable GestureCallBack callback - ) { - int screenHeight = ScreenUtils.getScreenHeight(); - dispatch_gesture( - new float[]{startX, screenHeight >> 1}, - new float[]{stopX, screenHeight >> 1}, - startTime, - duration, - callback - ); - } - - /** - * 点击屏幕 - * - * @param ratio 屏幕长宽份数 - * @param xRatio 屏幕宽ratio份的比例 - * @param yRatio - */ - public static void clickScreen( - int ratio, - int xRatio, - int yRatio, - @Nullable GestureCallBack callback - ) { - int screenHeight = ScreenUtils.getScreenHeight(); - int screenWidth = ScreenUtils.getScreenWidth(); - int y = (screenHeight / ratio) * yRatio; - int x = (screenWidth / ratio) * xRatio; - dispatch_gesture( - new float[]{x, y}, - new float[]{x, y}, - 100, - 50, - callback - ); - } - - /** - * 点击屏幕 - */ - public static void clickScreen( - int xRatio, - int yRatio - ) { - int screenHeight = ScreenUtils.getScreenHeight(); - int screenWidth = ScreenUtils.getScreenWidth(); - int y = (screenHeight / 20) * yRatio; - int x = (screenWidth / 20) * xRatio; - dispatch_gesture( - new float[]{x, y}, - new float[]{x, y}, - 100, - 100, - null - ); - } - - /** - * 点击屏幕 - * - * @param x x轴像素 - * @param y - * @param startTime 开始间隔时间 - * @param duration 持续时间 - */ - public static void clickScreen( - float x, - float y, - long startTime, - long duration, - @Nullable GestureCallBack callback - ) { - dispatch_gesture( - new float[]{x, y}, - new float[]{x, y}, - startTime, - duration, - callback - ); - } - - /** - * 返回 - */ - public static void back() { - AblService.getInstance().performGlobalAction(GLOBAL_ACTION_BACK); - } - - - /** - * 黏贴文本至view - * - * @param info - * @param text - */ - public static void paste(AccessibilityNodeInfo info, String text) { - ClipData clip = ClipData.newPlainText(System.currentTimeMillis() + "", text); - ClipboardManager clipboardManager = (ClipboardManager) AblService.getInstance().getSystemService(CLIPBOARD_SERVICE); - assert clipboardManager != null; - clipboardManager.setPrimaryClip(clip); - ClipData abc = clipboardManager.getPrimaryClip(); - assert abc != null; - ClipData.Item item = abc.getItemAt(0); - if (info != null) info.performAction(AccessibilityNodeInfo.ACTION_PASTE); - } - - - /** - * 具体的说话方法 - * - * @param text - * @param node - */ - public static void sayInput(String text, AccessibilityNodeInfo node) { - if(node!=null) { - if ("android.widget.EditText".equals(node.getClassName())) { - Log.e("TIAOSHI###", "要说的话:.." + text); - Bundle arguments = new Bundle(); - arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text); - node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments); - } - } - - } - - /** - * 判断当前页面是否包含某文本 - */ - public static boolean isContainText(String str) { - boolean flag = false; - List nodeInfos = AblViewUtil.findByText(str); - for (int i=0;i0&&rect.top>0&&rect.top<=2210&&rect.bottom>0&&rect.bottom<=2210&&rect.right<1080) { - Log.e("TIAOSHI###", "----twoNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); - nodeZuobiao(child); - flag = true; - } - } - return flag; - } - - /** - * 根据范围获和输入的文本获取节点 - */ - public static AccessibilityNodeInfo getNodeInfo(String str) { - AccessibilityNodeInfo nodeInfo = null; - List nodeInfos = AblViewUtil.findByText(str); - for (int i=0;i0&&rect.top>2000&&rect.top<=2210&&rect.bottom>0&&rect.bottom<=2210&&rect.right<1080) { - Log.e("TIAOSHI###", "----twoNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); - nodeZuobiao(child); - nodeInfo = child; - } - } - return nodeInfo; - } - - /** - * 查看节点的坐标点 - */ - public static void nodeZuobiao(AccessibilityNodeInfo nodeinfo){ - Rect rect = new Rect(); - nodeinfo.getBoundsInScreen(rect); - Log.e("TIAOSHI###", "----显示节点的坐标:" + "(" + rect.left + "," + rect.top + ")" + "," + "(" + rect.right + "," + rect.bottom + ")"); - - } - - /** - * @param - * @return - * @description 开启app - */ - @RequiresApi(api = Build.VERSION_CODES.N) - public static void startApplication() { - startApplicationtwo(FuzhuApplication.getContext(), "com.ss.android.ugc.aweme"); - } - - public static void startApplicationtwo(Context ctx, String pkName) { - PackageManager packageManager = ctx.getPackageManager(); - Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); - resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); - resolveIntent.setPackage(pkName); - List apps = packageManager.queryIntentActivities(resolveIntent, 0); - ResolveInfo ri = apps.iterator().next(); - if (ri != null) { - String packageName = ri.activityInfo.packageName; - String className = ri.activityInfo.name; - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - ComponentName cn = new ComponentName(packageName, className); - intent.setComponent(cn); - ctx.startActivity(intent); - } - } - - - public static void mySleep(int i) { - try { - Thread.sleep(i * 1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - - /** - * @param nikename 方法内字符串变量 - * @param child1 - * @param numt 上坐标点 - * @param numb 下坐标点 - * @param numl 左坐标点 - * @param numr 右坐标点 - * @param classStr 节点的包名 - * @return - */ - public static String getString(String nikename, AccessibilityNodeInfo child1, int numt, int numb, int numl, int numr, String classStr) { - Rect rect = new Rect(); - child1.getBoundsInScreen(rect); - if (rect.top >= numt && rect.bottom <= numb&&rect.left>=numl&&rect.right<=numr) { - Log.e("TIAOSHI###", "----RectNode:" + child1.getClassName() + ":" + child1.getText() + ":" + child1.getContentDescription()); - if (classStr.equals(child1.getClassName())) { - if (child1.getText() != null) { - nikename = child1.getText().toString(); - } - } - } - return nikename; - } - - - public void rigist(InfoMessage infoMessag){ - this.infoMessag=infoMessag; - } - public static void onMessage(String str){ - infoMessag.mesagesuccess(str); - } - - public static void zhuanghaoMessage(String str){ - infoMessag.mesagezhuang(str); - } - - public static void potfinish(String id,String str,String type){ - infoMessag.potfinish(id,str,type); - } - public static void potgegin(String str){ - infoMessag.potgegin(str); - } - - - /** - * 跳过广告 - */ - public static void Skip(){ - List nodeInfoList = AblService.getInstance().getRootInActiveWindow().findAccessibilityNodeInfosByText("跳过"); - for (AccessibilityNodeInfo info : nodeInfoList) { - CharSequence charSequence = info.getText(); - if (charSequence != null) { - String msg = charSequence.toString(); - if (msg.contains("跳过")) { - info.performAction(AccessibilityNodeInfo.ACTION_CLICK); - } - } - } - } - - /** - * 关闭弹窗 - */ - public static void Close(){ - if (isContainText("青少年模式")){ - findAndPerformActionTextView("我知道了"); - } - if (isContainText("获取设备的定位信息")){ - findAndPerformActionTextView("仅在使用中允许"); - } - if (isContainText("检测到更新")){ - findAndPerformActionTextView("以后再说"); - } - if (isContainText("发现通讯录朋友")){ - findAndPerformActionTextView("暂时不要"); - } - Log.e("_____-------","弹窗解决"); - } - - - /** - * - * @param text - * 根据文本寻找控件节点 - */ - public static void findAndPerformActionTextView(String text) { - if (AblService.getInstance().getRootInActiveWindow() == null) { - return; - } - List node = AblService.getInstance().getRootInActiveWindow().findAccessibilityNodeInfosByText(text); - for ( int i = 0; i < node.size(); i++ ){ - AccessibilityNodeInfo nodeInfo = (AccessibilityNodeInfo) node.get(i); - if (nodeInfo != null && nodeInfo.isEnabled()){ - performViewClick(nodeInfo); - } - } - } - /** - * 模拟点击事件,如果该node不能点击,则点击父node,将点击事件一直向父级传递,直至到根node或者找到一个可以点击的node - * - * @param nodeInfo nodeInfo - */ - public static void performViewClick(AccessibilityNodeInfo nodeInfo) { - if (nodeInfo == null) { - return; - } else { - while (nodeInfo != null) { - if (nodeInfo.isClickable()) { - nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); - break; - } - nodeInfo = nodeInfo.getParent(); - } - } - } -} +package com.fisherbone.fuzhu.abllib.utils; + +import android.accessibilityservice.AccessibilityService; +import android.accessibilityservice.GestureDescription; +import android.annotation.TargetApi; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.Path; +import android.graphics.Rect; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; + +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; + +import com.blankj.utilcode.util.ScreenUtils; +import com.fisherbone.fuzhu.FuzhuApplication; +import com.fisherbone.fuzhu.InfoMessage; +import com.fisherbone.fuzhu.abllib.AblService; +import com.fisherbone.fuzhu.abllib.callback.AniCallBack; +import com.fisherbone.fuzhu.abllib.callback.AnisCallBack; +import com.fisherbone.fuzhu.abllib.callback.GestureCallBack; + +import java.util.ArrayList; +import java.util.List; + +import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_BACK; +import static android.content.Context.CLIPBOARD_SERVICE; + +/** + * 界面操作工具类 + * wechat 1483232332 + */ +public class AblViewUtil { + private static InfoMessage infoMessag; + /** + * 根据id获取view + * + * @param parent + * @param id 界面id + * @param position + * @return + */ + public static AccessibilityNodeInfo findById( + AccessibilityNodeInfo parent, + String id, + int position, + @Nullable AniCallBack callBack + ) { + if (parent != null) { + List accessibilityNodeInfos = + parent.findAccessibilityNodeInfosByViewId(id); + if (accessibilityNodeInfos != null && + !accessibilityNodeInfos.isEmpty() && + position < accessibilityNodeInfos.size()) { + if (callBack != null) { + callBack.succ(accessibilityNodeInfos.get(position)); + } + return accessibilityNodeInfos.get(position); + } + } + if (callBack != null) { + callBack.fail(); + } + return null; + } + + public static AccessibilityNodeInfo findById( + AccessibilityNodeInfo parent, + String id, + int position + ) { + return findById(parent, id, position, null); + } + + public static AccessibilityNodeInfo findById(String id, int position) { + return findById(AblService.getInstance().getRootInActiveWindow(), id, position, null); + } + + public static AccessibilityNodeInfo findById(String id, int position, AniCallBack callBack) { + return findById(AblService.getInstance().getRootInActiveWindow(), id, position, callBack); + } + + public static List findById( + AccessibilityNodeInfo parent, + String id, + @Nullable AnisCallBack anisCallBack + ) { + if (parent != null) { + List accessibilityNodeInfos = + parent.findAccessibilityNodeInfosByViewId(id); + if (accessibilityNodeInfos != null && + !accessibilityNodeInfos.isEmpty()) { + if (anisCallBack != null) { + anisCallBack.succ(accessibilityNodeInfos); + } + return accessibilityNodeInfos; + } + } + if (anisCallBack != null) { + anisCallBack.fail(); + } + return new ArrayList<>(); + } + + public static List findById( + AccessibilityNodeInfo parent, + String id + ) { + return findById(parent, id, null); + } + + public static List findById(String id) { + return findById(AblService.getInstance().getRootInActiveWindow(), id, null); + } + + public static List findById(String id, AnisCallBack anisCallBack) { + return findById(AblService.getInstance().getRootInActiveWindow(), id, anisCallBack); + } + + /** + * 根据文本获取view + * + * @param parent + * @param text + * @param position + * @return + */ + public static AccessibilityNodeInfo findByText(AccessibilityNodeInfo parent, String text, int position) { + if (parent != null) { + List accessibilityNodeInfos = + parent.findAccessibilityNodeInfosByText(text); + if (accessibilityNodeInfos != null && + !accessibilityNodeInfos.isEmpty() && + position < accessibilityNodeInfos.size()) { + return accessibilityNodeInfos.get(position); + } + } + return null; + } + + public static AccessibilityNodeInfo findByText(String text, int position) { + return findByText(AblService.getInstance().getRootInActiveWindow(), text, position); + } + + public static List findByText(AccessibilityNodeInfo parent, String text) { + if (parent != null) { + List accessibilityNodeInfos = + parent.findAccessibilityNodeInfosByText(text); + if (accessibilityNodeInfos != null && + !accessibilityNodeInfos.isEmpty()) { + return accessibilityNodeInfos; + } + } + return new ArrayList<>(); + } + + public static List findByText(String text) { + return findByText(AblService.getInstance().getRootInActiveWindow(), text); + } + + /** + * 手势模拟 + * + * @param start_position 开始位置,长度为2的数组,下标0为x轴,下标1为y轴 + * @param end_position + * @param startTime 开始间隔时间 + * @param duration 持续时间 + * @param callback 回调 + */ + @TargetApi(Build.VERSION_CODES.N) + public static void dispatch_gesture( + float[] start_position, + float[] end_position, + long startTime, + long duration, + @Nullable GestureCallBack callback + ) { + Path path = new Path(); + path.moveTo(start_position[0], start_position[1]); + path.lineTo(end_position[0], end_position[1]); + GestureDescription.Builder builder = new GestureDescription.Builder(); + GestureDescription.StrokeDescription strokeDescription = + new GestureDescription.StrokeDescription(path, startTime, duration); + GestureDescription gestureDescription = builder.addStroke(strokeDescription).build(); + AblService.getInstance().dispatchGesture(gestureDescription, new AccessibilityService.GestureResultCallback() { + @Override + public void onCompleted(GestureDescription gestureDescription) { + if (callback != null) { + callback.succ(gestureDescription); + } + } + + @Override + public void onCancelled(GestureDescription gestureDescription) { + if (callback != null) { + callback.fail(gestureDescription); + } + } + }, null); + } + + /** + * x轴居中竖直滑动屏幕 + * + * @param yRatio y轴份数 + * @param startSlideRatio y轴开始的份数 + * @param stopSlideRatio y轴结束的份数 + */ + public static void scrollVertical( + int yRatio, + int startSlideRatio, + int stopSlideRatio, + long startTime, + long duration, + @Nullable GestureCallBack callback + ) { + int screenHeight = ScreenUtils.getScreenHeight(); + int screenWidth = ScreenUtils.getScreenWidth(); + int start = (screenHeight / yRatio) * startSlideRatio; + int stop = (screenHeight / yRatio) * stopSlideRatio; + dispatch_gesture( + new float[]{screenWidth >> 1, start}, + new float[]{screenWidth >> 1, stop}, + startTime, + duration, + callback + ); + + } + + /** + * 竖直滑动,y轴分为20份 + * + * @param startSlideRatio 开始份数 + * @param stopSlideRatio 结束份数 + */ + public static void scrollVertical( + int startSlideRatio, + int stopSlideRatio + ) { + int screenHeight = ScreenUtils.getScreenHeight(); + int screenWidth = ScreenUtils.getScreenWidth(); + int start = (screenHeight / 20) * startSlideRatio; + int stop = (screenHeight / 20) * stopSlideRatio; + dispatch_gesture( + new float[]{screenWidth >> 1, start}, + new float[]{screenWidth >> 1, stop}, + 50, + 500, + null + ); + + } + + + /** + * x轴居中竖直滑动屏幕 + * + * @param startY y轴开始位置 + * @param stopY y轴结束位置 + */ + public static void scrollVertical( + float startY, + float stopY, + long startTime, + long duration, + @Nullable GestureCallBack callback + ) { + int screenWidth = ScreenUtils.getScreenWidth(); + dispatch_gesture( + new float[]{screenWidth >> 1, startY}, + new float[]{screenWidth >> 1, stopY}, + startTime, + duration, + callback + ); + + } + + + /** + * y轴居中横向滑动 + * + * @param xRatio x轴份数 + * @param startSlideRatio x轴开始滑动份数 + * @param stopSlideRatio x轴结束滑动份数 + * @param startTime 开始延迟时间 + * @param duration 滑动持续时间 + * @param callback 回调 + */ + public void scrollHorizontal( + int xRatio, + int startSlideRatio, + int stopSlideRatio, + long startTime, + long duration, + @Nullable GestureCallBack callback + ) { + int screenHeight = ScreenUtils.getScreenHeight(); + int screenWidth = ScreenUtils.getScreenWidth(); + int start = (screenWidth / xRatio) * startSlideRatio; + int stop = (screenWidth / xRatio) * stopSlideRatio; + dispatch_gesture( + new float[]{start, screenHeight >> 1}, + new float[]{stop, screenHeight >> 1}, + startTime, + duration, + callback + ); + } + + /** + * y轴居中横向滑动 + * + * @param startX x轴开始位置 + * @param stopX x轴结束位置 + * @param startTime 开始延迟时间 + * @param duration 滑动持续时间 + * @param callback 回调 + */ + public static void scrollHorizontal( + int startX, + int stopX, + long startTime, + long duration, + @Nullable GestureCallBack callback + ) { + int screenHeight = ScreenUtils.getScreenHeight(); + dispatch_gesture( + new float[]{startX, screenHeight >> 1}, + new float[]{stopX, screenHeight >> 1}, + startTime, + duration, + callback + ); + } + + /** + * 点击屏幕 + * + * @param ratio 屏幕长宽份数 + * @param xRatio 屏幕宽ratio份的比例 + * @param yRatio + */ + public static void clickScreen( + int ratio, + int xRatio, + int yRatio, + @Nullable GestureCallBack callback + ) { + int screenHeight = ScreenUtils.getScreenHeight(); + int screenWidth = ScreenUtils.getScreenWidth(); + int y = (screenHeight / ratio) * yRatio; + int x = (screenWidth / ratio) * xRatio; + dispatch_gesture( + new float[]{x, y}, + new float[]{x, y}, + 100, + 50, + callback + ); + } + + /** + * 点击屏幕 + */ + public static void clickScreen( + int xRatio, + int yRatio + ) { + int screenHeight = ScreenUtils.getScreenHeight(); + int screenWidth = ScreenUtils.getScreenWidth(); + int y = (screenHeight / 20) * yRatio; + int x = (screenWidth / 20) * xRatio; + dispatch_gesture( + new float[]{x, y}, + new float[]{x, y}, + 100, + 100, + null + ); + } + + /** + * 点击屏幕 + * + * @param x x轴像素 + * @param y + * @param startTime 开始间隔时间 + * @param duration 持续时间 + */ + public static void clickScreen( + float x, + float y, + long startTime, + long duration, + @Nullable GestureCallBack callback + ) { + dispatch_gesture( + new float[]{x, y}, + new float[]{x, y}, + startTime, + duration, + callback + ); + } + + /** + * 返回 + */ + public static void back() { + AblService.getInstance().performGlobalAction(GLOBAL_ACTION_BACK); + } + + + /** + * 黏贴文本至view + * + * @param info + * @param text + */ + public static void paste(AccessibilityNodeInfo info, String text) { + ClipData clip = ClipData.newPlainText(System.currentTimeMillis() + "", text); + ClipboardManager clipboardManager = (ClipboardManager) AblService.getInstance().getSystemService(CLIPBOARD_SERVICE); + assert clipboardManager != null; + clipboardManager.setPrimaryClip(clip); + ClipData abc = clipboardManager.getPrimaryClip(); + assert abc != null; + ClipData.Item item = abc.getItemAt(0); + if (info != null) info.performAction(AccessibilityNodeInfo.ACTION_PASTE); + } + + + /** + * 具体的说话方法 + * + * @param text + * @param node + */ + public static void sayInput(String text, AccessibilityNodeInfo node) { + if(node!=null) { + if ("android.widget.EditText".equals(node.getClassName())) { + Log.e("TIAOSHI###", "要说的话:.." + text); + Bundle arguments = new Bundle(); + arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text); + node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments); + } + } + + } + + /** + * 判断当前页面是否包含某文本 + */ + public static boolean isContainText(String str) { + boolean flag = false; + List nodeInfos = AblViewUtil.findByText(str); + for (int i=0;i0&&rect.top>0&&rect.top<=2210&&rect.bottom>0&&rect.bottom<=2210&&rect.right<1080) { + Log.e("TIAOSHI###", "----twoNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); + nodeZuobiao(child); + flag = true; + } + } + return flag; + } + + /** + * 根据范围获和输入的文本获取节点 + */ + public static AccessibilityNodeInfo getNodeInfo(String str) { + AccessibilityNodeInfo nodeInfo = null; + List nodeInfos = AblViewUtil.findByText(str); + for (int i=0;i0&&rect.top>2000&&rect.top<=2210&&rect.bottom>0&&rect.bottom<=2210&&rect.right<1080) { + Log.e("TIAOSHI###", "----twoNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); + nodeZuobiao(child); + nodeInfo = child; + } + } + return nodeInfo; + } + + /** + * 查看节点的坐标点 + */ + public static void nodeZuobiao(AccessibilityNodeInfo nodeinfo){ + Rect rect = new Rect(); + nodeinfo.getBoundsInScreen(rect); + Log.e("TIAOSHI###", "----显示节点的坐标:" + "(" + rect.left + "," + rect.top + ")" + "," + "(" + rect.right + "," + rect.bottom + ")"); + + } + + /** + * @param + * @return + * @description 开启app + */ + @RequiresApi(api = Build.VERSION_CODES.N) + public static void startApplication() { + startApplicationtwo(FuzhuApplication.getContext(), "com.ss.android.ugc.aweme"); + } + + public static void startApplicationtwo(Context ctx, String pkName) { + PackageManager packageManager = ctx.getPackageManager(); + Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); + resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); + resolveIntent.setPackage(pkName); + List apps = packageManager.queryIntentActivities(resolveIntent, 0); + + // 检查应用是否已安装 + if (apps == null || apps.isEmpty()) { + throw new RuntimeException("应用未安装: " + pkName); + } + + ResolveInfo ri = apps.iterator().next(); + if (ri != null && ri.activityInfo != null) { + String packageName = ri.activityInfo.packageName; + String className = ri.activityInfo.name; + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + ComponentName cn = new ComponentName(packageName, className); + intent.setComponent(cn); + ctx.startActivity(intent); + } else { + throw new RuntimeException("无法获取应用启动信息: " + pkName); + } + } + + + public static void mySleep(int i) { + try { + Thread.sleep(i * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + + /** + * @param nikename 方法内字符串变量 + * @param child1 + * @param numt 上坐标点 + * @param numb 下坐标点 + * @param numl 左坐标点 + * @param numr 右坐标点 + * @param classStr 节点的包名 + * @return + */ + public static String getString(String nikename, AccessibilityNodeInfo child1, int numt, int numb, int numl, int numr, String classStr) { + Rect rect = new Rect(); + child1.getBoundsInScreen(rect); + if (rect.top >= numt && rect.bottom <= numb&&rect.left>=numl&&rect.right<=numr) { + Log.e("TIAOSHI###", "----RectNode:" + child1.getClassName() + ":" + child1.getText() + ":" + child1.getContentDescription()); + if (classStr.equals(child1.getClassName())) { + if (child1.getText() != null) { + nikename = child1.getText().toString(); + } + } + } + return nikename; + } + + + public void rigist(InfoMessage infoMessag){ + this.infoMessag=infoMessag; + } + public static void onMessage(String str){ + infoMessag.mesagesuccess(str); + } + + public static void zhuanghaoMessage(String str){ + infoMessag.mesagezhuang(str); + } + + public static void potfinish(String id,String str,String type){ + infoMessag.potfinish(id,str,type); + } + public static void potgegin(String str){ + infoMessag.potgegin(str); + } + + + /** + * 跳过广告 + */ + public static void Skip(){ + List nodeInfoList = AblService.getInstance().getRootInActiveWindow().findAccessibilityNodeInfosByText("跳过"); + for (AccessibilityNodeInfo info : nodeInfoList) { + CharSequence charSequence = info.getText(); + if (charSequence != null) { + String msg = charSequence.toString(); + if (msg.contains("跳过")) { + info.performAction(AccessibilityNodeInfo.ACTION_CLICK); + } + } + } + } + + /** + * 关闭弹窗 + */ + public static void Close(){ + if (isContainText("青少年模式")){ + findAndPerformActionTextView("我知道了"); + } + if (isContainText("获取设备的定位信息")){ + findAndPerformActionTextView("仅在使用中允许"); + } + if (isContainText("检测到更新")){ + findAndPerformActionTextView("以后再说"); + } + if (isContainText("发现通讯录朋友")){ + findAndPerformActionTextView("暂时不要"); + } + Log.e("_____-------","弹窗解决"); + } + + + /** + * + * @param text + * 根据文本寻找控件节点 + */ + public static void findAndPerformActionTextView(String text) { + if (AblService.getInstance().getRootInActiveWindow() == null) { + return; + } + List node = AblService.getInstance().getRootInActiveWindow().findAccessibilityNodeInfosByText(text); + for ( int i = 0; i < node.size(); i++ ){ + AccessibilityNodeInfo nodeInfo = (AccessibilityNodeInfo) node.get(i); + if (nodeInfo != null && nodeInfo.isEnabled()){ + performViewClick(nodeInfo); + } + } + } + /** + * 模拟点击事件,如果该node不能点击,则点击父node,将点击事件一直向父级传递,直至到根node或者找到一个可以点击的node + * + * @param nodeInfo nodeInfo + */ + public static void performViewClick(AccessibilityNodeInfo nodeInfo) { + if (nodeInfo == null) { + return; + } else { + while (nodeInfo != null) { + if (nodeInfo.isClickable()) { + nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); + break; + } + nodeInfo = nodeInfo.getParent(); + } + } + } +} diff --git a/app/src/main/java/com/fisherbone/fuzhu/activity/MainActivity.java b/app/src/main/java/com/fisherbone/fuzhu/activity/MainActivity.java index 5c32aed..ca49177 100644 --- a/app/src/main/java/com/fisherbone/fuzhu/activity/MainActivity.java +++ b/app/src/main/java/com/fisherbone/fuzhu/activity/MainActivity.java @@ -11,6 +11,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -18,13 +19,16 @@ import android.os.Handler; import android.os.IBinder; import android.provider.Settings; import android.util.Log; +import android.view.Gravity; import android.view.View; +import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; import android.widget.PopupWindow; import android.widget.TextView; import android.widget.Toast; import com.blankj.utilcode.util.ToastUtils; +import com.fisherbone.fuzhu.step.DingDingDakaStep; import com.fisherbone.fuzhu.utils.SafeToastUtils; import com.fisherbone.fuzhu.BaseActivity; import com.derry.wechat.debug.BuildConfig; @@ -231,72 +235,85 @@ public class MainActivity extends BaseActivity implements InfoMessage { ChangLiang.isstart = "0"; ChangLiang.isstarttwo = "0"; controlWindow = new ControlWindow(MainActivity.this); - LiveEventBus.get("some_key", String.class).observe(this, new Observerlife() { - @Override - public void onChanged(Object o) { - controlWindow.showRunInfo((String) o); + + // LiveEventBus 1.7.3 在 Android 12+ 上有兼容性问题,静态初始化时会崩溃 + // 在 Android 12+ 上完全禁用 LiveEventBus,避免应用崩溃 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + // Android 12 以下正常使用 LiveEventBus + try { + LiveEventBus.get("some_key", String.class).observe(this, new Observerlife() { + @Override + public void onChanged(Object o) { + controlWindow.showRunInfo((String) o); + } + }); + LiveEventBus.get("run_time", String.class).observe(this, new Observerlife() { + @Override + public void onChanged(Object o) { + controlWindow.showRunTimeInfo((String) o); + } + }); + LiveEventBus.get("success", String.class).observe(this, new Observerlife() { + @Override + public void onChanged(Object o) { + Log.e("TIAOSHI###", "getcontrolStatus==执行了"); + getcontrolStatus(); + } + }); + LiveEventBus.get("ablservice", String.class).observe(this, new Observerlife() { + @Override + public void onChanged(Object o) { + tvShowInfo.setText((String)o); + if("无障碍服务被销毁".equals((String)o)){ + againStart("0"); + } + } + }); + LiveEventBus.get("jiaguantime", String.class).observe(this, new Observerlife() { + @Override + public void onChanged(Object o) { + Log.w("TIAOSHI###运行时长", (String) o); + //开启运行倒计时 + daojishitwo(Integer.parseInt((String) o)); + } + }); + LiveEventBus.get("closedtime", String.class).observe(this, new Observerlife() { + @Override + public void onChanged(Object o) { + if(mdDisposable!=null) { + mdDisposable.dispose(); + } + } + }); + LiveEventBus.get("runningstate", String.class).observe(this, new Observerlife() { + @Override + public void onChanged(Object o) { + againStart((String) o); + } + }); + LiveEventBus.get("yunkong", String.class).observe(this, new Observerlife() { + @Override + public void onChanged(Object o) { + if("open".equals((String) o)){ + }else { + closeService(); + } + } + }); + LiveEventBus.get("task_runtime", MessageBean.class).observe(this, new Observerlife() { + @Override + public void onChanged(Object o) { + MessageBean mesg = (MessageBean) o; + taskDaojishi(mesg.getRuntime(),mesg); + } + }); + } catch (Exception e) { + Log.e("MainActivity", "LiveEventBus 初始化失败", e); } - }); - LiveEventBus.get("run_time", String.class).observe(this, new Observerlife() { - @Override - public void onChanged(Object o) { - controlWindow.showRunTimeInfo((String) o); - } - }); - LiveEventBus.get("success", String.class).observe(this, new Observerlife() { - @Override - public void onChanged(Object o) { - Log.e("TIAOSHI###", "getcontrolStatus==执行了"); - getcontrolStatus(); - } - }); - LiveEventBus.get("ablservice", String.class).observe(this, new Observerlife() { - @Override - public void onChanged(Object o) { - tvShowInfo.setText((String)o); - if("无障碍服务被销毁".equals((String)o)){ - againStart("0"); - } - } - }); - LiveEventBus.get("jiaguantime", String.class).observe(this, new Observerlife() { - @Override - public void onChanged(Object o) { - Log.w("TIAOSHI###运行时长", (String) o); - //开启运行倒计时 - daojishitwo(Integer.parseInt((String) o)); - } - }); - LiveEventBus.get("closedtime", String.class).observe(this, new Observerlife() { - @Override - public void onChanged(Object o) { - if(mdDisposable!=null) { - mdDisposable.dispose(); - } - } - }); - LiveEventBus.get("runningstate", String.class).observe(this, new Observerlife() { - @Override - public void onChanged(Object o) { - againStart((String) o); - } - }); - LiveEventBus.get("yunkong", String.class).observe(this, new Observerlife() { - @Override - public void onChanged(Object o) { - if("open".equals((String) o)){ - }else { - closeService(); - } - } - }); - LiveEventBus.get("task_runtime", MessageBean.class).observe(this, new Observerlife() { - @Override - public void onChanged(Object o) { - MessageBean mesg = (MessageBean) o; - taskDaojishi(mesg.getRuntime(),mesg); - } - }); + } else { + // Android 12+ 上禁用 LiveEventBus,避免静态初始化崩溃 + Log.w("MainActivity", "Android 12+ 上已禁用 LiveEventBus(兼容性问题),相关功能可能不可用"); + } InjectUtils.injectEvent(this); requestVersion(); @@ -323,7 +340,7 @@ public class MainActivity extends BaseActivity implements InfoMessage { .setFindViewMillisInFuture(10000)//寻找界面超时时间 .setFindViewCountDownInterval(200)//寻找界面间隔时间 .build().init(); - AblStepHandler.getInstance().initStepClass(new TestAblStep0(), new TestAblStep1(), new TestAblStep2(), new TestAblStep8(), new TestAblStep9(), new TestAblStep10(), new TestAblStep12(), new TestAblStep13(), new TestAblStep18(), new TestAblStep19(), new TestAblStep23(), new TestAblStep25(), new TestAblStep26(), new TestAblStep27(), new TestAblStep28(), new TestAblStep29(), new TestAblStep31(), new TestAblStep32(), new TestAblStep33()); + AblStepHandler.getInstance().initStepClass(new TestAblStep0(), new TestAblStep1(), new TestAblStep2(), new TestAblStep8(), new TestAblStep9(), new TestAblStep10(), new TestAblStep12(), new TestAblStep13(), new TestAblStep18(), new TestAblStep19(), new TestAblStep23(), new TestAblStep25(), new TestAblStep26(), new TestAblStep27(), new TestAblStep28(), new TestAblStep29(), new TestAblStep31(), new TestAblStep32(), new TestAblStep33(),new DingDingDakaStep()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.READ_CONTACTS); if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) { @@ -369,7 +386,7 @@ public class MainActivity extends BaseActivity implements InfoMessage { } - @OnClickk({R.id.rl_05, R.id.rl_12, R.id.rl_011, R.id.rl_10, R.id.rl_09, R.id.rl_08, R.id.rl_07, R.id.rl_06, R.id.rl_04, R.id.rl_03, R.id.rl_01, R.id.rl_02, R.id.rl_16}) + @OnClickk({R.id.rl_05, R.id.rl_12, R.id.rl_011, R.id.rl_10, R.id.rl_09, R.id.rl_08, R.id.rl_07, R.id.rl_06, R.id.rl_04, R.id.rl_03, R.id.rl_01, R.id.rl_02, R.id.rl_16, R.id.rl_17}) public void click(View view) { if(ProfileSpUtils.getInstance().getSetBean().isRedswitchone()){ SafeToastUtils.showShort(MainActivity.this, "请关闭云端控制"); @@ -398,9 +415,29 @@ public class MainActivity extends BaseActivity implements InfoMessage { JumpUtils.gotoActivity(MainActivity.this, KeyWordActivity.class, false, "", ""); } else if (id == R.id.rl_01) { JumpUtils.gotoActivity(MainActivity.this, RecFollowActivity.class, false, "", ""); - // JumpUtils.gotoActivity(MainActivity.this, MainActivityy.class, false, "", ""); } else if (id == R.id.rl_16) { JumpUtils.gotoActivity(MainActivity.this,CancelThumbUpActivity.class, false, "", ""); + } else if (id == R.id.rl_17) { + // 钉钉打卡 + if (AblUtil.isAccessibilityServiceOpen(MainActivity.this)) { + // 启动钉钉应用并执行打卡操作 + executeDingDingDaka(); + // 启动自动化打卡流程 + // 延迟1秒后发送 STEP_270 消息,让钉钉应用有时间启动 + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + Log.e("TIAOSHI###", "MainActivity: 启动钉钉打卡自动化流程"); + // 必须先设置 setStop(false),否则消息不会被处理 + AblStepHandler.getInstance().setStop(false); + Log.e("TIAOSHI###", "MainActivity: 已设置 setStop(false),发送 STEP_270 消息"); + AblStepHandler.sendMsg(AblSteps.STEP_270); + } + }, 1000); + } else { + SafeToastUtils.showShort(MainActivity.this, "请先开启辅助服务"); + AblUtil.openAccessibilitySettings(); + } } else if (id == R.id.rl_02) { // service.stopSelf(); @@ -563,6 +600,154 @@ public class MainActivity extends BaseActivity implements InfoMessage { } } + /** + * 执行钉钉打卡 + */ + private void executeDingDingDaka() { + // 钉钉应用包名 + String dingDingPackageName = "com.alibaba.android.rimet"; + // 钉钉的主 Activity(已知的正确启动 Activity) + String dingDingMainActivity = "com.alibaba.android.rimet.biz.LaunchHomeActivity"; + + // 检查钉钉应用是否已安装(可能是权限问题导致检查失败,但应用实际已安装) + boolean isInstalled = isAppInstalled(dingDingPackageName); + if (!isInstalled) { + Log.w("MainActivity", "应用检查失败,但继续尝试启动(可能是权限问题)"); + // 不直接返回,继续尝试启动 + } + + try { + // 方法1: 优先使用系统推荐的方式启动应用(getLaunchIntentForPackage) + PackageManager packageManager = getPackageManager(); + Intent launchIntent = packageManager.getLaunchIntentForPackage(dingDingPackageName); + + if (launchIntent != null) { + launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(launchIntent); + SafeToastUtils.showShort(MainActivity.this, "正在启动钉钉..."); + Log.d("MainActivity", "成功启动钉钉应用(使用 getLaunchIntentForPackage)"); + } else { + // 方法2: 如果 getLaunchIntentForPackage 返回 null,使用已知的 Activity 名称 + Log.w("MainActivity", "getLaunchIntentForPackage 返回 null,使用已知的 Activity 名称"); + Intent intent = new Intent(); + intent.setComponent(new ComponentName(dingDingPackageName, dingDingMainActivity)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + SafeToastUtils.showShort(MainActivity.this, "正在启动钉钉..."); + Log.d("MainActivity", "成功启动钉钉应用(使用 LaunchHomeActivity)"); + } + + // 启动自动化打卡流程 + // 延迟1秒后发送 STEP_270 消息,让钉钉应用有时间启动 + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + Log.e("TIAOSHI###", "MainActivity: 启动钉钉打卡自动化流程"); + // 必须先设置 setStop(false),否则消息不会被处理 + AblStepHandler.getInstance().setStop(false); + Log.e("TIAOSHI###", "MainActivity: 已设置 setStop(false),发送 STEP_270 消息"); + AblStepHandler.sendMsg(AblSteps.STEP_270); + } + }, 1000); + } catch (Exception e) { + e.printStackTrace(); + Log.e("MainActivity", "启动钉钉失败", e); + SafeToastUtils.showShort(MainActivity.this, "启动钉钉失败:" + e.getMessage()); + } + } + + /** + * 检查应用是否已安装 + * @param packageName 应用包名 + * @return true 表示已安装,false 表示未安装 + */ + private boolean isAppInstalled(String packageName) { + try { + PackageManager packageManager = getPackageManager(); + + // 方法1: 尝试获取包信息(最简单的方式) + try { + packageManager.getPackageInfo(packageName, 0); + Log.d("MainActivity", "✓ 通过 getPackageInfo 检测到应用已安装: " + packageName); + return true; + } catch (PackageManager.NameNotFoundException e) { + Log.d("MainActivity", "✗ getPackageInfo 未找到应用: " + packageName); + } + + // 方法2: 尝试获取启动 Intent(更可靠) + try { + Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName); + if (launchIntent != null) { + Log.d("MainActivity", "✓ 通过 getLaunchIntentForPackage 检测到应用已安装: " + packageName); + return true; + } else { + Log.d("MainActivity", "✗ getLaunchIntentForPackage 返回 null: " + packageName); + } + } catch (Exception e) { + Log.w("MainActivity", "getLaunchIntentForPackage 异常: " + packageName, e); + } + + // 方法3: 尝试查询 Intent 活动 + try { + Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); + resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); + resolveIntent.setPackage(packageName); + List apps = packageManager.queryIntentActivities(resolveIntent, PackageManager.MATCH_DEFAULT_ONLY); + if (apps != null && !apps.isEmpty()) { + Log.d("MainActivity", "✓ 通过 queryIntentActivities 检测到应用已安装: " + packageName + ", 找到 " + apps.size() + " 个活动"); + return true; + } else { + Log.d("MainActivity", "✗ queryIntentActivities 未找到活动: " + packageName); + } + } catch (Exception e) { + Log.w("MainActivity", "queryIntentActivities 异常: " + packageName, e); + } + + // 方法4: 尝试使用 MATCH_UNINSTALLED_PACKAGES(需要权限,但更全面) + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + packageManager.getPackageInfo(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES); + Log.d("MainActivity", "✓ 通过 MATCH_UNINSTALLED_PACKAGES 检测到应用: " + packageName); + return true; + } + } catch (PackageManager.NameNotFoundException e) { + Log.d("MainActivity", "✗ MATCH_UNINSTALLED_PACKAGES 未找到应用: " + packageName); + } catch (Exception e) { + Log.w("MainActivity", "MATCH_UNINSTALLED_PACKAGES 异常: " + packageName, e); + } + + Log.w("MainActivity", "⚠ 所有方法都未检测到应用: " + packageName); + return false; + + } catch (Exception e) { + Log.e("MainActivity", "检查应用安装状态失败: " + packageName, e); + return false; + } + } + + /** + * 打开应用商店(可选功能) + * @param packageName 应用包名 + */ + private void openAppStore(String packageName) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("market://details?id=" + packageName)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } catch (Exception e) { + // 如果应用商店不可用,尝试使用浏览器打开 + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("https://play.google.com/store/apps/details?id=" + packageName)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } catch (Exception ex) { + e.printStackTrace(); + } + } + } + private void openService() { //单击了“bindService”按钮 Intent intent = new Intent(MainActivity.this, TestTwoService.class); @@ -1397,7 +1582,10 @@ public class MainActivity extends BaseActivity implements InfoMessage { long b = a - aLong; long c = 0 + aLong; Log.e("TIAOSHI###运行剩余时长", b + ""); - LiveEventBus.get("run_time").post("任务已运行"+c/60+"分钟"); + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("run_time").post("任务已运行"+c/60+"分钟"); + } } }) .doOnComplete(new Action() { @@ -1409,7 +1597,10 @@ public class MainActivity extends BaseActivity implements InfoMessage { AblViewUtil.potgegin("停止"); break; case "6": - LiveEventBus.get("some_key").post("任务运行即将结束"); + // Android 12+ 上禁用 LiveEventBus + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + LiveEventBus.get("some_key").post("任务运行即将结束"); + } break; default: diff --git a/app/src/main/java/com/fisherbone/fuzhu/step/DingDingDakaStep.java b/app/src/main/java/com/fisherbone/fuzhu/step/DingDingDakaStep.java new file mode 100644 index 0000000..4d85f41 --- /dev/null +++ b/app/src/main/java/com/fisherbone/fuzhu/step/DingDingDakaStep.java @@ -0,0 +1,212 @@ +package com.fisherbone.fuzhu.step; + +import android.graphics.Rect; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.accessibility.AccessibilityNodeInfo; + +import com.fisherbone.fuzhu.abllib.AblService; +import com.fisherbone.fuzhu.abllib.AblStepHandler; +import com.fisherbone.fuzhu.abllib.AblSteps; +import com.fisherbone.fuzhu.abllib.BaseAblStep; +import com.fisherbone.fuzhu.abllib.utils.AblViewUtil; + +/** + * 钉钉打卡自动化步骤 + * 参考 TestAblStep0.java 的风格 + * 流程: + * 1. STEP_270: 等待钉钉应用启动完成 + * 2. STEP_271: 在钉钉首页查找并点击"打卡"按钮 + * 3. STEP_272: 在打卡页面查找并点击"打卡"按钮 + */ +public class DingDingDakaStep extends BaseAblStep { + + @Override + public void onStep(int step, Message msg) { + Log.e("TIAOSHI###", "DingDingDakaStep.onStep: 收到步骤 step=" + step + ", Thread=" + Thread.currentThread().getName()); + try { + switch (step) { + case AblSteps.STEP_270: + Log.e("TIAOSHI###", "钉钉打卡-步骤1: 等待应用启动"); + // 确保 isStop 为 false + if (AblStepHandler.getInstance().isStop()) { + Log.e("TIAOSHI###", "钉钉打卡-步骤1: 检测到 isStop=true,重新设置为 false"); + AblStepHandler.getInstance().setStop(false); + } + // 使用 postDelayed 直接在当前线程延迟执行,避免 Handler 消息丢失 + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + Log.e("TIAOSHI###", "钉钉打卡-步骤1: postDelayed 回调执行,发送 STEP_271"); + // 再次确保 isStop 为 false + if (AblStepHandler.getInstance().isStop()) { + Log.e("TIAOSHI###", "钉钉打卡-步骤1: postDelayed 中检测到 isStop=true,重新设置为 false"); + AblStepHandler.getInstance().setStop(false); + } + AblStepHandler.sendMsg(AblSteps.STEP_271, 0); + Log.e("TIAOSHI###", "钉钉打卡-步骤1: 已发送 STEP_271 消息(立即执行)"); + } + }, 2000); + Log.e("TIAOSHI###", "钉钉打卡-步骤1: 已设置 postDelayed(延迟2000ms)"); + break; + + case AblSteps.STEP_271: + // 步骤2: 在钉钉首页查找并点击"打卡"按钮 + Log.e("TIAOSHI###", "钉钉打卡-步骤2: STEP_271 开始执行"); + Log.e("TIAOSHI###", "钉钉打卡-步骤2: isStop=" + AblStepHandler.getInstance().isStop()); + // 确保 isStop 为 false + if (AblStepHandler.getInstance().isStop()) { + Log.e("TIAOSHI###", "钉钉打卡-步骤2: 检测到 isStop=true,重新设置为 false"); + AblStepHandler.getInstance().setStop(false); + } + Log.e("TIAOSHI###", "钉钉打卡-步骤2: 查找并点击打卡按钮"); + if (clickDakaButton("打卡")) { + Log.e("TIAOSHI###", "成功点击打卡按钮,等待跳转到打卡页面"); + // 使用 postDelayed 直接延迟执行,避免 Handler 消息丢失 + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + Log.e("TIAOSHI###", "钉钉打卡-步骤2: postDelayed 回调执行,发送 STEP_272"); + // 再次确保 isStop 为 false + if (AblStepHandler.getInstance().isStop()) { + AblStepHandler.getInstance().setStop(false); + } + AblStepHandler.sendMsg(AblSteps.STEP_272, 0); + Log.e("TIAOSHI###", "钉钉打卡-步骤2: 已发送 STEP_272 消息(立即执行)"); + } + }, 2000); + Log.e("TIAOSHI###", "钉钉打卡-步骤2: 已设置 postDelayed(延迟2000ms)"); + } else { + // 尝试其他可能的文本 + Log.e("TIAOSHI###", "未找到'打卡',尝试其他文本"); + if (clickDakaButton("考勤打卡") || clickDakaButton("工作") || clickDakaButton("工作台")) { + Log.e("TIAOSHI###", "找到并点击了其他入口"); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if (AblStepHandler.getInstance().isStop()) { + AblStepHandler.getInstance().setStop(false); + } + AblStepHandler.sendMsg(AblSteps.STEP_272, 0); + } + }, 2000); + Log.e("TIAOSHI###", "钉钉打卡-步骤2: 已设置 postDelayed(延迟2000ms)"); + } else { + Log.e("TIAOSHI###", "未找到打卡入口"); + } + } + break; + + case AblSteps.STEP_272: + // 步骤3: 在打卡页面查找并点击"打卡"按钮 + Log.e("TIAOSHI###", "钉钉打卡-步骤3: STEP_272 开始执行"); + Log.e("TIAOSHI###", "钉钉打卡-步骤3: isStop=" + AblStepHandler.getInstance().isStop()); + // 确保 isStop 为 false + if (AblStepHandler.getInstance().isStop()) { + Log.e("TIAOSHI###", "钉钉打卡-步骤3: 检测到 isStop=true,重新设置为 false"); + AblStepHandler.getInstance().setStop(false); + } + Log.e("TIAOSHI###", "钉钉打卡-步骤3: 在打卡页面点击打卡"); + if (clickDakaButton("打卡")) { + Log.e("TIAOSHI###", "成功完成打卡操作"); + } else { + // 尝试其他可能的打卡按钮文本 + if (clickDakaButton("上班打卡") || clickDakaButton("下班打卡") || + clickDakaButton("外勤打卡") || clickDakaButton("立即打卡")) { + Log.e("TIAOSHI###", "成功完成打卡操作"); + } else { + Log.e("TIAOSHI###", "未找到打卡按钮"); + } + } + break; + + default: + Log.e("TIAOSHI###", "DingDingDakaStep.onStep: 未知步骤 step=" + step); + break; + } + } catch (Exception e) { + Log.e("TIAOSHI###", "DingDingDakaStep.onStep: 执行异常 step=" + step, e); + } + } + + /** + * 查找并点击包含指定文本的按钮 + * 参考 TestAblStep0.java 的风格,直接遍历节点 + */ + private boolean clickDakaButton(String text) { + try { + AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); + if (root == null) { + Log.e("TIAOSHI###", "无法获取根节点"); + return false; + } + + // 遍历所有节点查找文本 + return findAndClickNode(root, text); + + } catch (Exception e) { + Log.e("TIAOSHI###", "查找打卡按钮异常: " + text, e); + return false; + } + } + + /** + * 递归查找并点击包含指定文本的节点 + * 参考 TestAblStep0.java 的遍历方式 + */ + private boolean findAndClickNode(AccessibilityNodeInfo node, String text) { + if (node == null) { + return false; + } + + try { + // 检查当前节点的文本和描述 + CharSequence nodeText = node.getText(); + CharSequence nodeContentDesc = node.getContentDescription(); + + // 输出节点信息用于调试(参考 TestAblStep0.java) + if (nodeText != null || nodeContentDesc != null) { + Log.e("TIAOSHI###", "节点: " + node.getClassName() + " 文本: " + nodeText + " 描述: " + nodeContentDesc); + } + + // 检查是否包含目标文本 + if ((nodeText != null && nodeText.toString().contains(text)) || + (nodeContentDesc != null && nodeContentDesc.toString().contains(text))) { + + Rect rect = new Rect(); + node.getBoundsInScreen(rect); + if (rect.width() > 0 && rect.height() > 0 && node.isEnabled()) { + Log.e("TIAOSHI###", "找到匹配节点: " + text + " 坐标: [" + rect.left + "," + rect.top + "][" + rect.right + "," + rect.bottom + "]"); + + // 尝试点击节点 + if (node.isClickable()) { + boolean clicked = node.performAction(AccessibilityNodeInfo.ACTION_CLICK); + if (clicked) { + Log.e("TIAOSHI###", "成功点击节点: " + text); + return true; + } + } else { + // 如果节点不可点击,使用 performViewClick(会自动向上查找可点击的父节点) + AblViewUtil.performViewClick(node); + Log.e("TIAOSHI###", "使用 performViewClick 点击: " + text); + return true; + } + } + } + + // 递归查找子节点(参考 TestAblStep0.java 的遍历方式) + for (int i = 0; i < node.getChildCount(); i++) { + AccessibilityNodeInfo child = node.getChild(i); + if (findAndClickNode(child, text)) { + return true; + } + } + } catch (Exception e) { + Log.w("TIAOSHI###", "查找节点异常", e); + } + + return false; + } +} + diff --git a/app/src/main/java/com/fisherbone/fuzhu/utils/LiveEventBusFix.java b/app/src/main/java/com/fisherbone/fuzhu/utils/LiveEventBusFix.java new file mode 100644 index 0000000..af08a7e --- /dev/null +++ b/app/src/main/java/com/fisherbone/fuzhu/utils/LiveEventBusFix.java @@ -0,0 +1,60 @@ +package com.fisherbone.fuzhu.utils; + +import android.content.Context; +import android.os.Build; + +/** + * 修复 LiveEventBus 在 Android 12+ 上的 BroadcastReceiver 注册问题 + * + * 注意:由于 Android 12+ 的限制,无法通过反射完全修复此问题。 + * 实际解决方案:在 MainActivity 中使用 try-catch 包裹所有 LiveEventBus 调用。 + */ +public class LiveEventBusFix { + + private static boolean isFixed = false; + private static boolean isUnavailable = false; + + /** + * 标记 LiveEventBus 为不可用 + */ + public static void markAsUnavailable() { + isUnavailable = true; + android.util.Log.w("LiveEventBusFix", "LiveEventBus 已标记为不可用"); + } + + /** + * 检查 LiveEventBus 是否可用 + */ + public static boolean isAvailable() { + return !isUnavailable; + } + + /** + * 修复 LiveEventBus 的 BroadcastReceiver 注册问题 + * 必须在 Application.onCreate() 中尽早调用,在 LiveEventBus 初始化之前 + * + * 注意:由于 Android 12+ 的限制,无法通过反射完全修复此问题。 + * 建议在 MainActivity 中使用 try-catch 包裹所有 LiveEventBus 调用。 + * + * @param context Application Context + */ + public static void fix(Context context) { + if (isFixed) { + return; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + // Android 12+ 上,LiveEventBus 1.7.3 版本存在兼容性问题 + // 无法通过反射修复,因为替换 Context 会导致类型转换错误 + // 解决方案:在 MainActivity 中使用 try-catch 包裹所有 LiveEventBus 调用 + android.util.Log.w("LiveEventBusFix", "⚠ LiveEventBus 1.7.3 在 Android 12+ 上有兼容性问题"); + android.util.Log.w("LiveEventBusFix", "建议:1) 在 MainActivity 中使用 try-catch 包裹所有 LiveEventBus 调用"); + android.util.Log.w("LiveEventBusFix", " 2) 升级 LiveEventBus 到支持 Android 12+ 的版本"); + android.util.Log.w("LiveEventBusFix", " 3) 使用其他事件总线库(如 EventBus)"); + } + + isFixed = true; // 标记为已处理,避免重复调用 + } + +} + diff --git a/app/src/main/java/com/fisherbone/fuzhu/utils/LiveEventBusWrapper.java b/app/src/main/java/com/fisherbone/fuzhu/utils/LiveEventBusWrapper.java new file mode 100644 index 0000000..a0da617 --- /dev/null +++ b/app/src/main/java/com/fisherbone/fuzhu/utils/LiveEventBusWrapper.java @@ -0,0 +1,93 @@ +package com.fisherbone.fuzhu.utils; + +import android.util.Log; + +import com.jeremyliao.liveeventbus.LiveEventBus; + +/** + * LiveEventBus 包装类,用于处理 Android 12+ 兼容性问题 + * 如果 LiveEventBus 初始化失败,所有调用会静默失败,不会导致崩溃 + */ +public class LiveEventBusWrapper { + + private static final String TAG = "LiveEventBusWrapper"; + private static boolean isAvailable = true; + + /** + * 检查 LiveEventBus 是否可用 + */ + private static boolean checkAvailable() { + if (!isAvailable) { + return false; + } + + try { + // 尝试获取一个测试实例,检查是否初始化成功 + LiveEventBus.get("_test_", String.class); + return true; + } catch (Exception e) { + isAvailable = false; + Log.w(TAG, "LiveEventBus 不可用(可能是 Android 12+ 兼容性问题)", e); + return false; + } + } + + /** + * 安全地获取 LiveEventBus 实例 + */ + public static Object get(String key, Class type) { + if (!checkAvailable()) { + return null; + } + + try { + return LiveEventBus.get(key, type); + } catch (Exception e) { + Log.w(TAG, "LiveEventBus.get() 失败: " + key, e); + isAvailable = false; + return null; + } + } + + /** + * 安全地获取 LiveEventBus 实例(无类型) + */ + public static Object get(String key) { + if (!checkAvailable()) { + return null; + } + + try { + return LiveEventBus.get(key); + } catch (Exception e) { + Log.w(TAG, "LiveEventBus.get() 失败: " + key, e); + isAvailable = false; + return null; + } + } + + /** + * 安全地发送消息 + */ + public static void post(String key, Object value) { + if (!checkAvailable()) { + return; + } + + try { + Object bus = get(key); + if (bus != null) { + // 使用反射调用 post 方法 + try { + java.lang.reflect.Method postMethod = bus.getClass().getMethod("post", Object.class); + postMethod.invoke(bus, value); + } catch (Exception e) { + Log.w(TAG, "LiveEventBus.post() 失败: " + key, e); + } + } + } catch (Exception e) { + Log.w(TAG, "LiveEventBus.post() 失败: " + key, e); + } + } +} + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 34490ff..b737b9e 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,606 +1,618 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main1.xml b/app/src/main/res/layout/activity_main1.xml deleted file mode 100644 index 405c546..0000000 --- a/app/src/main/res/layout/activity_main1.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - -