使用 AccessibilityService 中的 AccessibilityNodeInfo 执行滚动

perform scroll using AccessibilityNodeInfo in AccessibilityService

我想滚动当前屏幕。 我试过了 AccessibilityNodeInfo accessibilityNodeInfo=getRootInActiveWindow(); accessibilityNodeInfo.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN); 但我总是说 "Cannot perform this action on a sealed instance"。 请帮忙

首先:您尝试做的事情存在问题。

当你看到这个

Cannot perform this action on a sealed instance.

此消息 Android 告诉您您拥有的信息已设置。能够说出一个不可滚动的视图对您来说有意义吗?不。您不能强制视图可滚动。可滚动的视图取决于视图。例如,可滚动的 Button 是没有意义的!无障碍服务无法强制执行此行为。

应用程序的根节点很可能是某种类型的框架布局,永远无法滚动。层次结构的可滚动部分几乎总是 layout/root 主视图的子视图。这个故事的寓意,你不能说一个视图是可滚动的,你必须找到一个可滚动的视图。

话虽如此,我将为您提供一个更好的解决方案,希望它在您支持的设备范围内。

@TargetApi(Build.VERSION_CODES.M)
public boolean scrollTo(AccessibilityNodeInfo nodeInfo) {

    return nodeInfo.performAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_ON_SCREEN.getId());

}

如果您需要支持 Android M 之前的版本,您需要做的是在布局中探索视图的 AccessibilityNodeInfo 层次结构,这是正确的,这看起来大概像这样(未测试,但应该非常接近!):

public boolean scrollView(AccessibilityNodeInfo nodeInfo) {

    if (nodeInfo == null) return false;

    if (nodeInfo.isScrollable()) {
        return nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
    }

    for (int i = 0; i < nodeInfo.getChildCount(); i++) {
        if (scrollView(nodeInfo.getChild(i)) {
            return true;
        }
    }

    return false;
}