You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 23:42:45