最近的项目中用了无障碍服务,想通过getRootInActiveWindow()来获取View节点,然后实现一些功能啊,但是发现getRootInActiveWindow(),经常性为null,获取不到子节点信息,而且获取不的全,只有一部分。
网上查了很多资料,对于无障碍服务的介绍比较少,看官方文档也没有发现什么解决方法。
但是自己理解,分析了一下然后解决出来了,给大家分享一下。
先说一下无障碍服务的xml 配置
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackAllMask"
android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
android:canRequestFilterKeyEvents="true"
android:canRetrieveWindowContent="true"
android:canRequestEnhancedWebAccessibility="true"
android:notificationTimeout="100" />
这是正常的无障碍服务xml配置
一开始,我看到
android:accessibilityEventTypes="typeAllMask" 和 android:accessibilityFeedbackType="feedbackAllMask"
填写All就可以免去其他类型,于是我认为accessibilityflags也是这个道理,后来发现flagDefault,只是基本的,并不会带上特殊的flag类型
android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
然后就是getRootInActiveWindow()这个方法,这个方法只有在窗口发生改变的时候,获取子节点才不会为null
有人问为什么有时候我在同一个界面有时候就可以获取,有时候就不能?
我解释一下窗口发生改变包含屏幕亮度改变,view的变化什么的,很全面,所以有时候能获取,只是赶巧了。
所以我们不用getRootInActiveWindow()这个方法,用getwindows()这个方法。
getwindows()返回的是一个AccessibilityWindowInfo的List集合,包括界面上所有的东西,比如下拉栏就是一个window,下面的桌面又是一个window。
然后通过AccessibilityWindowInfo.getRoot()就可以获取到AccessibilityNodeInfo。
所以每个window就想当于一个getRootInActiveWindow(),只要无障碍服务打开就永远不会为null,并且获取的节点信息比getRootInActiveWindow() 更全面(这里的全面不是指有好几个window所以全面,在windows 中,有一个窗口,就对应着getRootInActiveWindow(),所代表的窗口,然而在这同样的窗口里,window所获取的节点信息,比getRootInActiveWindow()所获取的节点信息全面)
有问题加我QQ754178954
最近有好多人加q问我,有问题最好评论,我可以统一回答,不要和我要demo。。。没有那么准确的需求demo
想要了解getwindows 可以做什么,我做了个Hi touch 可以在google上搜到,没有google 可以搜一下fooview 基本是一样的,如果这两个可以获取控件,就可以获取到,如果获取不到就要通过AutoMator分析一下了