GVKun编程网logo

第四方支付:使用Android AccessibilityService完成个人收款服务(第四方收款支付平台)

22

如果您对第四方支付:使用AndroidAccessibilityService完成个人收款服务和第四方收款支付平台感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解第四方支付:使用AndroidA

如果您对第四方支付:使用Android AccessibilityService完成个人收款服务第四方收款支付平台感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解第四方支付:使用Android AccessibilityService完成个人收款服务的各种细节,并对第四方收款支付平台进行深入的分析,此外还有关于AccessibilityService、accessibilityservice android辅助功能出现的问题、AccessibilityService从入门到出轨、Android accessibility service detect notification的实用技巧。

本文目录一览:

第四方支付:使用Android AccessibilityService完成个人收款服务(第四方收款支付平台)

第四方支付:使用Android AccessibilityService完成个人收款服务(第四方收款支付平台)

因为AccessibilityService的使用很简单,本文第一篇只讲实现微信个人收款回调服务的思路以及介绍使用到的技术。我个人认为这部分的内容对比编写一个安卓脚本更有价值。

本文仅供技术交流,切勿用于非法用户

一、 了解AccessibilityService

无障碍服务旨在帮助残疾人使用Android设备和应用程序。它们在后台运行,当系统被触发时接收系统的回调。这样的事件表示用户界面中的一些状态转换,例如,焦点已经改变,按钮被点击等。这样的服务可以可选地请求查询活动窗口的内容的能力。可访问性服务的开发需要扩展该类并实现其抽象方法。

在AccessibilityService的支持下,可以使你的安卓程序支持监听页面、页面组件和消息通知等事件并支持一系列例如点击、滑动和手势等操作。由此,我们可以通过继承AccessibilityService编写脚本。但是仅仅是操作UI层面的脚本辅助,,好处是使用场景不需要root,只需要打开一些权限即可。

一般使用场景是微信抢红包、自动点赞之类的。理论上,我们能拿到通知栏就可以实现微信收款的回调。所以本文讲了如果投入到生产环境需要考虑的设计以及方案。

二、 收款回调服务

总体的逻辑是:自动生成二维码、解析二维码上传到服务器、收到收款通知的时候回调到服务器
里面就包括了一些细节,例如:请求时传输内容的加密、设备的唯一ID、心跳机制等

这样完成的支付是有很大的局限性的。例如:在设备数量有限的情况只能支持到低并发的支付请求、对设备的正常运行完全依赖

1. 自动生成收款二维码

这个步骤主要是脚本的操作。重复输入金额生成二维码。
这里说一下个人支付的方案: 假设用户目标支付是金额5元,那么最先5元的收款码一定要保留支付时间的,正常用户支付完成了就可以释放了,如果用户放弃支付,可能在1-2分钟释放这个付款码。所以我们有两种方法:

(1) 多台设备&&多个收款账户
(2) 金额偏移

第一个方案固然是可行并且最理想的。所以我们这里讲求次方案,就是生成5元支付金额时,向前(–)或者向后(++)生成数个支付码,例如4.99、4.98、5.01、5.02。当然我更倾向于向前的。

(3)两者结合

这样并发量就是一个组合结果了,对于个人收款应该足够(如果不够,应该去申请商业支付啦)

2. 解析二维码上传到服务端

因为权限问题,在一个service里面截图是被拒绝的。

(1) displayManagerService

这个方案是可行的。自行了解

(2) 利用微信本身的保存收钱码功能

在这里插入图片描述

嗯…这个香

3. 收到通知回调到服务器

(1) 生成设备指纹

这个搜索(android 设备指纹)一大堆啊就不过多阐述了。主要是生成一个唯一标识去辨别设备的。

(2) 传输加密

如果明文传输也可以。
这里加密主要是为了验证消息的确来自设备,万一接口暴露了,被伪造请求,会直接造成经济损失啊。
因为设备是自己保管的,不存在被逆向然后密钥泄漏风险(如果服务器被注入我就管不着了)
这里也是用常用的CBC加密PKCS7PADDING填充
具体好像搜索(android cbc)又有答案了…

(3) 心跳机制、前台服务

因为回调服务是完全依赖设备正常运行的。但是这里比较简单只是细节问题。

(1) 轮询

开一个子线程定时请求服务器,服务器去做检测,上次心跳时差大于30s就不要使用这个设备的收钱码了,并且发出通知,然后人工处理就好了。

(1) Socket

没啥好说的,自带心跳。还可以对接函数进行云控app。有想象力的自行发挥吧。

本文介绍就到这里了,下面上个demo演示视频

视频中就是我的收款码,觉得有用的直接可以赞赏咯

<iframe allowfullscreen="true" data-mediaembed="bilibili" id="lBASdW61-1620706823489" src="https://player.bilibili.com/player.html?aid=930494608"></iframe>

使用Android AccessibilityService完成个人收款服务

AccessibilityService

AccessibilityService

AccessibilityService从入门到出轨

AccessibilityService根据官方的介绍,是指开发者通过增加类似contentDescription的属性,从而在不修改代码的情况下,让残障人士能够获得使用体验的优化,大家可以打开AccessibilityService来试一下,点击区域,可以有语音或者触摸的提示,帮助残障人士使用App。

当然,现在AccessibilityService已经基本偏离了它设计的初衷,至少在国内是这样,越来越多的App借用AccessibilityService来实现了一些其它功能,甚至是灰色产品。

使用入门

老规矩,官网镇楼
https://developer.android.com...
https://developer.android.com...

要使用AccessibilityService实际上非常简单,一般来说,只需要以下三步即可。

继承系统AccessibilityService

public class MyAccessibility extends AccessibilityService {

private static final String TAG = "xys";

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    Log.d(TAG, "onAccessibilityEvent: " + event.toString());
}

@Override
public void onInterrupt() {
}

}
其中有两个必须实现的方法:onAccessibilityEvent和onInterrupt。

在onAccessibilityEvent中,我们可以接收所监听的事件。不熟悉这些事件的话,只需要使用toString把这些信息打出来,自己多看几个Log,就大概能够了解了。

新建配置文件

在资源目录res下新建xml文件夹,新建accessibility.xml文件,写入:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"

                   android:accessibilityEventTypes="typeAllMask"
                   android:accessibilityFeedbackType="feedbackSpoken"
                   android:canRetrieveWindowContent="true"
                   android:notificationTimeout="1000"/>

里面有一些比较简单的配置。

其中 description 为 用户允许应用的辅助功能的说明字符串,这里没有指定所要辅助的应用packageNames,当没有指定时,默认辅助所有的应用,建议大家在使用时,指定需要监听的包名(你可以通过|来进行分隔),而不是所有的包名。typeAllMask是设置响应事件的类型,feedbackGeneric是设置回馈给用户的方式,有语音播出和振动。

注册

在AndroidMainifest中注册:

<service

android:name=".MyAccessibility"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
    <action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>

<meta-data
    android:name="android.accessibilityservice"
    android:resource="@xml/accessibility"/>

</service>
完成以上步骤后,一个AccessibilityService就可以使用了,你要知道的是,AccessibilityService具有很高的系统权限,所以,系统不会让App直接设置是否启用,需要用户进入设置-辅助功能中去手动启用,这样在一定程度上,保护了用户数据的安全。

如何理解AccessibilityService

很多人可能对AccessibilityService了解的不是很深入,所以认为AccessibilityService是在调用一些系统服务来自动执行一些操作,实际上,这个理解不能算错,当然也不全对,我觉得你可以把AccessibilityService理解为——『按键精灵』。相信很多开发者都玩过PC上的这款软件,他的作用,就是将你一次操作的整个记录,录制下来,然后就可以根据这个记录,重复的执行这些操作,例如:先点击某个输入框,再输入XXXX,再输入验证码,最后点击某按钮,这些操作如果需要重复执行,那么显然是一套机械的步骤,那么通过按键精灵,记录下这些操作后,直接通过脚本就可以完成这些操作。其实AccessibilityService跟这个是一样的,我们记录的,实际上就是我们的操作步骤,或者称之为『脚本』,那么系统在监控整个手机的各种AccessibilityService事件时,就会根据我们的逻辑来判断该使用哪一个脚本。

因此,我们完全可以抽象出一个基类AccessibilityService,并抽象出一些脚本的事件,例如,根据Text查找对应的View、点击某个View、滑动、返回等等,所以,我在这里封装了一个BaseAccessibilityService,这里就不贴具体的代码了,大家可以参考我的Github:

https://github.com/xuyisheng/...

入门

不知道从什么时候开始,AccessibilityService突然从一个残障人士使用的辅助服务,一跃变成了各种App的黑科技,利用AccessibilityService来做的事情,也越来越偏离了AccessibilityService设计的初衷,各种安全问题也随之暴露出来,Google的理想是好的,愿天下都是安分守己的程序员。

免Root自动安装

这个也许是能考证的最早利用AccessibilityService的使用场景了,最早在一些应用市场中出现,例如用户一次下载了很多App,那么每个App下载完毕后都会弹出安装界面,而且需要用户手动去处理,确实体验不太好,所以后来就出现了利用Root权限来静默安装App的功能,但现在普通用户Root的需求越来越少,所以,AccessibilityService来实现免Root自动安装的黑科技,才走上了桌面。

那么按照我们前面的思路,要实现自动安装,实际上就是把手动安装的步骤脚本化。一般来说,我们要安装一个App,会通过以下几个步骤:

调用系统的安装Intent
在安装界面上寻找『安装』、『下一步』这些操作按钮
点击『安装』、『下一步』按钮
完成安装
那么这些流程化的操作,我们就完全可以通过脚本来实现,下面就是一些简单的代码实现。

调用系统安装Intent:

public void autoInstall(View view) {

String apkPath = Environment.getExternalStorageDirectory() + "/test.apk";
Uri uri = Uri.fromFile(new File(apkPath));
Intent localIntent = new Intent(Intent.ACTION_VIEW);
localIntent.setDataAndType(uri, "application/vnd.android.package-archive");
startActivity(localIntent);

}
监控安装界面,并根据逻辑处理点击:

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

super.onAccessibilityEvent(event);
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED &&
        event.getPackageName().equals("com.android.packageinstaller")) {
    AccessibilityNodeInfo nodeInfo = findViewByText("安装", true);
    if (nodeInfo != null) {
        performViewClick(nodeInfo);
    }
}

}
代码写完才发现,看似很牛逼的自动安装,其实不过十几行代码。唯一复杂的,就是抽象化这些流程了。

抢红包

抢红包应该是AccessibilityService火起来的最大因素。网上借助AccessibilityService来实现的抢红包插件也是数不胜数,又是一个看上去很牛逼的功能。那么我们再来分析下,你是怎么抢红包的。

加入你现在在桌面,怎么知道有红包了呢?哦,看通知栏,出现了『微信红包』这几个关键字,然后,你点击这条通知进去,点击红包的那条消息,然后再点击拆红包的按钮,返回,回到桌面。

这样一看,抢红包完全是一个体力活啊,如果有个机器人能帮助我完成上面的动作,根本不用我抢啊,对的,这个机器人就是AccessibilityService,我们同样把抢红包流程化。

获取通知栏通知事件
点击通知栏消息
找到红包消息
点击
点击拆红包
返回
这每个步骤,也都不难啊,我们的工具类中,所有的方法都实现了,唯一要做的,就是写几个ifelse把逻辑拼起来就行了,具体代码就不贴了,毕竟是微信严打的一件事,大家适可而止就好了。

当然,这个Demo同样可以做的更完善一点,例如,增加WakeLock和Keyguard,实现在锁屏情况下的自动抢红包等功能。

微信自动回复

在了解了微信抢红包的方式之后,再看看微信自动回复,是不是就更是小菜一碟了?我们只要把抢红包的流程稍微改一下,就完成了整个功能的实现,不相信?

获取通知栏通知事件
点击通知栏消息
找到红包消息 ——> 输入自动回复的消息
点击 ——> 点击发送
点击拆红包 ——> 不需要了
返回
是不是非常简单?唯一一个有价值的代码如下:

private void notifyWechat(AccessibilityEvent event) {

if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {
    Notification notification = (Notification) event.getParcelableData();
    String content = notification.tickerText.toString();
    String[] msg = content.split(":");
    name = msg[0].trim();
    text = msg[1].trim();
    PendingIntent pendingIntent = notification.contentIntent;
    try {
        pendingIntent.send();
    } catch (PendingIntent.CanceledException e) {
        e.printStackTrace();
    }
}

}
一个简单的Trick而已,借用notification.contentIntent来唤起Notification对应的App。

实际上,我们能做的事情还有很多,当我们拿到对应的聊天信息时,可以通过聊天对象的筛选,来实现对『特别对象的监控』,例如你离开的时候,可以设置给你的老婆自动回复『亲爱的我在忙呢,等等哈』,而对其它人自动回复『滚,LZ忙』。再例如,可以对聊天信息进行分词、识别,从而实现对内容的精准回复,当然,这里还需要使用到一些第三方的语言分析软解,这里就不详解了,总之,没有想不到。

检查微信好友

那么再比如去年比较火的一个方法,通过拉好友进群组来检查是否还有好友关系。PC、Chrome上已经有很多软件来做这个检查了,其核心原理,都是通过拉群组的方式来做。那么在手机上,同样可以通过这种方式来实现,如果现在你还不知道该怎么做,那么后面的文章就没有看的必要了……

进程清理

大家应该都用过冯老师的『绿色守护』,这个App的最基本无Root功能,就是通过在应用管理界面『结束进程』的方式来停止一个后台运行的App,大家都知道天朝的App,基本都是全家桶,所以这种方式对释放系统资源确实还是有一定的帮助的,那么我们就来看看简单的实现。

核心原理非常简单,在应用详情页面,通过停止服务来禁止App服务。OK,那么我们要做的,实际上,就是下面的流程:

通过Intent打开对应App的管理详情信息页面
点击停止运行
返回,处理下一个
流程要比抢红包什么的简单多了,下面列出2个关键代码,大家应用详情界面:

public void cleanProcess(View view) {

for (String mPackage : mPackages) {
    Intent intent = new Intent();
    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    Uri uri = Uri.fromParts("package", mPackage, null);
    intent.setData(uri);
    startActivity(intent);
}

}
监控详情页面,进行停止操作:

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED &&
        event.getPackageName().equals("com.android.settings")) {
    CharSequence className = event.getClassName();
    if (className.equals("com.android.settings.applications.InstalledAppDetailsTop")) {
        AccessibilityNodeInfo info = findViewByText("强行停止");
        if (info.isEnabled()) {
            performViewClick(info);
        } else {
            performBackClick();
        }
    }
    if (className.equals("android.app.AlertDialog")) {
        clickTextViewByText("确定");
        performBackClick();
    }
}

}
这个App唯一的难点,应该就剩下怎么把UI做的好看一点了。

另外,还有一个兼容性的问题,大家都懂的,国内各种第三方的ROM厂家,经常会修改一些系统的Activity,甚至不同系统版本同一个功能的Activity都有可能不一样,所以,使用AccessibilityService的一个比较大的麻烦就是兼容性的处理,需要使用dumpsys和uiautomator这些工具来进行详细的分析,这些工具的使用以及分析方法,在我的新书《Android群英传:神兵利器》中都有详细的讲解,想深入了解的开发者可以参考下。

判断应用当前状态

借助AccessibilityService同样可以做一些比较有用的事情,例如监控App当前的状态,例如前台、后台的切换,通过TYPE_WINDOW_STATE_CHANGED即可进行判断,特别是在5.0以上,原先的getRunningTasks这个方法被升级到系统权限。

当然,AccessibilityService或多或少会存在一些性能问题,所以现在并不推荐使用这种方式来监控应用状态,更多的是通过activitylifecyclecallbacks来实现对App状态的跟踪与监控。

出轨

其实一旦我们了解了AccessibilityService的使用原理,那么就很难做到不逾矩,毕竟这里的诱惑太大了,当我写到这里时,甚至有种不寒而栗的感觉,所以这里申明:
本文所有内容仅供学习、技术交流,由此产生的各种问题,均与本人无关。

防卸载

据我所知,已经有些App或者称之为恶意软件实现了这样的功能,这个功能难吗,不难,估计都不超过20行代码,但确实很恶心,特别是对一些普通、小白用户,压根都不知道AccessibilityService是什么,莫名其妙你让我启用,写的可能比较好看,什么帮助你清理系统,优化资源,但实际上,在后面做一些见不得人的事情。

我们来分析下如何实现,当用户想要卸载你的App的时候,一般会来到设置界面,找到你的App然后选择卸载,那么如果我们监控这个页面,如果发现是自己的App,就直接退出,这样不就无法卸载了吗?是的,代码如下,没几行代码:

private String mDefenseName = "微信";

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

super.onAccessibilityEvent(event);
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED &&
        event.getPackageName().equals("com.android.settings")) {
    CharSequence className = event.getClassName();
    if (className.equals("com.android.settings.SubSettings")) {
        AccessibilityNodeInfo nodeInfo = findViewByText("应用程序信息");
        if (nodeInfo != null && findViewByText(mDefenseName) != null) {
            performBackClick();
        }
    }
}

}
那么有人要说了,如果是用的一些第三方ROM,直接在桌面就能卸载呢?同样的,只不过会稍微麻烦点,需要判断的东西更多了,要处理的兼容性更复杂了而已。

这里不得不说,虽然国内各种第三方ROM百花齐放、肆意妄为,但这也给AccessibilityService造成了很大的兼容性处理难题,所以对一些恶意的使用AccessibilityService的App也形成了很大的限制。

浏览器劫持

实际上并不局限于浏览器,各种App都能被劫持,因为AccessibilityService监控的是全局App,良心点的可能会指定包名进行监控。所以,我们可以监控任意一个App,例如浏览器,一旦打开,我们就输入指定的网址,或者是一打开一些App,就输入一些查询内容,这里我以鄙司的沪江网校为例,进入后直接进行搜索。

算了代码还是不贴了,完全都是Copy前面的内容。

监控密码框

呵呵呵,这个你还真是想多了,系统再天真也不会把这个权限开放给你,所有的设置为password类型的EditText都是无法被监控的,系统还算有点良心。

这里我只列举了一些非常简单的Hack方式,但实际上,还有很多,例如通过拉取指定网站的内容后自动安装App并模拟点击等,当然,AccessibilityService也可以用在自动化测试中,这完全就是一把双刃剑,是利是弊,完全取决于使用他的人。

跳过用户授权

一般来说,AccessibilityService是需要用户手动操作授权才可以执行的,但是,如果是在Root的情况下,或者是在ADB连接PC的情况下,甚至都不用用户授权,就可以完成AccessibilityService的授权操作。

Root的情况就不说了,通过修改Setting的数据库就可以更改这个设置了,当然,有Root的情况下,就根本不需要AccessibilityService了。

在没有Root的情况下,如果PC通过ADB发出指令,同样是可以自动完成授权的,这个可以参考360的一篇文章:

http://www.freebuf.com/articl...

我这里就不多说了,大家看看就懂了,并没有太多的技术含量,应该算是系统的一个小的漏洞。

AccessibilityService一般分析步骤

前面我们分析了那么多AccessibilityService好的不好的使用方法,实际上,总结下就这么几步。

分析操作的流程,拆解成单步可实现的过程
通过UIAutomator和adb shell dumpsys来查看对应的UI控件ID、文本或者是具体的Activity
通过逻辑组合进行代码编写
调试、兼容性处理
通过上面的这些方式,基本就可以实现一些固定流程的操作自动化了。关于AccessibilityService的工具类,我放到了Github上,虽然功能已经比较全了,但还没有经过很多的兼容性测试,同时,碍于时间和精力的关系,给出的Demo示例也不多,希望大家可以多提PR,共同完善。

https://github.com/xuyisheng/...

欢迎大家关注我的微信公众号:

Android群英传

accessibilityservice android辅助功能出现的问题

accessibilityservice android辅助功能出现的问题

做的一个抢红包的app,当用户跳转到系统开启辅助功能的界面为app开启辅助功能时,大约几分钟就会自动关闭这个辅助功能。我用的是小米真机5.1的系统。当我用夜神模拟器4.3的系统时,这个开启的辅助功能几乎会一直开着。

请问这是怎么回事,有人用过accessibilityservice这个辅助共能类的没,应该如何解决,如何可以让系统长时间的开着这个辅助选项?

AccessibilityService从入门到出轨

AccessibilityService从入门到出轨

前言



任何技术都是一把双刃剑,用的好与好不,都在于使用它的人,一念天堂,一念地狱。



    AccessibilityService根据官方的介绍,是指开发者通过增加类似contentDescription的属性,从而在不修改代码的情况下,让残障人士能够获得使用体验的优化,大家可以打开AccessibilityService来试一下,点击区域,可以有语音或者触摸的提示,帮助残障人士使用App。

    当然,现在AccessibilityService已经基本偏离了它设计的初衷,至少在国内是这样,越来越多的App借用AccessibilityService来实现了一些其它功能,甚至是灰色产品。

使用入门

    老规矩,官网镇楼
https://developer.android.com/guide/topics/ui/accessibility/services.html
https://developer.android.com/training/accessibility/service.html

    要使用AccessibilityService实际上非常简单,一般来说,只需要以下三步即可。

继承系统AccessibilityService

    其中有两个必须实现的方法:onAccessibilityEvent和onInterrupt。

    在onAccessibilityEvent中,我们可以接收所监听的事件。不熟悉这些事件的话,只需要使用toString把这些信息打出来,自己多看几个Log,就大概能够了解了。

新建配置文件

    在资源目录res下新建xml文件夹,新建accessibility.xml文件,写入:


    里面有一些比较简单的配置。

    其中 description 为 用户允许应用的辅助功能的说明字符串,这里没有指定所要辅助的应用packageNames,当没有指定时,默认辅助所有的应用,建议大家在使用时,指定需要监听的包名(你可以通过|来进行分隔),而不是所有的包名。typeAllMask是设置响应事件的类型,feedbackGeneric是设置回馈给用户的方式,有语音播出和振动。

注册

    在AndroidMainifest中注册:


    完成以上步骤后,一个AccessibilityService就可以使用了,你要知道的是,AccessibilityService具有很高的系统权限,所以,系统不会让App直接设置是否启用,需要用户进入设置-辅助功能中去手动启用,这样在一定程度上,保护了用户数据的安全。

如何理解AccessibilityService

    很多人可能对AccessibilityService了解的不是很深入,所以认为AccessibilityService是在调用一些系统服务来自动执行一些操作,实际上,这个理解不能算错,当然也不全对,我觉得你可以把AccessibilityService理解为——『按键精灵』。相信很多开发者都玩过PC上的这款软件,他的作用,就是将你一次操作的整个记录,录制下来,然后就可以根据这个记录,重复的执行这些操作,例如:先点击某个输入框,再输入XXXX,再输入验证码,最后点击某按钮,这些操作如果需要重复执行,那么显然是一套机械的步骤,那么通过按键精灵,记录下这些操作后,直接通过脚本就可以完成这些操作。其实AccessibilityService跟这个是一样的,我们记录的,实际上就是我们的操作步骤,或者称之为『脚本』,那么系统在监控整个手机的各种AccessibilityService事件时,就会根据我们的逻辑来判断该使用哪一个脚本。

    因此,我们完全可以抽象出一个基类AccessibilityService,并抽象出一些脚本的事件,例如,根据Text查找对应的View、点击某个View、滑动、返回等等,所以,我在这里封装了一个BaseAccessibilityService,这里就不贴具体的代码了,大家可以参考我的Github:

https://github.com/xuyisheng/AccessibilityUtil

入门

    不知道从什么时候开始,AccessibilityService突然从一个残障人士使用的辅助服务,一跃变成了各种App的黑科技,利用AccessibilityService来做的事情,也越来越偏离了AccessibilityService设计的初衷,各种安全问题也随之暴露出来,Google的理想是好的,愿天下都是安分守己的程序员。

免Root自动安装

    这个也许是能考证的最早利用AccessibilityService的使用场景了,最早在一些应用市场中出现,例如用户一次下载了很多App,那么每个App下载完毕后都会弹出安装界面,而且需要用户手动去处理,确实体验不太好,所以后来就出现了利用Root权限来静默安装App的功能,但现在普通用户Root的需求越来越少,所以,AccessibilityService来实现免Root自动安装的黑科技,才走上了桌面。

    那么按照我们前面的思路,要实现自动安装,实际上就是把手动安装的步骤脚本化。一般来说,我们要安装一个App,会通过以下几个步骤:

  1. 调用系统的安装Intent

  2. 在安装界面上寻找『安装』、『下一步』这些操作按钮

  3. 点击『安装』、『下一步』按钮

  4. 完成安装

    那么这些流程化的操作,我们就完全可以通过脚本来实现,下面就是一些简单的代码实现。

    调用系统安装Intent:


    监控安装界面,并根据逻辑处理点击:


    代码写完才发现,看似很牛逼的自动安装,其实不过十几行代码。唯一复杂的,就是抽象化这些流程了。

抢红包

    抢红包应该是AccessibilityService火起来的最大因素。网上借助AccessibilityService来实现的抢红包插件也是数不胜数,又是一个看上去很牛逼的功能。那么我们再来分析下,你是怎么抢红包的。

    加入你现在在桌面,怎么知道有红包了呢?哦,看通知栏,出现了『微信红包』这几个关键字,然后,你点击这条通知进去,点击红包的那条消息,然后再点击拆红包的按钮,返回,回到桌面。

    这样一看,抢红包完全是一个体力活啊,如果有个机器人能帮助我完成上面的动作,根本不用我抢啊,对的,这个机器人就是AccessibilityService,我们同样把抢红包流程化。

  1. 获取通知栏通知事件

  2. 点击通知栏消息

  3. 找到红包消息

  4. 点击

  5. 点击拆红包

  6. 返回

    这每个步骤,也都不难啊,我们的工具类中,所有的方法都实现了,唯一要做的,就是写几个ifelse把逻辑拼起来就行了,具体代码就不贴了,毕竟是微信严打的一件事,大家适可而止就好了。

    当然,这个Demo同样可以做的更完善一点,例如,增加WakeLock和Keyguard,实现在锁屏情况下的自动抢红包等功能。

微信自动回复

    在了解了微信抢红包的方式之后,再看看微信自动回复,是不是就更是小菜一碟了?我们只要把抢红包的流程稍微改一下,就完成了整个功能的实现,不相信?

  1. 获取通知栏通知事件

  2. 点击通知栏消息

  3. 找到红包消息 ——> 输入自动回复的消息

  4. 点击 ——> 点击发送

  5. 点击拆红包 ——> 不需要了

  6. 返回

    是不是非常简单?唯一一个有价值的代码如下:


    一个简单的Trick而已,借用notification.contentIntent来唤起Notification对应的App。

    实际上,我们能做的事情还有很多,当我们拿到对应的聊天信息时,可以通过聊天对象的筛选,来实现对『特别对象的监控』,例如你离开的时候,可以设置给你的老婆自动回复『亲爱的我在忙呢,等等哈』,而对其它人自动回复『滚,LZ忙』。再例如,可以对聊天信息进行分词、识别,从而实现对内容的精准回复,当然,这里还需要使用到一些第三方的语言分析软解,这里就不详解了,总之,没有想不到。

检查微信好友

    那么再比如去年比较火的一个方法,通过拉好友进群组来检查是否还有好友关系。PC、Chrome上已经有很多软件来做这个检查了,其核心原理,都是通过拉群组的方式来做。那么在手机上,同样可以通过这种方式来实现,如果现在你还不知道该怎么做,那么后面的文章就没有看的必要了……

进程清理

    大家应该都用过冯老师的『绿色守护』,这个App的最基本无Root功能,就是通过在应用管理界面『结束进程』的方式来停止一个后台运行的App,大家都知道天朝的App,基本都是全家桶,所以这种方式对释放系统资源确实还是有一定的帮助的,那么我们就来看看简单的实现。

    核心原理非常简单,在应用详情页面,通过停止服务来禁止App服务。OK,那么我们要做的,实际上,就是下面的流程:

  1. 通过Intent打开对应App的管理详情信息页面

  2. 点击停止运行

  3. 返回,处理下一个

    流程要比抢红包什么的简单多了,下面列出2个关键代码,大家应用详情界面:


    监控详情页面,进行停止操作:


    这个App唯一的难点,应该就剩下怎么把UI做的好看一点了。

    另外,还有一个兼容性的问题,大家都懂的,国内各种第三方的ROM厂家,经常会修改一些系统的Activity,甚至不同系统版本同一个功能的Activity都有可能不一样,所以,使用AccessibilityService的一个比较大的麻烦就是兼容性的处理,需要使用dumpsys和uiautomator这些工具来进行详细的分析,这些工具的使用以及分析方法,在我的新书《Android群英传:神兵利器》中都有详细的讲解,想深入了解的开发者可以参考下。

判断应用当前状态

    借助AccessibilityService同样可以做一些比较有用的事情,例如监控App当前的状态,例如前台、后台的切换,通过TYPEWINDOWSTATE_CHANGED即可进行判断,特别是在5.0以上,原先的getRunningTasks这个方法被升级到系统权限。

    当然,AccessibilityService或多或少会存在一些性能问题,所以现在并不推荐使用这种方式来监控应用状态,更多的是通过activitylifecyclecallbacks来实现对App状态的跟踪与监控。

出轨

    其实一旦我们了解了AccessibilityService的使用原理,那么就很难做到不逾矩,毕竟这里的诱惑太大了,当我写到这里时,甚至有种不寒而栗的感觉,所以这里申明:
本文所有内容仅供学习、技术交流,由此产生的各种问题,均与本人无关。

防卸载

    据我所知,已经有些App或者称之为恶意软件实现了这样的功能,这个功能难吗,不难,估计都不超过20行代码,但确实很恶心,特别是对一些普通、小白用户,压根都不知道AccessibilityService是什么,莫名其妙你让我启用,写的可能比较好看,什么帮助你清理系统,优化资源,但实际上,在后面做一些见不得人的事情。

    我们来分析下如何实现,当用户想要卸载你的App的时候,一般会来到设置界面,找到你的App然后选择卸载,那么如果我们监控这个页面,如果发现是自己的App,就直接退出,这样不就无法卸载了吗?是的,代码如下,没几行代码:


    那么有人要说了,如果是用的一些第三方ROM,直接在桌面就能卸载呢?同样的,只不过会稍微麻烦点,需要判断的东西更多了,要处理的兼容性更复杂了而已。

这里不得不说,虽然国内各种第三方ROM百花齐放、肆意妄为,但这也给AccessibilityService造成了很大的兼容性处理难题,所以对一些恶意的使用AccessibilityService的App也形成了很大的限制。

浏览器劫持

    实际上并不局限于浏览器,各种App都能被劫持,因为AccessibilityService监控的是全局App,良心点的可能会指定包名进行监控。所以,我们可以监控任意一个App,例如浏览器,一旦打开,我们就输入指定的网址,或者是一打开一些App,就输入一些查询内容,这里我以鄙司的沪江网校为例,进入后直接进行搜索。

    算了代码还是不贴了,完全都是Copy前面的内容。

监控密码框

    呵呵呵,这个你还真是想多了,系统再天真也不会把这个权限开放给你,所有的设置为password类型的EditText都是无法被监控的,系统还算有点良心。

    这里我只列举了一些非常简单的Hack方式,但实际上,还有很多,例如通过拉取指定网站的内容后自动安装App并模拟点击等,当然,AccessibilityService也可以用在自动化测试中,这完全就是一把双刃剑,是利是弊,完全取决于使用他的人。

跳过用户授权

    一般来说,AccessibilityService是需要用户手动操作授权才可以执行的,但是,如果是在Root的情况下,或者是在ADB连接PC的情况下,甚至都不用用户授权,就可以完成AccessibilityService的授权操作。

    Root的情况就不说了,通过修改Setting的数据库就可以更改这个设置了,当然,有Root的情况下,就根本不需要AccessibilityService了。

    在没有Root的情况下,如果PC通过ADB发出指令,同样是可以自动完成授权的,这个可以参考360的一篇文章:

http://www.freebuf.com/articles/terminal/114045.html

    我这里就不多说了,大家看看就懂了,并没有太多的技术含量,应该算是系统的一个小的漏洞。

AccessibilityService一般分析步骤

    前面我们分析了那么多AccessibilityService好的不好的使用方法,实际上,总结下就这么几步。

  1. 分析操作的流程,拆解成单步可实现的过程

  2. 通过UIAutomator和adb shell dumpsys来查看对应的UI控件ID、文本或者是具体的Activity

  3. 通过逻辑组合进行代码编写

  4. 调试、兼容性处理

    通过上面的这些方式,基本就可以实现一些固定流程的操作自动化了。关于AccessibilityService的工具类,我放到了Github上,虽然功能已经比较全了,但还没有经过很多的兼容性测试,同时,碍于时间和精力的关系,给出的Demo示例也不多,希望大家可以多提PR,共同完善。

https://github.com/xuyisheng/AccessibilityUtil


我的新课——Android动画开发的艺术』已经在慕课网实战课程中上线了,如果动画是你痛点,那么你一定不会后悔这门课~点击原文链接即可查看。

Android动画开发的艺术

本文分享自微信公众号 - Android群英传(android_heroes)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

Android accessibility service detect notification

Android accessibility service detect notification

0 down vote favorite

I''m trying to make my app detect whenever a notification is displayed. I''ve enabled it in the settings app andonServiceConnecteddoes get called, however when I create a notification or receive an e-mail through the gmail app nothing happens,onAccessibilityEventdoes not get called.

Android manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.slide" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.GET_TASKS"/> <application android:label="Slide" android:icon="@drawable/ic_launcher" android:theme="@style/AppTheme"> <activity android:name=".Settings" android:label="Slide"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".Tools" android:label="Slide" android:theme="@android:style/Theme.Translucent.NoTitleBar"> </activity> <service android:name=".LocalService"/> <service android:name=".NotificationService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" android:label="Slide" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService"/> </intent-filter> </service> </application>

NotificationService.java

package com.test.slide; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.view.accessibility.AccessibilityEvent; public class NotificationService extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { System.out.println("onAccessibilityEvent"); if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) { System.out.println("notification: " + event.getText()); } } @Override protected void onServiceConnected() { System.out.println("onServiceConnected"); AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED; info.notificationTimeout = 100; info.feedbackType = AccessibilityEvent.TYPES_ALL_MASK; setServiceInfo(info); } @Override public void onInterrupt() { System.out.println("onInterrupt"); } }

Thanks for any help.

android notifications accessibility
share | improve this question
edited Sep 26 ''12 at 12:20

asked Sep 23 ''12 at 17:18
ng93
396 1 4 20


Did you found the solution? i have exactly the same problem. –  Daniel Martinus Sep 25 ''12 at 17:24

alanv''s answer worked for me –  ng93 Sep 26 ''12 at 12:29

For what system version are you programming? ICS? jelly bean? –  Daniel Martinus Sep 27 ''12 at 11:33

Jelly bean 4.1.1 –  ng93 Oct 1 ''12 at 14:56

2 Answers

active oldest votes
up vote 2 down vote accepted

Accessibility services in Android 4.0 and above can behave strangely if there is no accessibility-service meta-data tag defined in the manifest. Try defining the meta-data as in the examples below. You should continue to use setServiceInfo() to maintain backward compatibility with pre-4.0 devices.

Also, I would recommend specifying a feedback type that is specific to your service, rather than using "all".

AndroidManifest.xml

 <service . . . android:name=".NotificationService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" > <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice" /> </service>

res/xml/accessibilityservice.xml

<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeNotificationStateChanged" android:accessibilityFeedbackType="feedbackAllMask" android:notificationTimeout="100" />

There was an error in your feedbackType. Corrected below. Still, consider using a more specific feedback type.

NotificationService.java

@Override protected void onServiceConnected() { AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED; info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK; info.notificationTimeout = 100; setServiceInfo(info); }
share | improve this answer
edited Sep 24 ''12 at 8:37

answered Sep 24 ''12 at 1:33
alanv
442 1 10


Now you are defining theserviceInfoin XML and code. You may leave out the code part of AccessibilityServiceInfo because the xml is defined in the manifest. –  Daniel Martinus Sep 24 ''12 at 5:57
1  
On the contrary, you must define it in both places for compatibility with pre-ICS devices. –  alanv Sep 24 ''12 at 8:01
up vote 1 down vote

The app using AccessibilityService needed to have a permission from settings>Accessibility in order to access the system events. Allow permission from settings . This may work

check this link

accessibility service is not started

今天关于第四方支付:使用Android AccessibilityService完成个人收款服务第四方收款支付平台的介绍到此结束,谢谢您的阅读,有关AccessibilityService、accessibilityservice android辅助功能出现的问题、AccessibilityService从入门到出轨、Android accessibility service detect notification等更多相关知识的信息可以在本站进行查询。

本文标签:

上一篇【基本功】Litho的使用及原理剖析(lithotroph)

下一篇Android MainFragment中使用多个Fragment(android 一个activity多个fragment)