Android AccessibilityService performAction() 方法无效
Android AccessibilityService performAction() method not working
我正在为 Android 开发无障碍服务。该服务调用一个应用程序,该应用程序有一个 RecyclerView。然后我想用 performAction(AccessibilityNodeInfo.ACTION_CLICK) 单击 RecyclerView 的一个元素,但它不起作用。我知道有几个类似的问题,但其中 none 对我有用。我还查看了官方文档中的 performAction 方法 https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo
的 class
这是我的代码:
@Override
public void onAccessibilityEvent(Accessibility event){
AccessibilityNodeInfo source = event.getSource();
if(source != null){
List<AccessibilityNodeInfo> list = source.findAccessibilityNOdeInfosByText("mystring");
list.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
这是我的配置xml文件:
<accessibility-srvice xmlns...
android:accessibilityFeedbackType = "feedbackGeneric"
android:AccessibilityFlags = "flagDefault"
android:canPerformGestures = "true"
android:canRetrieveWIndowCOntent = "true"
我想我误解了什么,但我不知道是什么。感谢任何帮助。
编辑 2022 年 3 月 29 日
简单的答案是,虽然通过文本查找节点很好,但该特定节点不是具有所需 onClick
事件的节点。解决方法是调用
list.get(0).getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK)
澄清讨论如下
我认为.performAction(AccessibilityNodeInfo.ACTION_CLICK)
是对的,但可能还有其他一些顾虑。抱歉发布为答案,但评论太少了。
您确定正在调用 onAccessibilityEvent
吗?我不认为这是正确的事件,但我不能确定。也许在那里放一个日志以确保它在您期望调用事件时调用事件。
此外,查看源代码可能会限制您的搜索,也许而不是 event.getSource()
尝试使用 rootInActiveWindow
(我使用 Kotlin 所以它可能有一个方法,请参阅 https://developer.android.com/reference/android/accessibilityservice/AccessibilityService#getRootInActiveWindow(int))
编辑:2022 年 3 月 28 日
我在自己的无障碍服务中有 运行 这段代码,它确实点击了按钮。但是很容易溢出。
var ranOnce = false // prevent overflow
override fun onAccessibilityEvent(event: AccessibilityEvent?) {
if (event == null) return
if (event.eventType == TYPE_WINDOW_STATE_CHANGED) return
if (event.source != null && !ranOnce) {
val nodeList = rootInActiveWindow.findAccessibilityNodeInfosByText("Menu")
//event.source.findAccessibilityNodeInfosByText("Menu") // <-- always nothing in list
Log.d("onAccessibilityEvent", "List of nodes: $nodeList")
if (nodeList.size > 0) {
android.util.Log.d("onAccessibilityEvent", "Node info: ${nodeList[0]}")
ranOnce = true
nodeList[0].performAction(AccessibilityNodeInfo.ACTION_CLICK) //<-- caused an infinite loop!
} else {
Log.d("onAccessibilityEvent", "No nodes found")
}
} else {
Log.d("onAccessibilityEvent", "event.source is null!")
}
}
我正在为 Android 开发无障碍服务。该服务调用一个应用程序,该应用程序有一个 RecyclerView。然后我想用 performAction(AccessibilityNodeInfo.ACTION_CLICK) 单击 RecyclerView 的一个元素,但它不起作用。我知道有几个类似的问题,但其中 none 对我有用。我还查看了官方文档中的 performAction 方法 https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo
的 class这是我的代码:
@Override
public void onAccessibilityEvent(Accessibility event){
AccessibilityNodeInfo source = event.getSource();
if(source != null){
List<AccessibilityNodeInfo> list = source.findAccessibilityNOdeInfosByText("mystring");
list.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
这是我的配置xml文件:
<accessibility-srvice xmlns...
android:accessibilityFeedbackType = "feedbackGeneric"
android:AccessibilityFlags = "flagDefault"
android:canPerformGestures = "true"
android:canRetrieveWIndowCOntent = "true"
我想我误解了什么,但我不知道是什么。感谢任何帮助。
编辑 2022 年 3 月 29 日
简单的答案是,虽然通过文本查找节点很好,但该特定节点不是具有所需 onClick
事件的节点。解决方法是调用
list.get(0).getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK)
澄清讨论如下
我认为.performAction(AccessibilityNodeInfo.ACTION_CLICK)
是对的,但可能还有其他一些顾虑。抱歉发布为答案,但评论太少了。
您确定正在调用
onAccessibilityEvent
吗?我不认为这是正确的事件,但我不能确定。也许在那里放一个日志以确保它在您期望调用事件时调用事件。此外,查看源代码可能会限制您的搜索,也许而不是
event.getSource()
尝试使用rootInActiveWindow
(我使用 Kotlin 所以它可能有一个方法,请参阅 https://developer.android.com/reference/android/accessibilityservice/AccessibilityService#getRootInActiveWindow(int))
编辑:2022 年 3 月 28 日
我在自己的无障碍服务中有 运行 这段代码,它确实点击了按钮。但是很容易溢出。
var ranOnce = false // prevent overflow
override fun onAccessibilityEvent(event: AccessibilityEvent?) {
if (event == null) return
if (event.eventType == TYPE_WINDOW_STATE_CHANGED) return
if (event.source != null && !ranOnce) {
val nodeList = rootInActiveWindow.findAccessibilityNodeInfosByText("Menu")
//event.source.findAccessibilityNodeInfosByText("Menu") // <-- always nothing in list
Log.d("onAccessibilityEvent", "List of nodes: $nodeList")
if (nodeList.size > 0) {
android.util.Log.d("onAccessibilityEvent", "Node info: ${nodeList[0]}")
ranOnce = true
nodeList[0].performAction(AccessibilityNodeInfo.ACTION_CLICK) //<-- caused an infinite loop!
} else {
Log.d("onAccessibilityEvent", "No nodes found")
}
} else {
Log.d("onAccessibilityEvent", "event.source is null!")
}
}