最近在使用心悦俱乐部这个APP,里面有个代币叫G分,可以换游戏道具,但需要每天领取,比较繁琐。于是索性做一个自动领取G分的辅助,姑且叫它G分助手吧。

1. 查看包名和当前Activity

首先使用adb shell连接上手机。在启动应用之后,输入dumpsys activity activities命令查看当前的Activity。

image.png

image.png

可以看到,包名是com.tencent.tgclub,欢迎页是WelcomeActivity,主页面是MainActivity。

2. 查看当前应用布局,View的id等

在Android sdk目录下,有一个tools文件夹。这之中有一个monitor工具,也就是之前的DDMS。连接手机到电脑之后,通过monitor即可看到当前应用界面的布局了。

点击dump view hierarchy

点击dump

当前应用布局

当前应用布局.png

通过monitor工具,我们就可以获取到想要点击View的id,从而为实现模拟点击做好准备。

3. AccessibilityService的配置

Accessibility Service的教程网上一搜一大把,很简单,这里就不赘述了。

AccessibilityService的xml配置文件如下:

android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged|typeViewClicked"

android:accessibilityFeedbackType="feedbackGeneric"

android:accessibilityFlags="flagReportViewIds|flagRequestEnhancedWebAccessibility|flagRetrieveInteractiveWindows"

android:canRequestEnhancedWebAccessibility="true"

android:canRetrieveWindowContent="true"

android:canPerformGestures="true"

android:description="@string/app_name"

android:notificationTimeout="10"

android:packageNames="com.tencent.tgclub" />

其中特别要指出的是,flagRequestEnhancedWebAccessibility这一项,是为了操作WebView中的内容的。最坑的地方在于,在api 26中这个flag就被废弃了,而且我并没有找到替代方法。也就是说,在Android O以后的手机很可能就不能用这个方式了,而且竟然没有可以替代的方式!(只能用Android 7及以前的手机暂时苟一下)

image.png

4. 实现代码

4.1 判断是否开启AccessibilityService的权限

/**

* 检测是否本应用辅助功能开启

*/

fun isAccessibilitySettingsOn(mContext: Context, clazz: Class): Boolean {

var accessibilityEnabled = 0

val service = mContext.packageName + "/" + clazz.canonicalName

try {

accessibilityEnabled = Settings.Secure.getInt(mContext.applicationContext.contentResolver,

Settings.Secure.ACCESSIBILITY_ENABLED)

} catch (e: Exception) {

e.printStackTrace()

}

val mStringColonSplitter = TextUtils.SimpleStringSplitter(':')

if (accessibilityEnabled == 1) {

val settingValue = Settings.Secure.getString(mContext.applicationContext.contentResolver,

Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)

if (settingValue != null) {

mStringColonSplitter.setString(settingValue)

while (mStringColonSplitter.hasNext()) {

val accessibilityService = mStringColonSplitter.next()

if (accessibilityService.equals(service, ignoreCase = true)) {

return true

}

}

}

}

return false

}

/**

* 检查是否开启辅助功能,没有开启就跳转到设置页面

*/

private fun checkAccessibilityOn() {

if (!isAccessibilitySettingsOn(this, GPointService::class.java)) {

mDialog = makeDialog(this,

"需要打开辅助功能",

"点击确定,在设置中找到\"G分助手\",打开辅助功能",

"确定",

DialogInterface.OnClickListener { _, _ -> startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)) },

false)

mDialog!!.show()

}

}

4.2 AccessibilityService的实现

4.2.1 需求分析

拟定功能有三点:

签到

领取月卡积分

喂猫

那么,我们的辅助功能应该是这样的:

每日定时打开心悦app -> 检查今日是否完成以上任务 -(如果没有)-> 执行任务 -> 检查是否成功 [ -> 上报]

4.2.2 思路

在AccessibilityService的onAccessibilityEvent回调方法中,可以接收到在xml中指定app的事件。

/**

* 检测到事件。

*/

override fun onAccessibilityEvent(event: AccessibilityEvent) {

Log.v(TAG, "onAccessibilityEvent: " + AccessibilityEvent.eventTypeToString(event.eventType))

if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {

// window状态改变(切换窗口、显示隐藏、对话框等)

// doSth...

} else if(event.eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {

// 当前window内容改变

// doSth...

}

}

首先检查一下今日任务是否已经执行完毕了,如果是的话就什么都不做。因为不能让辅助妨碍了用户的正常操作,所以在完成了任务之后就不需要再进行操作了。

按照4.2.1中的流程依次执行任务。

执行完毕之后,将结果保存在本地。

4.2.3 设计

思路上捋清楚了,接下来就是具体是设计了。

1. 任务设计

任务的设计主要分为两个方面。第一,数据结构;第二,存储方式。

如何得知当日是否已经执行完毕?执行任务之后如何存储?

最简单可行的想法就是使用SharedPreferences来进行记录,读取之后保存在AccessibilityService中。

private lateinit var mSharedPreferences: SharedPreferences

override fun onServiceConnected() {

Log.d(TAG, "onServiceConnected: GPointService")

mSharedPreferences = getSharedPreferences(SP_NAME, Context.MODE_PRIVATE)

}

另一方面,由于任务状态包括了签到、领取月卡积分、喂猫三项,任务重复性高,如果全都写在AccessibilityService中,冗余度很高,所以单独抽象一个Task基类出来。这样做的好处不仅在于可以减少重复代码,而且如果以后有新的任务,直接继承这个父类即可,利于扩展:

uml1

最后,创建一个TaskManager的单例类,统一管理任务,将职责从AccessibilityService中分割出来。

uml3

这里任务的设计暂告一段落了。

2. 任务执行

在任务执行之后,还需要保存任务的完成状态。对于每日更新的任务来说,每天的任务完成之后,需要将任务标记为已完成,并且在第二天的0点(或其他时候)重新变成未完成。

这个花了我很多时间,主要是比较各种方式的优劣。对于定/延时任务,一般来说有这几种方法:

Timer

Handler

AlarmManager

鉴于任务间隔时间很长,所以这里采用了AlarmManager作为定时任务的方法。

另外,考虑到不同的任务可能会有不同的执行时间和间隔,那么就没法统一执行时间了。这个问题其实还是很棘手的,虽然有不同的解决方案,但是我最后也没有找到一个比较完美的。

最终方案

采用过期时间mExpireTime。对于每个Task来说,执行完毕任务之后,设定一个任务过期时间。任务过期之前为保护期,在保护期内,任务不会再次运行。超过过期时间的,或者没有设置过期时间的,视为过期任务,则执行。同时将isTaskDone()方法修改为shouldRunTask()方法,使其更符合实际逻辑。

每次AccessibilityService的onAccessibilityEvent回调均会调用TaskManager.checkAndRunTasks()方法来检查所有任务是否过期,对于未过期的任务则跳过,只执行已过期的任务。在checkAndRunTasks方法中,会调用每个Task的shouldRunTask方法,检查是否应该运行。

对于TaskManager,简化了外部接口,使得任务的执行更加便捷且清晰;同时当一个任务执行时,其他任务禁止执行,避免互相干扰。

另外对Task类也进行了优化,删去了过度设计的部分。

umllast

4.3 最终代码

虽然因为手里没有Android 7测试样机,具体功能的实现没有办法继续写下去了,不过大体框架已经完成,剩下的内容就是往里面写各个任务的业务逻辑了,甚至根据需求可以添加其他任务。

Github地址是https://github.com/LittleFogCat/gpointhelper,有兴趣的可以自己改着玩。(不过我相信没有人会坚持看到这里。)

事实上,写到这里,我已经不想领G分了。

自动软件签到Android代码,Android辅助工具,G分助手的实现 - 心悦俱乐部app自动签到、领G分...相关推荐

  1. Android辅助工具,G分助手的实现 - 心悦俱乐部app自动签到、领G分

    最近在使用心悦俱乐部这个APP,里面有个代币叫G分,可以换游戏道具,但需要每天领取,比较繁琐.于是索性做一个自动领取G分的辅助,姑且叫它G分助手吧. 这个辅助主要是通过Accessibility Se ...

  2. 心理测试软件需求分析报告,心理测评软件都适用于哪些人群?具体有哪些功能?【心悦灵】...

    原标题:心理测评软件都适用于哪些人群?具体有哪些功能?[心悦灵] 心理测评软件是用来测量人们心理健康状态的心理设备,同时能够建立心理档案,针对心理异常的人们进行心理疏导或心理治疗,在心理咨询工作中起到 ...

  3. JAVA转smali软件_Java2Smali(Java代码转Smali工具)

    Java2Smali(Java代码转Smali工具)是一款可以自动将java代码转换成smali的工具,当然也可以将smali代码转换成java,如果您需要这款工具马上下载Java2Smali(Jav ...

  4. 研究天龙八部(网游), 写了个辅助自动打怪、答题提示的辅助工具

    最近玩了玩天龙八部,玩这个游戏简直就是遭罪,升级非常慢,而且杀怪也很累,纯手工,我都不知道为什么还有那么多人玩.玩到40多级了,实在是受不了,游戏的颜色搭配也是非常的伤眼睛,于是我就想写一个自动打怪的 ...

  5. 代码review辅助工具

    SourceMonitor:代码质量检测工具 SMSetupV3516.exe 主要分析方面是:行数.语句数.分支数.复杂度.函数深度及个数等 使用效果如下图: SourceInsight_Scan: ...

  6. 计算机安全辅助软件,四款国产安全辅助工具对比横评

    360安全卫士.金山卫士.QQ电脑管家和瑞星安全助手是目前国内最为流行的四款安全辅助软件,想必很多网友都有安装其中的某一款作为系统辅助工具.它们的功能总体上都差不多,但也各有各的功能特色,笔者此次将它 ...

  7. 计算机网络布线画图软件,一种计算机网络布线辅助工具的制作方法

    本实用新型涉及计算机网络布线辅助工具技术领域,具体为一种计算机网络布线辅助工具. 背景技术: 综合布线是一种模块化的.灵活性极高的建筑物内或建筑群之间的信息传输通道,通过它可使话音设备.数据设备.交换 ...

  8. sketch生成android代码,Android资源、点九图和 XML Sketch导出工具Android Res Export

    功能 导出多分辨率 PNG 资源 预览和导出多分辨率点九资源 导出矢量(Vector Drawable)资源 导出 Android 8 的自适应图标,圆形图标及旧版应用图标 查看和导出形状图层的 XM ...

  9. android 代码规范检测工具,Android 代码规范之Inspection 定制

    本文主要讲述两个方面: 1)为何制定Radio_Inspections 规范及实操 2)IDE Inspection 使用 第一部分 :为何制定Radio_Inspections 规范及实操 一 .制 ...

  10. 唐诗android代码,Android 唐诗宋词软件(源码讲解)

    取消屏幕标题,软件最大化. requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.Layo ...

最新文章

  1. SAP EWM - 存储类型 - 入库控制
  2. hikaripool连接保持_springboot2的hikari数据库连接池默认配置
  3. 使用ONVIF协议控制海康威视球机
  4. 二叉排序树与文件操作的设计与实现_堆排序就这么简单
  5. ant-design之form-重置表单多个值
  6. 信息学奥赛一本通 1232:Crossing River | OpenJudge NOI 4.6 702:Crossing River
  7. C++之STL种类及实现
  8. 移动互联网之路——Axure RP 8.0网站与APP原型设计从入门到精通
  9. 计算机相关的俚语,现代俄语计算机俚语的构成方式.pdf
  10. cups linux 升级_linux cups版本
  11. 软件测试肖sir__006xmind思维导图实战__微信发红包
  12. 配置文件加密 HikariDataSource
  13. PyImport_ImportModule
  14. 【C语言】共用体的定义与使用
  15. Ubuntu18.04安装ax200网卡驱动以及更新内核
  16. ORACLE DBLINK
  17. (转)日志管理软件logstash
  18. Linux命令英文全称学习
  19. openssl安全漏洞解决方案
  20. 阿里VS腾讯谁将是未来流量之王?

热门文章

  1. shell 截取ip地址最后一位_shell脚本获取IP地址段的方法
  2. HeadFirstJava——1_基本概念
  3. 航模飞机设计基础知识
  4. WPS Office 2012 专业版 附正版序列号
  5. vs C3861 “rand”: 找不到标识符 ConsoleApplication1
  6. Android 系统签名(.pk8、.pem) 制作成 storeFile
  7. .java中jar_java中的jar
  8. SQL Server2008安装详细教程
  9. python百度文库文字提取_百度文库文字爬取
  10. org.apache.commons.fileupload.DiskFileUpload/FileItem