commit
This commit is contained in:
25
doc/1.01版本方向
Normal file
25
doc/1.01版本方向
Normal file
@@ -0,0 +1,25 @@
|
||||
开发atom1.0版本
|
||||
1. 推荐加关:关注抖音【推荐】中的用户;
|
||||
2. 同城加关:关注抖音指定【同城】中的用户;
|
||||
3. 关键词 加关:对搜索指定关键词中的【用户】加关;
|
||||
4. 智能加关(后台群控):对后台指定的一批抖音用户进行加关;
|
||||
5. 私信(后台群控):对后台指定的一批抖音用户进行私信(文字、图片、作品);
|
||||
6. 一键取关:取消已关的粉丝;
|
||||
7. 话术设置:私信话术、直播话术、回访话术、首次关注话术;
|
||||
|
||||
|
||||
|
||||
|
||||
1.01版本阿童木:
|
||||
1.稳定性,无法长时间运行。
|
||||
2.推荐加关,运行时长,单位改为分钟。
|
||||
3.粉丝、关注增加区间设置。
|
||||
4.广告不需要进详情。
|
||||
5.无障碍模式出错。
|
||||
6.退出、重新开始时,需要重新打开无障碍。(无障碍已打开)
|
||||
7.悬浮窗消失(养号功能还在继续跑)
|
||||
8.一键取关,取关数无效。
|
||||
9.一键取关:取消互关点击后,弹窗:false
|
||||
10.一键取关:手动停止,第二次运行,点开始后无反应,需要重新打开APP。
|
||||
11.一键取关:取消互关,卡死在【我】的页面
|
||||
12.多次点击开始任务,会弹出多个悬浮窗。
|
||||
18
doc/1.1版本
Normal file
18
doc/1.1版本
Normal file
@@ -0,0 +1,18 @@
|
||||
ATOM v.1.1
|
||||
修改:
|
||||
1. 推荐关键:
|
||||
a. 视频观看时长改为2个输入框;
|
||||
b. 加关关注数、加关粉丝数、最小作品数改为范围设置;
|
||||
c. 取消最大作品时间;
|
||||
2. 一键取关:可以多选已关、互关,此时不做条件判断,依次取关;
|
||||
3. 话术设置:每种话术默认设置10条,最少不能少于10条;
|
||||
4. 多个账号同组同手机,执行任务时每次随机账号顺序执行;
|
||||
|
||||
新增:
|
||||
5. 关键词加关:设置指定关键词后,抖音搜索关键词,浏览视频、加关;
|
||||
6. 同城加关:设置城市后,抖音切换该城市后,在该城市下浏览、加关;
|
||||
7. 粉丝互动:给自己的粉丝批量发私信(文字、链接、图片);
|
||||
8. 大V粉截流:
|
||||
a. 指定抖音账号,在该抖音账号的粉丝中添加关注;
|
||||
b. 设置屏蔽关键词,不加关含有关键词的粉丝;
|
||||
c. 不加关默认头像、默认用户名的粉丝;
|
||||
16
doc/14.6版本适配
Normal file
16
doc/14.6版本适配
Normal file
@@ -0,0 +1,16 @@
|
||||
1.推荐加关可以正常使用
|
||||
2.获取当前抖音帐号可以正常使用(修改地方)
|
||||
// if ("dmt.viewpager.DmtViewPager$d".equals(child.getClassName())) {//抖音版本13.1写法
|
||||
if ("dmt.viewpager.DmtViewPager$MyAccessibilityDelegate".equals(child.getClassName())) {
|
||||
|
||||
3.退出抖音可以正常使用
|
||||
4.关机重启可以正常使用
|
||||
5.一键取关取消已关功能正常使用(修改地方)
|
||||
// if ("dmt.viewpager.DmtViewPager$d".equals(child.getClassName())) {//13.1版本写法
|
||||
if ("dmt.viewpager.DmtViewPager$MyAccessibilityDelegate".equals(child.getClassName())) {
|
||||
6.一键取关取消互关功能正常使用(修改地方)
|
||||
// if ("dmt.viewpager.DmtViewPager$d".equals(child.getClassName())) {//13.1版本写法
|
||||
if ("dmt.viewpager.DmtViewPager$MyAccessibilityDelegate".equals(child.getClassName())) {
|
||||
7.帐号切换可以正常使用
|
||||
8.导入通讯录可以正常使用
|
||||
9.
|
||||
39
doc/README.md
Normal file
39
doc/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# fuzhu
|
||||
|
||||
#### 介绍
|
||||
{**以下是 Gitee 平台说明,您可以替换此简介**
|
||||
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
||||
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
||||
|
||||
#### 软件架构
|
||||
软件架构说明
|
||||
|
||||
|
||||
#### 安装教程
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 使用说明
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 参与贡献
|
||||
|
||||
1. Fork 本仓库
|
||||
2. 新建 Feat_xxx 分支
|
||||
3. 提交代码
|
||||
4. 新建 Pull Request
|
||||
|
||||
|
||||
#### 特技
|
||||
|
||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
||||
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
||||
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
7
doc/atom操作手册
Normal file
7
doc/atom操作手册
Normal file
@@ -0,0 +1,7 @@
|
||||
1.开允许在其他应用上显示权限
|
||||
2.打开辅助
|
||||
3.激活
|
||||
adb shell pm grant com.fisherbone.fuzhu android.permission.WRITE_SECURE_SETTINGS
|
||||
4.开云端群控
|
||||
5.云端群控需点击环境检测
|
||||
|
||||
88
doc/基类代码
Normal file
88
doc/基类代码
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* 点击直播间下方的更多按钮
|
||||
* 1.说点什么
|
||||
* 2.更多
|
||||
* 3.礼物
|
||||
*/
|
||||
private void clickmore(String type) {
|
||||
accessibilityNodeInfos = new ArrayList<>();
|
||||
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());
|
||||
switch (type) {
|
||||
case "1"://说点什么
|
||||
if ("android.widget.TextView".equals(child1.getClassName())) {
|
||||
if (child1.getText() != null) {
|
||||
if (child1.getText().toString().equals("说点什么...")) {
|
||||
AblService.getInstance().clickcommontwo(child1, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "2"://更多
|
||||
if ("android.widget.Button".equals(child1.getClassName())) {
|
||||
if (child1.getContentDescription().equals("更多")) {
|
||||
AblService.getInstance().clickcommontwo(child1, "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "3"://礼物
|
||||
if ("android.widget.Button".equals(child1.getClassName())) {
|
||||
if (child1.getContentDescription().equals("礼物")) {
|
||||
AblService.getInstance().clickcommontwo(child1, "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享
|
||||
* 1为分享 2为私信朋友
|
||||
*/
|
||||
private void share(String type) {
|
||||
accessibilityNodeInfos = new ArrayList<>();
|
||||
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());
|
||||
switch (type) {
|
||||
case "1":
|
||||
if ("android.widget.TextView".equals(child3.getClassName())) {
|
||||
if (child3.getText() != null) {
|
||||
if (child3.getText().toString().equals("分享")) {
|
||||
AblService.getInstance().clickcommontwo(child3, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "2":
|
||||
if ("android.widget.TextView".equals(child3.getClassName())) {
|
||||
if (child3.getText() != null) {
|
||||
if (child3.getText().toString().equals("私信朋友")) {
|
||||
AblService.getInstance().clickcommontwo(child3, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
doc/如何让软件自动开启无障碍
Normal file
18
doc/如何让软件自动开启无障碍
Normal file
@@ -0,0 +1,18 @@
|
||||
https://zhuanlan.zhihu.com/p/263414387
|
||||
https://blog.csdn.net/weixin_42474371/article/details/104405463
|
||||
|
||||
|
||||
第一步:
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
第二部:
|
||||
Settings.Secure.putString(getContentResolver(),Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "com.fisherbone.fuzhu.abllib/AblService");
|
||||
Settings.Secure.putString(getContentResolver(),Settings.Secure.ACCESSIBILITY_ENABLED, "0");//1表示开启
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
92
doc/工作日志
Normal file
92
doc/工作日志
Normal file
@@ -0,0 +1,92 @@
|
||||
1.修改了推荐加关的参数
|
||||
2.项目启动提示添加评论话术
|
||||
3.一键取关参数调整
|
||||
4.添加视频观看时长
|
||||
5.详情页回关判断直接返回
|
||||
6.默认评论话术
|
||||
7.添加关注太快了,先休息一下,直接让停止继续加关注
|
||||
8.推荐加关流程优化
|
||||
9.运行稳定性
|
||||
10.完成了ATOM版本自动更新,并处理了抖音的一些弹框。
|
||||
|
||||
|
||||
|
||||
______________________________________________________________________
|
||||
测试帐号登录
|
||||
验证码故意输错,返回后重新授权,ChangLiang.task_type = "";则会重新领取任务
|
||||
|
||||
|
||||
loginResult()方法的成功回调中
|
||||
ChangLiang.task_type = "";
|
||||
ChangLiang.istask = false;
|
||||
ChangLiang.isstart="0";
|
||||
|
||||
实现闭环登录
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
版本: 1.0.1
|
||||
TIAOSHI: 有弹出==软件版本更新==classname==android.app.AlertDialog
|
||||
TIAOSHI: 有弹出软件版本更新
|
||||
TIAOSHILatest Toast Message:: 软件版本更新 [Source: com.fisherbone.fuzhu]
|
||||
TIAOSHI: 有弹出==应用包管理组件==classname==com.android.packageinstaller.PackageInstallerActivity
|
||||
TIAOSHI: 有弹出应用包管理组件
|
||||
TIAOSHILatest Toast Message:: 应用包管理组件 [Source: com.miui.packageinstaller]
|
||||
TIAOSHI: 有弹出==应用包管理组件==classname==com.android.packageinstaller.InstallAppProgress
|
||||
TIAOSHI: 有弹出应用包管理组件
|
||||
|
||||
|
||||
|
||||
|
||||
_________________________________________________________________________________________________
|
||||
E/TIAOSHI: 有弹出==抖音
|
||||
E/TIAOSHI: 有弹出抖音
|
||||
E/TIAOSHI: 有弹出==当前为非Wi-Fi环境,请注意流量消耗
|
||||
E/TIAOSHI: 有弹出当前为非Wi-Fi环境,请注意流量消耗
|
||||
E/TIAOSHI: 有弹出==为呵护未成年人健康成长,抖音推出儿童/青少年模式。该模式下部分功能无法正常使用。请监护人主动选择,并设置监护密码。《儿童/青少年使用须知》详情
|
||||
|
||||
|
||||
|
||||
_______________这个点击系统返回键不起作用
|
||||
E/TIAOSHI: 有弹出==发现通讯录好友==classname==com.ss.android.ugc.aweme.main.dw
|
||||
E/TIAOSHI: 有弹出发现通讯录好友
|
||||
E/TIAOSHILatest Toast Message:: 发现通讯录好友 [Source: com.ss.android.ugc.aweme]
|
||||
|
||||
|
||||
E/TIAOSHI: 有弹出==个人信息保护指引==classname==com.ss.android.ugc.aweme.main.dg
|
||||
E/TIAOSHI: 有弹出个人信息保护指引
|
||||
E/TIAOSHILatest Toast Message:: 个人信息保护指引 [Source: com.ss.android.ugc.aweme]
|
||||
|
||||
|
||||
——————————————————————————————可以使用系统返回键关闭
|
||||
E/TIAOSHI: 有弹出==好友推荐==classname==android.app.Dialog
|
||||
E/TIAOSHI: 有弹出好友推荐
|
||||
E/TIAOSHILatest Toast Message:: 好友推荐 [Source: com.ss.android.ugc.aweme]
|
||||
|
||||
_______________这个点击系统返回键不起作用
|
||||
E/TIAOSHI: 有弹出==检测到更新==classname==com.ss.android.ugc.aweme.update.a.a
|
||||
E/TIAOSHI: 有弹出检测到更新
|
||||
E/TIAOSHILatest Toast Message:: 检测到更新 [Source: com.ss.android.ugc.aweme]
|
||||
|
||||
_____________________________________________________________可以使用系统返回键关闭
|
||||
E/TIAOSHI: 有弹出==为呵护未成年人健康成长,抖音推出儿童/青少年模式。该模式下部分功能无法正常使用。请监护人主动选择,并设置监护密码。《儿童/青少年使用须知》详情==classname==androidx.appcompat.app.AlertDialog
|
||||
|
||||
_____________________________________________________________个人信息保护指引系统返回键不起作用
|
||||
E/TIAOSHI: 有弹出==个人信息保护指引==classname==com.ss.android.ugc.aweme.main.dg
|
||||
E/TIAOSHI: 有弹出个人信息保护指引
|
||||
E/TIAOSHILatest Toast Message:: 个人信息保护指引 [Source: com.ss.android.ugc.aweme]
|
||||
|
||||
|
||||
|
||||
_________________________________________________________________________________
|
||||
有弹出==抖音==classname==com.ss.android.ugc.aweme.profile.ui.UserProfileActivity
|
||||
有弹出抖音
|
||||
|
||||
|
||||
E/TIAOSHI: 有弹出==确认取消关注?==classname==com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
E/TIAOSHI: 有弹出确认取消关注?
|
||||
E/TIAOSHILatest Toast Message:: 确认取消关注? [Source: com.ss.android.ugc.aweme]
|
||||
129
doc/异常处理
Normal file
129
doc/异常处理
Normal file
@@ -0,0 +1,129 @@
|
||||
1.访问接口出错
|
||||
java.net.UnknownServiceException: CLEARTEXT communication to * not permitted by network
|
||||
在Android9版以上会发生如下异常
|
||||
|
||||
java.net.UnknownServiceException: CLEARTEXT communication to * not permitted by network
|
||||
|
||||
原因是Android9版本默认不允许http访问,他们认为http是不安全的,只能用https
|
||||
|
||||
解决办法
|
||||
|
||||
1:请求修改为https
|
||||
|
||||
2:targetSdkVersion 降到27以下
|
||||
|
||||
3:在 res 下新增一个 xml 目录,然后创建一个名为:network_security_config.xml 文件(名字自定) ,内容如下,大概意思就是允许开启http请求
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<network-security-config>
|
||||
|
||||
<base-config cleartextTrafficPermitted="true" />
|
||||
|
||||
</network-security-config>
|
||||
|
||||
在AndroidManifest.xml的Application中添加配置引用
|
||||
|
||||
<application
|
||||
|
||||
..
|
||||
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
|
||||
... >
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
2.Android-Android 10 创建不了文件夹
|
||||
尝试了很久,AndroidManifest已加了权限:
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
也动态申请了读写权限,但是创建文件夹一直失败,而运行以前的工程,没有问题!!,最后发现在AndroidManifest中配置一下android:requestLegacyExternalStorage="true" 搞定!!
|
||||
|
||||
<application
|
||||
...
|
||||
android:requestLegacyExternalStorage="true" // 这样就可以采用原有的存储策略
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
更为诡异的是,这时你再把这个属性去掉,把apk卸载重装,它都有权限创建了!
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
3.解决Android10 imei不能获取的问题(适配Android 10)
|
||||
https://blog.csdn.net/zqd1984309864/article/details/107410758?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2.control
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
4.处理账号登录过程中弹出的推荐好友弹框
|
||||
|
||||
/**
|
||||
* 关闭弹框
|
||||
* @param instance
|
||||
*/
|
||||
public void closedDialog(AblService instance) {
|
||||
//检查是否有弹框,并关闭所有弹窗
|
||||
//处理发现通讯好好友的弹框
|
||||
AccessibilityNodeInfo liebiaokong = AblViewUtil.findByText("好友推荐", 0);
|
||||
if (liebiaokong != null) {
|
||||
Log.e("TIAOSHI###", "弹出了好友推荐的弹框");
|
||||
AccessibilityNodeInfo parent = liebiaokong.getParent();
|
||||
AccessibilityNodeInfo child = parent.getChild(2);
|
||||
instance.clickcommontwo(child, "关闭好友推荐弹框");
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
5.getText().toString() //要做空指针检测
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
6.字符串中去除表情符号
|
||||
String s = EmojiFilter.filterEmoji(s1);//去除字符串中包含的表情符号
|
||||
Log.e("提交的字符串(不包含表情符号)", s);
|
||||
|
||||
|
||||
7.文本框自动输入功能
|
||||
AccessibilityNodeInfo自动输入
|
||||
在AccessibilityNoteInfo中实现自动输入时,有两种不同的方法:
|
||||
|
||||
(1).在android版本>21时可以使用两种,第一种是AccessibilityService自带的方法:
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, Constents.mobile[mobile_j]);
|
||||
info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
|
||||
|
||||
(2).ClipboardManager clipboard = (ClipboardManager)this.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("text", "15066306736");
|
||||
clipboard.setPrimaryClip(clip);
|
||||
//焦点(n是AccessibilityNodeInfo对象)
|
||||
info.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
|
||||
粘贴进入内容
|
||||
info.performAction(AccessibilityNodeInfo.ACTION_PASTE);
|
||||
|
||||
8.在悬浮窗上显示运行的信息时候,会有延迟的原因是因为线程等待,将线程等待的代码写在发送消息的方法行面后正常,或者写在下一个步骤上也可以实现同步。
|
||||
|
||||
|
||||
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "com.fisherbone.fuzhu"
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 29
|
||||
versionCode 121
|
||||
versionName "1.2.1"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.myapplication"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
versionCode 121
|
||||
versionName "1.2.1"
|
||||
multiDexEnabled true //突破应用方法数65535的一个限制
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
66
doc/异常检测
Normal file
66
doc/异常检测
Normal file
@@ -0,0 +1,66 @@
|
||||
1.轮询服务检测:Kathy
|
||||
2.调试浮窗 showFloatingWindow()
|
||||
3. /**
|
||||
* 撞号任务完成的通知
|
||||
* @param str
|
||||
*/
|
||||
@Override
|
||||
public void mesagezhuang(String str) {
|
||||
tv_run_info.setText(str);
|
||||
if(str.equals("停止")){
|
||||
AblStepHandler.getInstance().setStop(true);
|
||||
touchResult();
|
||||
stutas(true, tv_1, tv_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
(server)' ~ Channel is unrecoverably broken and will be disposed!
|
||||
|
||||
|
||||
2021-03-23 16:47:10.470 4153-4163/? I/droid.ugc.awem: Background concurrent copying GC freed 454215(22MB) AllocSpace objects, 54(1504KB) LOS objects, 48% free, 25MB/49MB, paused 290us total 362.688ms
|
||||
2021-03-23 16:47:11.023 1457-2525/? I/ActivityManager: Force stopping com.fisherbone.fuzhu appid=10313 user=0: from process:7884
|
||||
2021-03-23 16:47:11.024 1457-2525/? I/ActivityManager: Force finishing activity ActivityRecord{3b7d9c1 u0 com.fisherbone.fuzhu/.MainActivity t2146}
|
||||
2021-03-23 16:47:11.027 1457-2525/? I/ActivityManager: Force finishing activity ActivityRecord{8e26758 u0 com.fisherbone.fuzhu/.activity.SettingActivity t2146}
|
||||
2021-03-23 16:47:11.029 1457-2525/? I/ActivityManager: Force stopping service ServiceRecord{6fd05e6 u0 com.fisherbone.fuzhu/.abllib.AblService}
|
||||
___________________________________________________________________________________________________________________
|
||||
内存优化:第一招:https://blog.csdn.net/u013110200/article/details/100080824
|
||||
(1)未设定属性android:largeheap = "true"时,可以申请到的最大内存空间为221M。
|
||||
(2)设定属性android:largeheap = "true"时, 可以申请的最大内存空间为478M,是原来的两倍多一些。
|
||||
|
||||
|
||||
|
||||
|
||||
2021-03-24 14:23:10.016 1457-1521/? W/BroadcastQueue: Timeout of broadcast BroadcastRecord{4261d0 u-1 android.intent.action.TIME_TICK} - receiver=android.os.BinderProxy@62898f0, started 10000ms ago
|
||||
2021-03-24 14:23:10.016 1457-1521/? W/BroadcastQueue: Receiver during timeout of BroadcastRecord{4261d0 u-1 android.intent.action.TIME_TICK} : BroadcastFilter{e6330ee u0 ReceiverList{7826e69 7125 com.fisherbone.fuzhu/10313/u0 remote:62898f0}}
|
||||
2021-03-24 14:23:10.055 3094-3094/? I/Timeline: Timeline: Activity_launch_request time:20206285
|
||||
2021-03-24 14:23:10.059 1457-2090/? I/ActivityManager: START u0 {dat=snssdk1128://user/profile pkg=com.ss.android.ugc.aweme cmp=com.ss.android.ugc.aweme/.profile.ui.UserProfileActivity (has extras)} from uid 10319
|
||||
2021-03-24 14:23:10.065 1457-2090/? D/CompatibilityInfo: mCompatibilityFlags - 0
|
||||
2021-03-24 14:23:10.066 1457-2090/? D/CompatibilityInfo: applicationDensity - 320
|
||||
2021-03-24 14:23:10.066 1457-2090/? D/CompatibilityInfo: applicationScale - 1.0
|
||||
2021-03-24 14:23:10.066 1457-2090/? D/ActivityTrigger: ActivityTrigger activityPauseTrigger
|
||||
2021-03-24 14:23:10.081 1457-1521/? I/ActivityManagerServiceInjector: finish silent ANR: ProcessRecord{a6256d5 7125:com.fisherbone.fuzhu/u0a313}
|
||||
2021-03-24 14:23:10.081 1457-1521/? I/ActivityManager: Killing 7125:com.fisherbone.fuzhu/u0a313 (adj 100): bg anr
|
||||
2021-03-24 14:23:10.082 2949-3567/? D/PowerKeeper.Event: notifyActiveKilled processName: com.fisherbone.fuzhu, pid:7125, reason:bg anr
|
||||
2021-03-24 14:23:10.082 1457-1526/? W/libprocessgroup: kill(-7125, 9) failed: No such process
|
||||
2021-03-24 14:23:10.094 1457-1526/? I/chatty: uid=1000(system) ActivityManager identical 2 lines
|
||||
2021-03-24 14:23:10.099 1457-1526/? W/libprocessgroup: kill(-7125, 9) failed: No such process
|
||||
2021-03-24 14:23:10.100 1457-3397/? D/CompatibilityInfo: mCompatibilityFlags - 0
|
||||
2021-03-24 14:23:10.100 1457-3397/? D/CompatibilityInfo: applicationDensity - 320
|
||||
2021-03-24 14:23:10.100 1457-3397/? D/CompatibilityInfo: applicationScale - 1.0
|
||||
2021-03-24 14:23:10.104 1457-1526/? W/libprocessgroup: kill(-7125, 9) failed: No such process
|
||||
2021-03-24 14:23:10.108 1457-3397/? I/Timeline: Timeline: App_transition_ready time:20206337
|
||||
2021-03-24 14:23:10.110 1457-1526/? W/libprocessgroup: kill(-7125, 9) failed: No such process
|
||||
2021-03-24 14:23:10.110 3094-3094/? W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@66063ae
|
||||
2021-03-24 14:23:10.116 1457-1526/? W/libprocessgroup: kill(-7125, 9) failed: No such process
|
||||
2021-03-24 14:23:10.120 3094-3265/? D/ViewContentFactory: initViewContentFetcherClass
|
||||
2021-03-24 14:23:10.120 3094-3265/? I/ContentCatcher: ViewContentFetcher : ViewContentFetcher
|
||||
2021-03-24 14:23:10.120 3094-3265/? D/ViewContentFactory: createInterceptor took 0ms
|
||||
2021-03-24 14:23:10.122 1457-1526/? W/libprocessgroup: kill(-7125, 9) failed: No such process
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
异常弹框的包名
|
||||
com.bytedance.android.livesdk.dislike.b
|
||||
31
doc/技术代码
Normal file
31
doc/技术代码
Normal file
@@ -0,0 +1,31 @@
|
||||
1.左滑动操作
|
||||
// AblViewUtil.onMessage("不满足点赞关注评论条件");
|
||||
// AblViewUtil.scrollHorizontal(10, 500, 100, 300, new GestureCallBack() {
|
||||
// @Override
|
||||
// public void succ(GestureDescription gestureDescription) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void fail(GestureDescription gestureDescription) {
|
||||
//
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
2.坐标点点击
|
||||
AblService.getInstance().clickPoint(659, 666, 300);//红米7a
|
||||
|
||||
@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 + ")");
|
||||
// ToastUtils.showShort("点击"+s+"按钮"+ "("+ (rect.left + rect.right) / 2 + "," + (rect.top + rect.bottom) / 2 + ")");
|
||||
} else {
|
||||
Log.e("TIAOSHI###", "没有找到"+s+"按钮,直接退出了。。。。");
|
||||
return;
|
||||
}
|
||||
}
|
||||
395
doc/技术文档
Normal file
395
doc/技术文档
Normal file
@@ -0,0 +1,395 @@
|
||||
一、三种常用的定时器
|
||||
1.Handler类的postDelayed方法:
|
||||
|
||||
final Handler mHandler = new Handler();
|
||||
Runnable r = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//do something
|
||||
//每隔1s循环执行run方法
|
||||
mHandler.postDelayed(this, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
//主线程中调用:
|
||||
mHandler.postDelayed(r, 100);//延时100毫秒
|
||||
2.用handler+timer+timeTask方法:
|
||||
|
||||
final Handler handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (msg.what == 1) {
|
||||
//do something
|
||||
}
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
};
|
||||
|
||||
Timer timer = new Timer();
|
||||
TimerTask timerTask = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
Message message = new Message();
|
||||
message.what = 1;
|
||||
handler.sendMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
//主线程中调用:
|
||||
timer.schedule(timerTask, 1000, 500);//延时1s,每隔500毫秒执行一次run方法
|
||||
3.Thread+handler方法:
|
||||
|
||||
final Handler handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (msg.what == 1) {
|
||||
//do something
|
||||
}
|
||||
super.handleMessage(msg);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class MyThread extends Thread {//这里也可用Runnable接口实现
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(1000);//每隔1s执行一次
|
||||
Message msg = new Message();
|
||||
msg.what = 1;
|
||||
handler.sendMessage(msg);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//主线程中调用:
|
||||
new Thread(new MyThread()).start();
|
||||
4.ScheduledThreadPoolExecutor方法:
|
||||
|
||||
private ScheduledThreadPoolExecutor mThreadPoolExecutor;
|
||||
if (mThreadPoolExecutor != null) {
|
||||
mThreadPoolExecutor.shutdownNow();
|
||||
}
|
||||
mThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
|
||||
mThreadPoolExecutor.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
}, 0, 500, TimeUnit.MILLISECONDS);
|
||||
二、三种延时的快捷方法:
|
||||
1.Handler的postDelayed方法:
|
||||
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//do something
|
||||
}
|
||||
}, 1000); //延时1s执行
|
||||
2.timer + TimerTask方法:
|
||||
|
||||
Timer timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
//do something
|
||||
}
|
||||
},1000);//延时1s执行
|
||||
3.Thread方法:
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(1000);//延时1s
|
||||
//do something
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
自带定时器 CountDownTimer
|
||||
利用 CountDownTimer 实现一个时长为 5 秒的 View 倒计时显示,要求从 5s 开始每隔 1 秒倒计时显示到 1s
|
||||
|
||||
|
||||
CountDownTimer countDownTimer = new CountDownTimer(totalTime, 2000) {
|
||||
@Override
|
||||
public void onTick(long millisUntilFinished) {
|
||||
updateFileData(fileId); //执行任务
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
if (User.getInstance().isLoginIng()) {
|
||||
if (countDownTimer != null) {
|
||||
countDownTimer.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
countDownTimer.start();
|
||||
|
||||
|
||||
三、定时轮询
|
||||
为什么使用Service
|
||||
普通的线程也可以达到在后台做事情的功能,那么为什么使用 Service呢?是因为 Service是系统的组件,它的优先级比普通的线程要高,
|
||||
不容易被系统回收。而且 线程不好控制,Service相对好控制一些。运行在前台的Activity是不会被系统回收 的,而Service如果不想被
|
||||
系统回收,就需要在Service中设置一下
|
||||
startForeground(int,Notification)
|
||||
具体的使用场景有:
|
||||
a、拥有长连接QQ
|
||||
b、定时轮询
|
||||
c、服务里面注册广播接收者。有些广播接收者只能通过代码注册,比如屏幕锁屏、 屏幕解锁、电量发生变化等。
|
||||
e、IntentService
|
||||
Android RxJava 实际应用讲解:(无条件)网络请求轮询
|
||||
https://www.jianshu.com/p/11b3ec672812
|
||||
|
||||
|
||||
四、沉浸式框架implementation 'com.hannesdorfmann.mosby3:mvp:3.0.0-alpha4'
|
||||
|
||||
五、获取结点元素 方式一:
|
||||
// 遍历root下的子节点有哪些
|
||||
for (int i = 0; i < root.getChildCount(); i++) {
|
||||
AccessibilityNodeInfo child = root.getChild(i);
|
||||
Log.e("TIAOSHI###", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription());
|
||||
if ("dmt.viewpager.DmtViewPager$d".equals(child.getClassName())) {
|
||||
Log.e("TIAOSHI###ViewPager", "----twoNode:" + child.getChildCount());
|
||||
for (int y = 0; y < child.getChildCount(); y++) {
|
||||
AccessibilityNodeInfo child1 = child.getChild(y);
|
||||
Log.e("TIAOSHI###", "----twoNode:" + child1.getClassName() + ":" + child1.getText() + ":" + child1.getContentDescription());
|
||||
if ("android.widget.TabHost".equals(child1.getClassName())) {
|
||||
for (int j = 0; j < child1.getChildCount(); j++) {
|
||||
AccessibilityNodeInfo child2 = child1.getChild(j);
|
||||
Log.e("TIAOSHI###", "----threeNode:" + child2.getClassName() + ":" + child2.getText());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
六、横向滑动
|
||||
AblViewUtil.scrollHorizontal(10,600,100,600, new GestureCallBack() {
|
||||
@Override
|
||||
public void succ(GestureDescription gestureDescription) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(GestureDescription gestureDescription) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
七、停止服务
|
||||
AblStepHandler.getInstance().setStop(true);
|
||||
|
||||
八、定时器
|
||||
private void daojishizreo(int a) {
|
||||
//启动计时器
|
||||
//从0开始发射11个数字为:0-10依次输出,延时0s执行,每1s发射一次。
|
||||
mdDisposable = Flowable.intervalRange(0, a + 1, 0, 1, TimeUnit.SECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext(new Consumer<Long>() {
|
||||
@Override
|
||||
public void accept(Long aLong) throws Exception {
|
||||
long b = a - aLong;
|
||||
|
||||
}
|
||||
})
|
||||
.doOnComplete(new Action() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
AblStepHandler.getInstance().setStop(true);
|
||||
Log.e("TIAOSHI###", "停止了");
|
||||
}
|
||||
})
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
|
||||
九、for循环找控件
|
||||
/**
|
||||
* 寻找留下你的精彩评论
|
||||
*/
|
||||
private AccessibilityNodeInfo findcoment() {
|
||||
AccessibilityNodeInfo infooos=null;
|
||||
AccessibilityNodeInfo rootttt = AblService.getInstance().getRootInActiveWindow();
|
||||
for (int j = 0; j < rootttt.getChildCount(); j++) {
|
||||
AccessibilityNodeInfo child = rootttt.getChild(j);
|
||||
Log.e("TIAOSHI###", "----1Node:" + child.getClassName() + ":" + child.getText());
|
||||
if (!"dmt.viewpager.DmtViewPager$d".equals(child.getClassName())) {
|
||||
// Log.e("TIAOSHI###ViewPager", "----2Node:" + child.getChildCount());
|
||||
for (int y = 0; y < child.getChildCount(); y++) {
|
||||
AccessibilityNodeInfo child1 = child.getChild(y);
|
||||
Log.e("TIAOSHI###", "----2Node:" + child1.getClassName() + ":" + child1.getText());
|
||||
// if ("android.widget.LinearLayout".equals(child1.getClassName())) {
|
||||
for (int x = 0; x < child1.getChildCount(); x++) {
|
||||
AccessibilityNodeInfo child6 = child1.getChild(x);
|
||||
Log.e("TIAOSHI###", "----3Node:" + child6.getClassName() + ":" + child6.getText());
|
||||
for (int z = 0; z < child6.getChildCount(); z++) {
|
||||
AccessibilityNodeInfo child7 = child6.getChild(z);
|
||||
// Log.e("TIAOSHI###", "----4Node:" + child7.getClassName() + ":" + child7.getText());
|
||||
// if ("android.widget.LinearLayout".equals(child7.getClassName())) {
|
||||
for (int r = 0; r < child7.getChildCount(); r++) {
|
||||
AccessibilityNodeInfo child2 = child7.getChild(r);
|
||||
// Log.e("TIAOSHI###", "----5Node:" + child2.getClassName() + ":" + child2.getText());
|
||||
|
||||
for (int m = 0; m < child2.getChildCount(); m++) {
|
||||
AccessibilityNodeInfo child3 = child2.getChild(m);
|
||||
// Log.e("TIAOSHI###", "----6Node:" + child3.getClassName() + ":" + child3.getText());
|
||||
for (int n = 0; n < child3.getChildCount(); n++) {
|
||||
AccessibilityNodeInfo child4 = child3.getChild(n);
|
||||
// Log.e("TIAOSHI###", "----7Node:" + child4.getClassName() + ":" + child4.getText());
|
||||
|
||||
for (int k = 0; k < child4.getChildCount(); k++) {
|
||||
AccessibilityNodeInfo child5 = child4.getChild(k);
|
||||
// Log.e("TIAOSHI###", "----8Node:" + child5.getClassName() + ":" + child5.getText());
|
||||
|
||||
for (int p = 0; p < child5.getChildCount(); p++) {
|
||||
AccessibilityNodeInfo child8 = child5.getChild(p);
|
||||
// Log.e("TIAOSHI###", "----9Node:" + child8.getClassName() + ":" + child8.getText());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// }
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
return infooos;
|
||||
}
|
||||
|
||||
十、超级大坑 目前无解
|
||||
在做验证码登录的是时候,getRootInActiveWindow()方法的返回值为null,getWindow()方法也为null,网上查遍资料也没有
|
||||
印象笔记搜索:getRootInActiveWindow()方法的返回值为null
|
||||
解决办法是让,也没先返回home,然后再打开就可以了。
|
||||
|
||||
十一、导入手机联系人
|
||||
遇到的两个问题:1是内容提供者的配置
|
||||
2是权限的问题
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.READ_CONTACTS);
|
||||
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED){
|
||||
requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS},REQUEST_CODE_ASK_PERMISSIONS);
|
||||
// return;
|
||||
}
|
||||
}
|
||||
加入这段代码就好了。
|
||||
|
||||
十二、绑定服务 https://blog.csdn.net/imxiangzi/article/details/76039978?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control
|
||||
|
||||
十三、WindowManager.LayoutParams详解 https://blog.csdn.net/weixin_34055787/article/details/92576555
|
||||
|
||||
十四、在Android中用广播监听AccessibilityService的开启状态并更新UI界面https://blog.csdn.net/huang826336127/article/details/80139543
|
||||
|
||||
十五、Android RxJava/RxAndroid:takeWhile,直test测试条件通过才执行链式操作TestAblStep12
|
||||
https://blog.csdn.net/zhangphil/article/details/79882700
|
||||
|
||||
十六、关机重启
|
||||
AblStepHandler.getInstance().setStop(false);
|
||||
AblStepHandler.sendMsg(AblSteps.STEP_25);
|
||||
|
||||
十七、退出抖音
|
||||
AblStepHandler.getInstance().setStop(false);
|
||||
AblStepHandler.sendMsg(AblSteps.STEP_192);//检测我的页面弹出了好友推荐对话框,并关闭
|
||||
十八、捕捉弹框(获取事件)
|
||||
// TODO Auto-generated method stub
|
||||
// System.out.println("Enter->onAccessibilityEvent");
|
||||
//判断是否是通知事件typeAnnouncement
|
||||
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){
|
||||
List<CharSequence> text = event.getText();
|
||||
if(text.size()>0) {
|
||||
CharSequence charSequence = text.get(0);
|
||||
String s = charSequence.toString();
|
||||
Log.e("TIAOSHI", "有弹出");
|
||||
Log.e("TIAOSHI", "有弹出==" + s);
|
||||
//获取消息来源
|
||||
String sourcePackageName = (String) event.getPackageName();
|
||||
//获取事件具体信息
|
||||
Parcelable parcelable = event.getParcelableData();
|
||||
//如果是下拉通知栏消息
|
||||
if (parcelable instanceof Notification) {
|
||||
} else {
|
||||
//其它通知信息,包括Toast
|
||||
String toastMsg = (String) event.getText().get(0);
|
||||
Log.e("TIAOSHI", "有弹出" + toastMsg);
|
||||
Log.e("Latest Toast Message:", "" + toastMsg + " [Source: " + sourcePackageName + "]");
|
||||
EventBus.getDefault().post(new SixEvent("success", toastMsg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void getdouyin() {
|
||||
int num = 0;
|
||||
accessibilityNodeInfos = new ArrayList<>();
|
||||
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 ("androidx.viewpager.widget.ViewPager".equals(child.getClassName())) {
|
||||
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());
|
||||
for (int r = 0; r < child3.getChildCount(); r++) {
|
||||
AccessibilityNodeInfo child4 = child3.getChild(r);
|
||||
Log.e("TIAOSHI###", "----5Node:" + child4.getClassName() + ":" + child4.getText()+ ":" + child4.getContentDescription());
|
||||
for (int m = 0; m < child4.getChildCount(); m++) {
|
||||
AccessibilityNodeInfo child5 = child4.getChild(m);
|
||||
Log.e("TIAOSHI###", "----6Node:" + child5.getClassName() + ":" + child5.getText()+ ":" + child5.getContentDescription());
|
||||
for (int p = 0; p < child5.getChildCount();p++) {
|
||||
AccessibilityNodeInfo child6 = child5.getChild(p);
|
||||
Log.e("TIAOSHI###", "----7Node:" + child6.getClassName() + ":" + child6.getText()+ ":" + child6.getContentDescription());
|
||||
for (int t = 0; t < child6.getChildCount();t++) {
|
||||
AccessibilityNodeInfo child7 = child6.getChild(t);
|
||||
Log.e("TIAOSHI###", "----8Node:" + child7.getClassName() + ":" + child7.getText()+ ":" + child7.getContentDescription());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
Rect rect = new Rect();
|
||||
child7.getBoundsInScreen(rect);
|
||||
Log.e("TIAOSHI###", "----8Node:" + "(" + rect.left + "," + rect.top + ")" + "," + "(" + rect.right + "," + rect.bottom + ")");
|
||||
|
||||
数据更新进度条:http://www.zyiz.net/tech/detail-56306.html
|
||||
|
||||
抢红包的demo: http://www.voidcn.com/article/p-cujkxxnt-bpb.html
|
||||
85
doc/新增任务功能注释(1).sql
Normal file
85
doc/新增任务功能注释(1).sql
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
-- 直播间抢抖币
|
||||
{
|
||||
"success": 4,
|
||||
"msg": "执行固定任务",
|
||||
"data": {
|
||||
"task_type": "4", -- 固定任务
|
||||
"short_id": "tangjie0501", -- 抖音号
|
||||
"short_name": "软件工程师蝴蝶剑", -- 抖音名称
|
||||
"task_id": "3000def9108812dbd2df76980516532e", -- 任务id
|
||||
"start_time": "09:00:00", -- 开始时间
|
||||
"end_time": "16:00:00", -- 结束时间
|
||||
"create_time": "2021-01-12 18:31:22", -- 创建时间
|
||||
"function_execute": {
|
||||
"id": 1, -- 任务功能id
|
||||
"task_id": "3000def9108812dbd2df76980516532e", -- 任务id
|
||||
"account_duration": 2, -- 单账号时长(h)
|
||||
"live_num": 10, -- 直播间个数
|
||||
"change_time": 3, -- 切换时间设置(s)
|
||||
"live_speech": 1, -- 直播间话术是否开启 1:开启 0:关闭'
|
||||
"live_click": 1, -- 是否点赞 1:是 0:否
|
||||
"grab_lucky_bag": 1, -- 是否抢福袋 1:是 0:否
|
||||
"bag_min_coin": 1, -- 抢福袋时,抖币的最小数字,小于则不参与
|
||||
"grab_red_envelopes": 1, -- 是否抢红包 1:是 0:否
|
||||
"red_min_coin": 1, -- 抢红包时,抖币的最小数字,大于参与
|
||||
"create_time": "2021-07-01 10:48:37", -- 创建时间
|
||||
"task_type": 1, -- 任务类型(1:固定 0:临时)
|
||||
"if_quguan": 1, -- 0:要取关,1:不要取关
|
||||
"touch_num": "0" -- 撞号数量
|
||||
},
|
||||
"func_type": "5" -- 任务功能是直播间抢抖币
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- 直播间加热
|
||||
|
||||
{
|
||||
"success": 4,
|
||||
"msg": "执行固定任务",
|
||||
"data": {
|
||||
"task_type": "4", -- 固定任务
|
||||
"short_id": "tangjie0501", -- 抖音id
|
||||
"short_name": "软件工程师蝴蝶剑", -- 抖音名
|
||||
"task_id": "3000def9108812dbd2df76980516532e", -- 任务id
|
||||
"start_time": "09:00:00",-- 开始时间
|
||||
"end_time": "16:00:00", -- 结束时间
|
||||
"create_time": "2021-01-12 18:31:22", -- 创建时间
|
||||
"function_execute": {
|
||||
"id": 1, -- 任务功能id
|
||||
"task_id": "3000def9108812dbd2df76980516532e", -- 任务id
|
||||
"account_duration": 1, -- 单账号时长(h)
|
||||
"live_nickname": "12", -- 加热直播间抖音昵称
|
||||
"live_come": 1, -- 进直播间方式 1:直播广场 2:关注列表
|
||||
"live_speech": 1, -- 直播间话术是否开启 1:开启 0:关闭
|
||||
"live_click": 0, -- 是否点赞 1:是 0:否
|
||||
"live_documentary": 1, -- 直播间跟单 1:是 0:否
|
||||
"fans_gift": 1, -- 优先粉丝团礼物 1:是 0:否
|
||||
"fans_gift_type": 1, -- 礼物类型 1:固定礼物 2:全部礼物
|
||||
"gift_heart": 1, -- 心心相吸的个数
|
||||
"gift_time_min": 3, -- 随机间隔时间的最小时间(分)
|
||||
"gift_time_max": 10, -- 随机间隔时间的最大时间(分)
|
||||
"grab_lucky_bag": 1, -- 是否抢福袋 1:是 0:否
|
||||
"bag_min_coin": 1, -- 抢福袋时,抖币的最小数字,小于则不参与
|
||||
"grab_red_envelopes": 1, -- 是否抢红包 1:是 0:否
|
||||
"red_min_coin": 2, -- 抢红包时,抖币的最小数字,大于参与
|
||||
"create_time": "2021-07-01 10:50:51", -- 创建事假
|
||||
"task_type": 1, -- 任务类型(1:固定 0:临时)
|
||||
"if_quguan": 1, -- 0:要取关,1:不要取关
|
||||
"touch_num": "0" -- -- 撞号数量
|
||||
},
|
||||
"func_type": "6" -- 任务功能是直播间加热
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-- 直播间抢抖币任务、或 直播间加热任务执行完毕后,调取的接口,统计抖币
|
||||
app/Appscanlogin/taskDbTj
|
||||
-- 直播间话术接口
|
||||
app/Appscanlogin/liveScript
|
||||
-- 获取直播间数据
|
||||
app/Appoperate/LiveRoom
|
||||
-- 返回最后一次关注直播间id
|
||||
app/Appoperate/returnRoomid
|
||||
8
doc/硬件信息
Normal file
8
doc/硬件信息
Normal file
@@ -0,0 +1,8 @@
|
||||
红米7A分辨率屏幕分辨率: 1520 x 720 HD
|
||||
|
||||
|
||||
红米10屏幕分辨率: 宽1080==高2167
|
||||
|
||||
|
||||
|
||||
红米9note宽1080==高2111
|
||||
104
doc/策略模式
Normal file
104
doc/策略模式
Normal file
@@ -0,0 +1,104 @@
|
||||
看下策略模式的定义
|
||||
策略模式定义了一些列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变换。
|
||||
|
||||
首先,需要定义一个策略接口。
|
||||
|
||||
public interface Strategy {
|
||||
void travel();
|
||||
}
|
||||
然后根据不同的出行方式实行对应的接口
|
||||
|
||||
public class WalkStrategy implements Strategy{
|
||||
|
||||
@Override
|
||||
public void travel() {
|
||||
System.out.println("walk");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class PlaneStrategy implements Strategy{
|
||||
|
||||
@Override
|
||||
public void travel() {
|
||||
System.out.println("plane");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class SubwayStrategy implements Strategy{
|
||||
|
||||
@Override
|
||||
public void travel() {
|
||||
System.out.println("subway");
|
||||
}
|
||||
}
|
||||
此外还需要一个包装策略的类,并调用策略接口中的方法
|
||||
|
||||
public class TravelContext {
|
||||
Strategy strategy;
|
||||
|
||||
public Strategy getStrategy() {
|
||||
return strategy;
|
||||
}
|
||||
|
||||
public void setStrategy(Strategy strategy) {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
public void travel() {
|
||||
if (strategy != null) {
|
||||
strategy.travel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
测试一下代码
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
TravelContext travelContext=new TravelContext();
|
||||
travelContext.setStrategy(new PlaneStrategy());
|
||||
travelContext.travel();
|
||||
travelContext.setStrategy(new WalkStrategy());
|
||||
travelContext.travel();
|
||||
travelContext.setStrategy(new SubwayStrategy());
|
||||
travelContext.travel();
|
||||
}
|
||||
}
|
||||
|
||||
输出结果如下
|
||||
plane
|
||||
walk
|
||||
subway
|
||||
|
||||
|
||||
5 策略模式的优点与缺点
|
||||
策略模式主要用来分离算法,根据相同的行为抽象来做不同的具体策略实现。很好的实现了开闭原则,也就是定义抽象,注入具体实现,从而达到很好的可扩展性。
|
||||
|
||||
优点
|
||||
|
||||
使用了组合,使架构更加灵活
|
||||
|
||||
富有弹性,可以较好的应对变化(开闭原则)
|
||||
|
||||
更好的代码复用性(相对于继承)
|
||||
|
||||
消除大量的条件语句
|
||||
|
||||
缺点
|
||||
|
||||
随着策略的增加,子类也会变得繁多。
|
||||
|
||||
选择何种算法需要客户端来创建对象,增加了耦合,这里可以通过与工厂模式结合解决该问题;
|
||||
|
||||
策略模式设计原则:
|
||||
|
||||
找出应用中需要变化的部分,把它们独立出来,不要和那些不需要变化的代码混在一起
|
||||
面向接口编程,而不是面向实现编程
|
||||
多用组合,少用继承
|
||||
6 总结
|
||||
策略模式在开发应用场景很多,平时有意识的运用好策略模式,可以很好的提高的程序的可维护性和可扩展性。
|
||||
|
||||
|
||||
策略模式和工厂模式搭配使用
|
||||
15
doc/评论话术
Normal file
15
doc/评论话术
Normal file
@@ -0,0 +1,15 @@
|
||||
1.好几次看到你了~缘分互关一下吧!互赞三个!
|
||||
2.拍的不错,好几次看到你了~缘分互关一下吧!,互赞三个!
|
||||
3.你的视频真好~互关一下,互赞三个!
|
||||
4.唉~好几次看到你了~缘分互关一下,互赞三个!
|
||||
5.看到你好几次了~互赞三个互关吧!
|
||||
6.在吗?互关一下互赞三个吧,我看到你好几次了
|
||||
7.感谢关注~我的作品评论一下吧
|
||||
8.最新的作品评论一下吧!感谢
|
||||
9.最近发了几个好笑视频~求点赞
|
||||
10.忙啥呢~互赞三个好吗?
|
||||
11.一直关注你互赞三个吧!
|
||||
12.hi~我发的搞笑视频看了吗?赞一下吧
|
||||
13.互赞三个~好吗?
|
||||
14.挺喜欢你的视频的,互关然后互赞三个吧
|
||||
15.期待更新更多作品啊~互关后互赞三个吧
|
||||
39
doc/适配资料
Normal file
39
doc/适配资料
Normal file
@@ -0,0 +1,39 @@
|
||||
1.//加关注(659,576)
|
||||
AccessibilityNodeInfo guanzhu = guanzhu();
|
||||
遍历找结点有可能出错,此处用到坐标点点击
|
||||
2.点击评论
|
||||
// (659, 810);
|
||||
commentClick(AblService.getInstance());
|
||||
用到坐标点点击
|
||||
|
||||
3.点击留下你的精彩评论吧
|
||||
AblService.getInstance().clickPoint(153, 1292, 300);//红米7a
|
||||
用到坐标点点击
|
||||
|
||||
|
||||
4.匹配抖音14.6版本
|
||||
推荐加关的修改地方,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
_______________________________________________________________________________________________________
|
||||
_______________________________________________________________________________________________________
|
||||
适配华为手机需要修改的地方
|
||||
AblService.getInstance().clickPoint(153, 1292, 300);//红米7a
|
||||
21
doc/项目进度
Normal file
21
doc/项目进度
Normal file
@@ -0,0 +1,21 @@
|
||||
1.后台派取关任务可以执行
|
||||
2.后台派登录任务可以执行
|
||||
3.后台派撞号任务可以执行
|
||||
4.后台派停止任务可以执行
|
||||
5.测试网络版本的帐号登录成功
|
||||
6.测试后台派一个固定的推荐加关的任务,然后再将任务停止。 此处场景是先开启一个固定任务,然后再接收一个紧急的停任务。
|
||||
此处有一个核心逻辑,最后三个参数,传值分两种情况,一、如果来的紧急任务是一个停任务,那么就传空。二、如果来的紧急任务是一个其它任务。那么就传值
|
||||
7.测试后台派一个固定的推荐加关的任务,然后再将任务停止,再拍一条紧急加关的任务,再停止。
|
||||
核心逻辑: //是否有当前有执行任务,如果没有任务执行,则:
|
||||
//初始化5秒的接口参数
|
||||
ChangLiang.task_id = "";//当前执行任务id
|
||||
ChangLiang.id = "";//当前执行任务功能id
|
||||
ChangLiang.task_type = "";//当前执行任务类型
|
||||
8.后台派固定任务撞号可以执行成功
|
||||
9.后台派紧急任务撞号可以执行成功
|
||||
|
||||
|
||||
8月16日 完成了 自动打开无障碍功能
|
||||
8月17日 完成了 直播间加热点赞逻辑的功能,修复若干闪退的bug
|
||||
8月18日 完成了 修复了直播间加热bug,对软件运行性能进行优化
|
||||
|
||||
Reference in New Issue
Block a user