如何用AccessibilityService获取活动窗口及窗口更新时的全量内容?
通过AccessibilityService获取活动窗口文本内容及窗口更新监听方案
一、核心配置确认
你的无障碍服务配置已经满足基础要求,其中android:canRetrieveWindowContent="true"是获取窗口内容的关键,同时配置的typeWindowStateChanged和typeWindowContentChanged事件正好对应你需要的「应用切换/主屏幕显示」「窗口内容更新」场景。可以精简事件类型减少资源消耗,优化后的配置示例:
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews|flagReportViewIds" android:canRetrieveWindowContent="true" android:canTakeScreenshot="true" android:description="@string/app_name" android:notificationTimeout="100" />
二、获取活动窗口全部文本内容的实现
在你的AccessibilityService子类中,通过监听指定事件,递归遍历窗口根节点的所有子节点来提取文本:
1. 监听目标事件并获取根节点
@Override public void onAccessibilityEvent(AccessibilityEvent event) { int eventType = event.getEventType(); // 仅处理窗口状态变化(应用打开/关闭、回到主屏幕)和内容更新事件 if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) { AccessibilityNodeInfo rootNode = getRootInActiveWindow(); if (rootNode != null) { StringBuilder allWindowText = new StringBuilder(); traverseAllNodes(rootNode, allWindowText); // 这里得到当前活动窗口的全部文本内容,可按需处理 String fullText = allWindowText.toString().trim(); Log.d("WindowText", fullText); rootNode.recycle(); // 必须回收节点,避免内存泄漏 } } }
2. 递归遍历节点提取文本
/** * 递归遍历所有AccessibilityNode,提取文本内容 */ private void traverseAllNodes(AccessibilityNodeInfo node, StringBuilder textCollector) { if (node == null) return; // 提取当前节点的文本 CharSequence nodeText = node.getText(); if (nodeText != null && !nodeText.toString().trim().isEmpty()) { textCollector.append(nodeText).append("\n"); } // 遍历所有子节点 for (int i = 0; i < node.getChildCount(); i++) { AccessibilityNodeInfo childNode = node.getChild(i); traverseAllNodes(childNode, textCollector); if (childNode != null) { childNode.recycle(); } } } @Override public void onInterrupt() { // 服务中断时的清理操作 }
三、窗口更新时获取屏幕内容的说明
- 当触发
TYPE_WINDOW_STATE_CHANGED事件时(比如打开/关闭应用、回到主屏幕),调用上述逻辑即可获取当前活动窗口的全部文本。 - 当窗口内容动态更新时(比如列表加载、文本变化),
TYPE_WINDOW_CONTENT_CHANGED事件会触发,同样可以实时获取更新后的窗口文本。 - 无障碍服务的
getRootInActiveWindow()返回的是当前前台活动窗口的根节点,遍历该节点就能覆盖当前屏幕显示的所有可访问文本内容;如果需要处理多窗口场景,可使用getWindows()获取所有窗口后逐个遍历。
注意事项
- 必须在系统设置的「无障碍」页面手动开启你的服务,否则无法正常工作。
- 部分应用会限制无障碍服务的访问权限(如金融类APP),这类应用的窗口内容无法被获取。
- 所有获取到的
AccessibilityNodeInfo必须调用recycle()回收,否则会引发内存泄漏。 - Android 10+版本中,部分场景可能需要适配系统权限限制,但基础的文本提取逻辑不受影响。
内容的提问来源于stack exchange,提问作者Gaurav Mandlik
相关产品推荐
相关产品推荐

