滚动阅读
title: 滚动阅读 date: 2019-10-25 20:04:22
tags:
初步构思
- 定时任务启动
- 滑到面板桌面(从常规桌面上滑)
- 点击礼盒图标(右上角,测量位置)
- 点击完成相关任务(位置)
- 自动唤醒京东读书 app
- 点击图书(位置)
- 自动翻页(swipe)
- 完成后返回打卡页面
- 点击完成打卡(位置)
新增:
- 时间统计(共阅读了多久)
- 页数统计(共阅读了多少页)
防检测
自动翻页位置
- 滑动翻页(swipe) Math.random
- 点击翻页(touch),时间和位置都随机
- 映射音量键翻页
该机分辨率为 1440*720
下一页触摸区域在 x(480-720),y(0-1440)
规则:
30 分钟阅读 300 页,则每分钟阅读 10 页,至少 6 秒阅读完一页.
1 | 6000 * (Math.random() + 1); |
每页最少 6 秒,最多 12 秒不到.
每 300 页最少 30 分钟.最多 60 分钟不到.
随机时间
1 | var initTime = 6000 * (Math.random() + 0.33333); |
每页最少 2 秒,最多 8 秒不到.
每 300 页最少不到 16 分钟.最多 40 分钟不到.
定时运行脚本
点击脚本右边的菜单按钮->更多->定时任务设置定时运行脚本.注意必须保持 Auto.js 后台运行(自启动白名单、电源管理白名单等),不可加锁屏密码.
脚本的开头使用 device.wakeUp()来唤醒屏幕
1 | //# 启动app |
气泡信息toast(message)
注意,信息的显示是”异步”执行的,并且,不会等待信息消失程序才继续执行。如果在循环中执行该命令,可能出现脚本停止运行后仍然有不断的气泡信息出现的情况
官方貌似说了会实时显示进度,那么下面的统计就不需要了.
这里可以显示已经看了几页(估计得写个函数),看具体是怎么翻页了
1 | 如果触发一次, 就次数`total += 1`; |
1 | if (total >= 300 && totalTime >= 30 * 6000) { |
立即停止exit()
console.show()
显示控制台。这会显示一个控制台的悬浮窗(需要悬浮窗权限)。
print(text)
text {string} | {Object}
要打印到控制台的信息,相当于 log(text)。
基于坐标的触摸模拟
要获取要点击的位置的坐标,可以在开发者选项中开启”指针位置”。
setScreenMetrics(width, height)
设置脚本坐标点击所适合的屏幕宽高.
如果脚本运行时,屏幕宽度不一致会自动放缩坐标.
安卓 7.0 以上的触摸和手势模拟
click(x, y)
模拟点击坐标(x, y),并返回是否点击成功。只有在点击执行完成后脚本才继续执行。
使用该函数模拟连续点击时可能有点击速度过慢的问题,这时可以用press()
函数代替。
press(x, y, duration)
duration: {number}
按住时长,单位毫秒
模拟按住坐标(x, y), 并返回是否成功。只有按住操作执行完成时脚本才会继续执行。
如果按住时间过短,那么会被系统认为是点击;如果时长超过 500 毫秒,则认为是长按。
swipe(x1, y1, x2, y2, duration)
x1
{number} 滑动的起始坐标的 x 值
y1
{number} 滑动的起始坐标的 y 值
x2
{number} 滑动的结束坐标的 x 值
y2
{number} 滑动的结束坐标的 y 值
duration
{number} 滑动时长,单位毫秒
模拟从坐标(x1, y1)滑动到坐标(x2, y2),并返回是否成功。只有滑动操作执行完成时脚本才会继续执行。
随机数 random
random(min, max)
min
{number} 随机数产生的区间下界
max
{number} 随机数产生的区间上界
返回 {number}
返回一个在[min...max]
之间的随机数(正整数)。例如random(0, 2)
可能产生 0, 1, 2。
random()
返回 {number}
返回在[0, 1)的随机浮点数。
device.wakeUp()
唤醒设备。包括唤醒设备 CPU、屏幕等。可以用来点亮屏幕。
device.wakeUpIfNeeded()
如果屏幕没有点亮,则唤醒设备。
按键模拟
实体按键模拟依赖 root 权限,故放弃.
基于控件的操作
推荐使用auto()
函数来确保无障碍服务已启用.
auto([mode])
检查无障碍服务是否已经启用,如果没有启用则抛出异常并跳转到无障碍服务启用界面;同时设置无障碍模式为 mode。
如果不加 mode 参数,则为正常模式。
建议使用auto.waitFor()
和auto.setMode()
代替该函数,因为auto()
函数如果无障碍服务未启动会停止脚本;而auto.waitFor()
则会在在无障碍服务启动后继续运行。
auto.waitFor()
检查无障碍服务是否已经启用,如果没有启用则跳转到无障碍服务启用界面,并等待无障碍服务启动;当无障碍服务启动后脚本会继续运行。
点击文本click(text[, i])
text
{string} 要点击的文本
i
{number} 如果相同的文本在屏幕中出现多次,则 i 表示要点击第几个文本, i 从 0 开始计算
该函数可以点击大部分包含文字的按钮。例如微信主界面下方的”微信”, “联系人”, “发现”, “我”的按钮。
通常与 while 同时使用以便点击按钮直至成功。例如:
1 | while (!click("扫一扫")); |
UiSelector.exists()
返回 {Boolean}
判断屏幕上是否存在控件符合选择器所确定的条件。
例如要判断某个文本出现就执行某个动作,可以用:
1 | if (text("某个文本").exists()) { |
暂停 sleep()
1 | //暂停1秒 |
选取控件
一般软件的界面是由一个个控件构成的,例如图片部分是一个图片控件(ImageView),文字部分是一个文字控件(TextView);同时,通过各种布局来决定各个控件的位置,例如,线性布局(LinearLayout)里面的控件都是按水平或垂直一次叠放的,列表布局(AbsListView)则是以列表的形式显示控件。
控件有各种属性,包括文本(text), 描述(desc), 类名(className), id 等等。我们通常用一个控件的属性来找到这个控件,例如,想要点击 QQ 聊天窗口的”发送”按钮,我们就可以通过他的文本属性为”发送”来找到这个控件并点击他,具体代码为:
1 | var sendButton = text("发送").findOne(); |
在这个例子中, text(“发送”)表示一个条件(文本属性为”发送”),findOne()表示基于这个条件找到一个符合条件的控件,从而我们可以得到发送按钮 sendButton,再执行 sendButton.click()即可点击”发送”按钮。
果一个控件是图片控件.我们注意到这个图标的 desc(描述)属性为”搜索”,那么我们就可以通过 desc 属性来定位这个控件,得到点击搜索图标的代码为:
1 | desc("搜索").findOne().click(); |
另外,对于这个搜索图标而言,id 属性也是唯一的,我们也可以用 id(“action_search”).findOne().click()来点击这个控件。如果一个控件有 id 属性,那么这个属性很可能是唯一的.
i_reader_folder
定时器 Timers
setTimeout()
与 web 端用法一致.但是使用了一个不同的内部实现,它是基于 Android Looper-Handler 消息循环机制构建的。其实现机制与 Node.js 比较相似.
setInterval(callback, delay[,…args])
callback {Function} 当定时器到点时要调用的函数。
delay {number} 调用 callback 之前要等待的毫秒数。
…args {any} 当调用 callback 时要传入的可选参数。
因为定时器是异步执行,另外 delay 只能是 number,那么不采用这种方案.
刷页函数
1 | function turnPage(){ |
准备工作
先打开京东读书,登录账号
点击书城-免费-点击一本书-加入书架-(多加几本)
方案一: 点击翻页
1 | //检查无障碍服务开启情况 |
这里有问题
应该阅读到末尾结束,出现关闭阅读.点击关闭阅读.删除第一本.重新打开一本,开始阅读.
1 | //已读完时,左上角出现关闭阅读 |
开始阅读-阅读完-跳出阅读-删除-重新开始阅读
1 | //执行阅读主步骤 |