我想做什么/我做了什么:我正在尝试为视障用户制作一个非常基本的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;
}
问题:但是,通过这种方式,用户无法在按下按钮之前实际执行触发操作之前听取按钮的说明。当用户收听描述时,该按钮已被点击并且已执行操作。
问题:如何中断操作(例如:点击按钮后打开新活动),以便用户可以安全地浏览屏幕上的当前视图提供没有开始新活动或解雇其他行动?
类似于Talkback中发生的事情:用户单击以听取描述,双击以执行操作。除非用户双击,否则Talkback如何阻止动作发生?我查看了 TouchExplorationMode ,但我猜它主要用于手势而不是点击。
答案 0 :(得分:1)
你在找错了地方。一旦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"
/>
A11yService.java的部分内容
@Override
public void onAccessibilityEvent(AccessibilityEvent e) {
switch (e.getEventType()) {
case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: {
e.getSource().performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
}
}
}
然后,TalkBack在onGesture中拦截手势,向右滑动或向左滑动,捕获它们,并在AccessibilityNode遍历中的下一个或上一个元素上执行相同的操作(可访问性焦点)。容易腻!