Accessibility Service是Android上的一种辅助功能,用户帮助一些视力、身体、年龄上有问题的用户,可以更好的与手机进行交互,本文以微信为例子,利用Accessibility Service来监听微信的推送和窗口变化。
设置AndroidManifest.xml
在AndroidManifest.xml中配置AccessibilityService:
1 | <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/> |
设置AndroidManifest.xml
在res文件夹下新建xml文件夹,并添加上面定义好的:
accessible_service_config.xml
内容如下:
1 | <?xml version="1.0" encoding="utf-8"?> |
开发Service
新建上面定义好的Service类:
public class MonitorService extends AccessibilityService {
@SuppressLint("NewApi")
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
Log.e("EventType", eventType + "");
if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
if (Build.VERSION.SDK_INT < 18) {
Notification notification = (Notification) event.getParcelableData();
List<String> textList = getText(notification);
if (null != textList && textList.size() == 2) {
String user = textList.get(0);
String content = textList.get(1);
if (!TextUtils.isEmpty(content) && content.contains("[语音]")) {
Log.e("Push", user + "发来语音");
final PendingIntent pendingIntent = notification.contentIntent;
try {
pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
}
}else{
if(content.indexOf(':') != -1){
content = content.substring(content.indexOf(':') + 1);
}
Log.e("Push", user + "发来消息:" + content);
}
}
}
}
else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
String clazzName = event.getClassName().toString();
Log.e("ClassName", clazzName);
}
}
}
上面,对微信的推送以及窗口变化进行了监听,当然,也可以用于自动抢红包,例如,在窗口变化时,监听是否有“领取红包”的View,如果有,执行模拟点击事件。
if (clazzName.equals("com.tencent.mm.ui.LauncherUI")) {
AccessibilityNodeInfo nodeInfo = event.getSource();
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("领取红包");
if (null != list && list.size() > 0) {
AccessibilityNodeInfo node = list.get(list.size() - 1);
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
如果利用findByText方法找不到时,可以通过递归,利用View的一些属性来取到Node:
private void traverseNode(AccessibilityNodeInfo node) {
if (null == node) return;
int count = node.getChildCount();
if (count > 0) {
for (int i = 0; i < count; i++) {
AccessibilityNodeInfo childNode = node.getChild(i);
if(null != childNode){
traverseNode(childNode);
}
}
}
其中的View的属性,可以利用AndroidSDK中工具进行查看:
AndroidSDK/tools/uiautomatorviewer
鼠标移动可以随意查看,点击可以选中: