最近答题类 app 比较火, 玩了几把之后想到为什么不用技术来查找答案呢? 因此搞了一款辅助 app, 能够帮助大家直接搜索答案. 经过两天的开发和三天的测试, 终于让我的冲顶率达到了 80% 左右, 先上几个不错的战绩装个逼.
一. 用 app 去冲顶
这一节是教大家如何使用 app 的, 如果对使用 app 不感兴趣, 想了解技术的同学, 可以直接去第二节, 新建了一个辅助交流 QQ 群: 314100393, 大家有问题可以来这个群里问
1. 让 app 跑起来
安装 app 点击下载 app
进入手机的文件管理器, 在本 app 的 cache 目录下面新建 tessdata 目录 和 ShotImage 目录例如我的小米 Mix2 的目录是: Android/data/com.example.whensunet.chongdingdahui/cache
将 chi_sim.traineddata 文件放入上面新建的 tessdata 文件夹中, 这个文件是 ocr 识别的语言库, 没有的话就只能查找题干, 不能查找选项点击下载语言库
在 设置 > 无障碍 / 辅助功能 > WhenSunsetBaiWanYinXiongFuZhu 中点击开启, 开启 app 的服务
下载夸克浏览器, 这个浏览器比较轻便, 能够减少查找答案的时间
打开 app, 同意所有权限要求, 点击屏幕上的按钮, 选择搜索引擎
此时只要点击本 app 或冲顶大会的 app 的任意按钮, 就会跳转到夸克浏览器对按钮的内容或者题干 + 按钮内容进行搜索 , 点击屏幕最底端到屏幕最底端上升 500 像素内的按钮会直接搜索题干
如果无效请 进入设置中找到 app 的权限界面, 然后开启所有权限
本 app 目前适配了 mi5mix2 谷歌 nexus5 和小米 Max, 适用于 5.0 以上的 android 系统, 其他手机可能不能搜索按钮内容, 但是题干一般情况下所有手机都能搜索
2. 举个例子
以冲顶大会 app 来举个例子
点击 2 区域中任意选项按钮, 将会搜索题目 + 选项内容
注意需要让弹幕处于静止状态, 要不然可能会搜索到错误答案
如果要单独搜索题干, 那么需要在 3 区域点击右下角的按钮, 将 3 区域的输入框唤出并将其限制在 3 区域中, 最后点击输入框, 这样就能搜索题干了
3. 冲顶经验
经过 3 天的测试, 我的冲顶率已经达到了 80% 左右, 所以分享几个使用辅助的经验
12 道题目中一般会有 10 题是只需要搜索题干的
一般来说可以准备两只手机, 一只运行速度快的手机进行答案的搜索, 再搜索到答案之后先帮另一只手机选择答案, 然后点击返回键回到本手机的冲顶大会选择答案
比较难的场次会有 1-2 道需要查询选项的题目, 此时需要两到三个人, 每个人查一个选项, 这样能够确保总结出最后的正确答案
一般来说 ios 系统的直播速度比 android 系统慢 2-3 秒, 可以利用好这个时间差, 延长找答案的时间建议第二只手机使用 iphone 或者 ipad
建议如果两个人搜索答案的话, 可以一个人使用谷歌搜索, 一个人使用百度搜索
二. app 用到的技术解析
本节是对本 app 使用到的技术进行解析, 没有兴趣的同学可以直接跳过.
1. 需要实现的功能分析
监听冲顶大会 app 在前台的时候, 我们点击按钮的事件
获取到被点击按钮的文字内容
如果不能获取被点击按钮的文字内容, 需要使用 ocr 技术, 对图片进行文字解析
为了在 3 的情况下获取到图片, 我们需要在运行后台 service 的时候对屏幕进行截图
获取到查找内容之后拼接搜索引擎的 url, 调起浏览器
###2. 确定了需求之后要使用的技术 1. 使用 android 内置的无障碍服务可以实现监听冲顶大会 app 的各种事件 2. 我测试的时候发现, 冲顶大会做了某些处理, 使得不能通过无障碍来获取选项按钮的文字内容, 只能获取该 view 的区域此时我就想到额使用 ocr 技术, 来识别该区域的文字具体的库是 tess-two, 这是一个 c++ 的库, 需要开发者自己编译出 so 文件然后调用 java 层的 api, 来实现 ocr 识别 3. 在运行在后台的情况下, 对屏幕进行截图这里 5.0 起的 android 系统提供了 MediaProjection 这个 api, 能够获取当前屏幕的帧至于 5.0 以下需要 root 才能在后台进行屏幕截图, 所以就放弃了 4. 可以通过 Intent 和浏览器包名, 调起指定浏览器这里我用了比较简洁快速的夸克浏览器
3. 代码详解
因为某些原因, 打算过一段时间之后再放出源码, 所以这里就讲解一下, app 整个运行流程. 当然我放出的 apk 是 debug 版, 大家如果会反编译的话, 还是能看见源码的
首先是在 MainActivity 中初始化一些东西
初始化 tess-two 的库
向用户请求无障碍和屏幕截图的权限
运行无障碍 service
1 结束之后, 此时无障碍 service 已经运行起来了, 当我们点击冲顶大会的一个按钮的时候
进入了 **onAccessibilityEvent()** 方法
进入了按钮点击的事件
获取题干信息, 这里我们需要注意到的问题是, 冲顶大会的题干是不可点击的, 所以在 getQuestionRecursion 方法中我会获取到, 当前界面的 Root View 树的结构, 然后递归寻找每个 view 中符合题干特征的文字.(这里需要大家对 view 的绘制原理和 view 树的结构有一定的了解)
方法传入的 getRootInActiveWindow() 是获取到当前屏幕上面 window 的 view 树结构
可以看见方法内部就是对 view 树进行递归查找
判断点击区域是否在只查询题干的区域, 有了题干信息我们还需要判断, 查的是题干还是选项所以我规定了只要点击了屏幕上某个区域的按钮, 那么就是要对题干进行查询 (细心的同学会发现, 这个区域就是我前面提到的 屏幕底部 到 底部向上 500 像素的区域)getIsSearchQuestion 方法内部如图
内部的结构很简单, 仅仅是比较当前点击的 view 的区域, 是否在我规定的区域内部
如果 3 中返回的字符串不为空, 就表示我们需要直接查询题干, 此时直接调起夸克浏览器, 否则就要识别点击的 view 区域的图像, 来对选项进行查询, 这里我们就只讲 ocr 识别的部分 useOcrToSearch 方法内部如图
这里的代码也很简单, 构造 MediaProjection
通过 MediaProjection 获取一个 VirtualDisplay 并将 ImageReader 的 Surface 放入
此时 ImageReader 中每时每刻都会暂存一张当前屏幕的图片
接下来就是处理截图, 然后进行 ocr 识别了, 这里使用了 AsyncTask 在其他线程执行操作
前面我们都知道了怎么获取 view 的区域一个 Rect, 使用这个我们就可以将点击的按钮的区域变成一个 bitmap
有了 view 区域的图片, 就可以直接调用 tess-two 的 java api 来进行 ocr 了
最后我们终于获取到了选项的内容, 此时就可以调起浏览器进行搜索了速度挺快的, 我的 mi5 识别起来在 500 毫秒内, 网好的情况下从点击到显示查找界面不会超过 1.5 秒
三. 总结
大家可能会问, 为什么这个 app 不是百万英雄的辅助, 其实有两个原因:
百万英雄玩的人太多, 每场能分的钱等级分化太严重冲顶大会总的奖金少, 但是奖金比较平均
其实上面一个原因是屁话, 哈哈最开始本 app 是针对百万英雄的辅助, 但是头条毕竟是大厂, 技术还是很好的可能是为了防止作弊吧, 西瓜视频的无障碍功能被禁止了 , 所以只能先用冲顶大会试试水但是目前我已经找到了百万英雄的漏洞, 或许下一次博客就是百万英雄的辅助介绍了, 大家如果想知道的话, 要多多关注我哈
在简书上写了一年多的博客, 终于混了一个简书程序员优秀作者的称号, 还是多靠了大家的捧场, 接下还会发表更多关于 android 的高质量文章, 如果大家觉得有帮助希望能多多点赞
最后, 用了本 app 的同学, 如果冲顶成功了, 别忘了发红包哈, 嘿嘿!
来源: https://juejin.im/post/5a745189f265da4e9a492dca