如何 'interrupt' 在 AccessibilityService 中执行一个动作?
How to 'interrupt' an action from being performed in AccessibilityService?
我正在尝试做的事情 do/What 我已经做了: 我正在尝试为视障用户制作一个非常基本的 TalkBack 版本。我做了一个简单的辅助功能服务,它读取用户单击的按钮的内容描述并大声朗读。
@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;
}
问题: 但是,通过这种方式,用户无法在实际执行单击按钮时触发的操作之前收听按钮的描述。当用户听到描述时,按钮已经被点击并执行了一个动作。
问题:如何中断正在执行的操作(例如:单击按钮后打开一个新的 activity),以便用户可以安全地浏览在不启动新活动或启动其他操作的情况下,我提供的反馈在屏幕上的当前视图?
有点像 Talkback 中发生的事情:用户单击以听到描述,然后双击以执行操作。除非用户双击,否则 Talkback 如何防止操作发生?我查看了 TouchExplorationMode,但我猜它主要用于手势而不是点击。
你找错地方了。一旦 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 遍历中的下一个或上一个元素上执行相同的操作(辅助功能焦点)。轻松愉快!
我正在尝试做的事情 do/What 我已经做了: 我正在尝试为视障用户制作一个非常基本的 TalkBack 版本。我做了一个简单的辅助功能服务,它读取用户单击的按钮的内容描述并大声朗读。
@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;
}
问题: 但是,通过这种方式,用户无法在实际执行单击按钮时触发的操作之前收听按钮的描述。当用户听到描述时,按钮已经被点击并执行了一个动作。
问题:如何中断正在执行的操作(例如:单击按钮后打开一个新的 activity),以便用户可以安全地浏览在不启动新活动或启动其他操作的情况下,我提供的反馈在屏幕上的当前视图?
有点像 Talkback 中发生的事情:用户单击以听到描述,然后双击以执行操作。除非用户双击,否则 Talkback 如何防止操作发生?我查看了 TouchExplorationMode,但我猜它主要用于手势而不是点击。
你找错地方了。一旦 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 遍历中的下一个或上一个元素上执行相同的操作(辅助功能焦点)。轻松愉快!