如何"中断"在AccessibilityService中执行的操作?

Xen*_*ist 5 android accessibilityservice

我想做什么/我做了什么:我正在尝试为视障用户制作一个非常基本的TalkBack版本.我做了一个简单的辅助功能服务,读取用户点击的按钮的contentDescription并大声读出.

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

    // get the source node of the event
    AccessibilityNodeInfo source = event.getSource();
    if (source == null) {
        return;
    }

    // Check if a button is clicked and speak out the content
    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED
        && BUTTON_CLASS_NAME.equals(source.getClassName()) {
            Log.d("Button clicked", source.getViewIdResourceName().toString());
            convertTextToSpeech(source.getContentDescription().toString());
        }

    if (source != null)
        source.recycle();
    return;
}
Run Code Online (Sandbox Code Playgroud)

问题:但是,这样一来,用户就无法在按下单击按钮之前实际执行触发的操作之前听取按钮的描述.当用户收听描述时,已经点击了按钮并且已经执行了动作.

问题:如何中断操作(例如:在单击按钮后打开新活动),以便用户可以使用我提供的反馈安全地浏览屏幕上的当前视图,而无需启动新活动或触发其他操作?

类似于Talkback中发生的事情:用户单击以听取描述,双击以执行操作.除非用户双击,否则Talkback如何阻止动作发生?我已经研究过TouchExplorationMode,但我猜它主要用于手势而不是点击.

Chr*_*sCM 2

您找错地方了。一旦onAccessibilityEvent收到事件,操作就已经发生。它只是通知您,发生了点击事件。想要阻止它已经太晚了。

您确实需要 TouchExplorationMode。下面是 TalkBack 处理的快速而肮脏的实现,以及它如何使 UI 按照其应有的方式运行,而无需大量额外的垃圾和异常处理。我只包含了对此功能重要的部分。当然还有很多其他必要的脚手架,但这会分散对关键元素的注意力。

serviceConfig.xml的内容:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagRequestTouchExplorationMode"
    android:canRequestTouchExplorationMode="true"
    />
Run Code Online (Sandbox Code Playgroud)

A11yService.java的部分内容

@Override
public void onAccessibilityEvent(AccessibilityEvent e) {

    switch (e.getEventType()) {
        case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: {
            e.getSource().performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,TalkBack 会拦截 onGesture 中的手势,并捕获向右滑动或向左滑动的手势,并仅对 AccessibilityNode 遍历中的下一个或上一个元素执行相同的操作(辅助功能焦点)。十分简单!