利用AccessibilityService自动获取微信号(Android)
前言:
最近遇到一个需求,要求写一个小插件,能够自动在微信的页面弹出一个窗口,展示用户的相关信息(与我们公司有关的信息,方便运营快速了解用户信息)。
当时我第一反应是不可能,如果能够在别的app中获取对应的信息,那岂不是太不安全了。直到我知道了AccessibilityService这个东西。
基本思路:
利用AccessibilityService服务来获取到微信页面的页面信息,并获取到用户的微信号,有了微信号一切都好办了。
由于获取用户好友微信号和获取本人微信号的方法相同,因此此篇文章主要介绍的是如何通过AccessibilityService来获取本人的微信号。
过程:
AccessibilityService是什么?
在你的手机更多设置或者高级设置中,我们会发现有个无障碍的功能,很多人不知道这个功能具体是干嘛的,其实这个功能是为了增强用户界面以帮助残障人士,或者可能暂时无法与设备充分交互的人们。
它的具体实现是通过AccessibilityService服务运行在后台中,通过AccessibilityEvent接收指定事件的回调。这样的事件表示用户在界面中的一些状态转换,例如:焦点改变了,一个按钮被点击,等等。这样的服务可以选择请求活动窗口的内容的能力。简单的说AccessibilityService就是一个后台监控
服务,当你监控的内容发生改变时,就会调用后台服务的回调方法。
如何创建一个AccessibilityService?
实现一个自己的AccessibilityService,需要继承AccessibilityService类,并至少实现onAccessibilityEvent和onInterrupt方法:
public class MyAccessibilityService extends AccessibilityService {
final String TAG = "MyAccessibilityService";
/**
* 当服务启动的时候会被调用
*/
@Override
protected void onServiceConnected() {
super.onServiceConnected();
Log.d(TAG, "connected");
}
/**
* 监听窗口变化的回调
*/
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.d(TAG, event.getPackageName() + "");
}
/**
* 中断服务的回调
*/
@Override
public void onInterrupt() {
Log.d(TAG, "onInterrupt");
}
}
AccessibilityService中的一些常用方法:
- disableSelf():禁用当前服务,服务可以通过该方法停止运行;
- findFocus(int focus):查找拥有特定焦点类型的控件;
- getRootInActiveWindow():如果配置能够获取窗口内容,则会返回当前活动窗口的根结点;
- getServiceInfo():获取当前服务的配置信息;
- onAccessibilityEvent(AccessibilityEvent event):有关AccessibilityEvent事件的回调函数,系统通过sendAccessibiliyEvent()不断的发送AccessibilityEvent到此处;
- performGlobalAction(int action):执行全局操作,比如返回,回到主页,打开最近等操作;
- setServiceInfo(AccessibilityServiceInfo info):设置当前服务的配置信息;
- onServiceConnected():系统成功绑定该服务时被触发,也就是当你在设置中开启相应的服务,系统成功的绑定了该服务时会触发,通常我们可以在这里做一些初始化操作;
- onInterrupt():服务中断时的回调。
声明该服务:
<service
android:name=".MyAccessibilityService"
android:enabled="true"
android:exported="true"
android:label="这是一个用户测试的无障碍服务"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
</service>
配置服务参数:
主要是用于声明该服务的一些配置参数,现在有两种配置服务参数的方法:在安卓4.0之后可以通过meta-data标签来在xml中配置,也可以通过动态代码直接配置。这里我们通过xml进行配置。
首先在res下的xml文件夹下创建配置文件,
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackAllMask"
android:canRetrieveWindowContent="true"
android:notificationTimeout="100"
android:packageNames="com.tencent.mm"
android:description="@string/description" />
然后将配置文件添加到清单文件中,
<service
android:name=".MyAccessibilityService"
android:enabled="true"
android:exported="true"
android:label="这是一个用户测试的无障碍服务"
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/config_accessibility" />
</service>
下面对xml中的一些参数进行介绍:
- accessibilityEventTypes:表示该服务对界面中的哪些变化感兴趣,即哪些事件通知,比如窗口打开,滑动,焦点变化,长按等。具体的值可以在AccessibilityEvent类中查到,如typeAllMask表示接受所有的事件通知;
- accessibilityFeedbackType:表示反馈方式,比如是语音播放,还是震动(此参数是必须的,不写的话不会走回调方法);
- canRetrieveWindowContent:表示该服务能否访问活动窗口中的内容.也就是如果你希望在服务中获取窗体内容的化,则需要设置其值为true;
- notificationTimeout:接受事件的时间间隔,通常将其设置为100即可;
- packageNames:表示对该服务是用来监听哪个包的产生的事件,这里以微信的包名为例(如果要监听的包有多个,则可以在代码中设置;如若不写,则监控的是所有的包);
- description:对该服务的无障碍描述。
如何开启AccessibilityService呢?
以小米手机为例,在设置中打开更多设置,进入无障碍。然后打开之前声明的服务即可。

如何获取微信“我的”页面的微信号呢?
这里主要利用AccessibilityNodeInfo的findAccessibilityNodeInfosByViewId(String viewId)方法,该方法用于根据控件标识来获取到整个控件。
那么问题来了,如何知道微信该控件的标识呢?这里可以通过SDK的工具DDMS工具。
进入SDK目录的tools目录,找到monitor.bat文件,双击即可。

进入DDMS界面后,选中微信的包名,并点击如下所示按钮即可分析当前微信页面的布局信息:

如下图,可以发现该控件的标识为:com.tencent.mm:id/czz

因此,即可通过如下方法获取到该控件的值:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.d(TAG, event.getPackageName() + ""); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
// 通过id获取到微信号的View
List<AccessibilityNodeInfo> nodeInfoList = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.tencent.mm:id/czz");
String wxCode;
if (nodeInfoList != null && nodeInfoList.size() > 0) {
wxCode = nodeInfoList.get(0).getText().toString();
Log.d(TAG, wxCode);
}
} }
运行结果如下:

总结:
- 在过程中遇到了两个问题:第一个问题是运行完了之后服务已经开启,但是一直不走回调,经查是由于没有写accessibilityFeedbackType参数的原因;
- 第二个问题是,一开始通过Android Studio自带的Layout Inspector来获取控件的标识,当时获取的标识是czz,并不全,导致一直获取不到相应的微信号;
- 无障碍服务是一个很便携但是也很危险的服务,所以轻易不要给别人无障碍服务的权限;
- 不要轻易对一件事进行判断,需要进行了解之后才进行判断(在此之前我一直觉得该功能是无法实现的);
- 对于一个功能,第一反应应该是如何实现而不是如何推脱。
参考博客:
大家如果有什么疑问或者建议可以通过评论或者邮件的方式联系我,欢迎大家的评论~
利用AccessibilityService自动获取微信号(Android)的更多相关文章
- 微信公众平台开发—利用OAuth2.0获取微信用户基本信息
在借鉴前两篇获取微信用户基本信息的基础下,本人也总结整理了一些个人笔记:如何通过OAuth2.0获取微信用户信息 1.首先在某微信平台下配置OAuth2.0授权回调页面: 2.通过appid构造url ...
- asp.net 利用HttpWebRequest自动获取网页编码并获取网页源代码
/// <summary> /// 获取源代码 /// </summary> /// <param name="url"></param& ...
- Centos7(Linux)网络配置,自动获取ip地址
Centos7.0 Vmware 网络桥接配置,利用DHCP自动获取ip地址 首先要将Vmware10.0.3设置为桥接模式. CentOS 7.0默认安装好之后是没有自动开启网络连接的! cd / ...
- 微信公众号开发系列-获取微信OpenID
在微信开发时候在做消息接口交互的时候须要使用带微信加密ID(OpenId),下面讲讲述2中类型方式获取微信OpenID.接收事件推送方式和网页授权获取用户基本信息方式获取. 1.通过接收被动消息方式获 ...
- ASP.NET Core2实现静默获取微信公众号的用户OpenId
最近在做个微信公众号的项目,需要将入口放置在公众号二级菜单内,通过点击该菜单链接后进入到该项目中去,进入到项目后程序会自动通过微信公众号的API完成用户的OpenId获取.需求很简单,实现起来也不复杂 ...
- linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件
原创,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4555328.html 之前写过一篇<windows下Android利用ant自动编译.修改配置文件.批量 ...
- 第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token
一.access_token简介 为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台 开放了许多接口,包括自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等, 开 ...
- 微信公众号平台接口开发:基础支持,获取微信服务器IP地址
官方说明 目前看不出来这个接口有哪些具体运用,但是既然有这个接口,那我们就试试能不能用 访问接口 修改WeCharBase.cs,新增以下2个方法 public static string Serve ...
- 微信小程序+“芝麻小客服”可设自动关注公众号,助力运营闭环
微信小程序全面上线已经接近1年的时间,从最初的"用完即走"理念到2017年总计更新开放60余次的功能创新,微信小程序不一定会爆发下一次的红利,但绝对是微信生态中重要的一环. 芝麻小 ...
随机推荐
- token:NLP之词形还原
已迁移到我新博客,阅读体验更佳token:NLP之词形还原 完整代码实现放在我的github上:click me 一.任务描述 形态还原算法: 输入一个单词 如果词典里有该词,输出该词及其属性,转4, ...
- Win10构建Python全栈开发环境With WSL
目录 Win10构建Python全栈开发环境With WSL 启动WSL 总结 对<Dev on Windows with WSL>的补充 Win10构建Python全栈开发环境With ...
- <pre>标签:\r\n换行符的保留
mysql数据读库的\r\n换行符处理 这个问题是我在采集数据时发现的,采集网页的数据,大概有6千多条,采集的内容保留了最原始的\r\n和\n换行字符,但在mysql管理工具中(phpmyadmin和 ...
- 全球第一免费开源ERP Odoo PM OKR项目管理操作指南
概览 Odoo项目允许你和整个项目团队一起管理项目, 与项目和任务成员中的任何一个人沟通. 它与包含可定制阶段的任务的项目一起工作.项目可以是内部的或客户导向的.任务是项目执行的一部分.你可以给这 ...
- SuperMap iObject入门开发系列之二地下三维管线系统介绍
本文是一位好友“托马斯”授权给我来发表的,介绍都是他的研究成果,在此,非常感谢. 上次对超图平台组件式开发进行介绍,这次介绍的是基于这个框架开发的地下三维管线系统.地下管线涉及给水.雨水.污水.燃气. ...
- 关于web资金系统提现安全保护,防止极快的重复并发请求导致重复提现的解决思路
关于WEB金融系统中的提现安全问题很多人没有深入思想,导致有漏洞,常常会遇到有些人遇到被攻击到导资金损失的麻烦, 其实要彻底解决重复并发请求 导致重复提现问题,是需要花点心思的,并没有看起来的 ...
- July 08th. 2018, Week 28th. Sunday
Make each day your masterpiece. 让生命中的每一天都成为杰作. From John Wooden. Try to focus on what we are doing r ...
- 关于raft算法
列出一些比较好的学习资料, 可以经常翻一番,加深印象 0 raft官方git 1 raft算法动画演示 2 Raft 为什么是更易理解的分布式一致性算法 3 raft一致性算法 4 Raf ...
- Unity项目开发过程中常见的问题,你遇到过吗?
最近看到有朋友问一个unity游戏开发团队,需要掌握哪些知识之类的问题.事实上Unity引擎是一个很灵活的引擎,根据团队开发游戏类型的不同,对人员的要求也有差异,所以不能一概而论.但是,一些在Unit ...
- 内核ring buffer -- kfifo
目前kernel的kfifo根据版本有两种形式, 早期的函数形式和现在的宏定义形式 1. 早期的(linux-3.0.56/kernel/kfifo.c) 感兴趣读者可以自己看, 源码如下: /* * ...