如何在运行时提取有关 android 应用程序中 UI 元素的信息?
How to extract information about UI elements in an android app at runtime?
Hierarchy Viewer 允许您通过将 phone 连接到笔记本电脑来提取有关 UI 元素的信息。它的工作原理是通过 adb 轮询 Window Manager/View 管理器以获取信息。
我想知道是否可以使用后台服务在运行时提取 phone 上前台屏幕的 UI 信息?
我正在尝试构建无障碍服务(类似于 Talkback),并试图找到一种方法来收集有关所有 UI 元素(它们的 class(例如按钮)和位置)在活动的前景屏幕上。我已经能够提供辅助功能服务,但我无法找到获取 UI 信息的方法。
我写了一些代码,效果很好,也许这就是你想要的。
首先,获取内容视图:
ViewGroup parent = (ViewGroup) findViewById(android.R.id.content);
然后用一个方法检查父视图的每个元素:
private void showViewInfo(View view){
if(view instanceof ViewGroup){
//do something when find view group:
System.out.println(view.getClass().toString()+"\tx:"+view.getX()+"\ty:"+view.getY());
for(int i=0;i<((ViewGroup) view).getChildCount();i++){
showViewInfo(((ViewGroup) view).getChildAt(i));
}
}else{
//do something when find children
System.out.println(view.getClass().toString()+"\tx:"+view.getX()+"\ty:"+view.getY());
}
}
最后,以父视图为参数调用方法:
showViewInfo(parent);
你可以得到这样的东西:
System.out: class android.support.v7.widget.ContentFrameLayout x:0.0 y:0.0
完整代码如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewGroup parent = (ViewGroup) findViewById(android.R.id.content);
showViewInfo(parent);
}
private void showViewInfo(View view){
if(view instanceof ViewGroup){
//do something when find view group:
System.out.println(view.getClass().toString()+"\tx:"+view.getX()+"\ty:"+view.getY());
//find the children
for(int i=0;i<((ViewGroup) view).getChildCount();i++){
showViewInfo(((ViewGroup) view).getChildAt(i));
}
}else{
//do something when find children
System.out.println(view.getClass().toString()+"\tx:"+view.getX()+"\ty:"+view.getY());
}
}
}
我找到了问题的答案。
Android 可访问性 API 提供此功能。我能够实现辅助功能服务,并且对于每个辅助功能事件,我能够使用 Accessibility Node Info 函数,它本质上是前台屏幕上所有 UI 元素的树形表示。例如一个线性布局由一个按钮和一个图像组成,那么按钮和图像将是 LL 的子级。
可以通过以下方式找到树的根:
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
然后我能够使用 getChild()
函数遍历树(广度优先搜索),该函数为我提供了活动屏幕上所有 UI 元素的列表。
希望它对其他人也有帮助!
Hierarchy Viewer 允许您通过将 phone 连接到笔记本电脑来提取有关 UI 元素的信息。它的工作原理是通过 adb 轮询 Window Manager/View 管理器以获取信息。
我想知道是否可以使用后台服务在运行时提取 phone 上前台屏幕的 UI 信息?
我正在尝试构建无障碍服务(类似于 Talkback),并试图找到一种方法来收集有关所有 UI 元素(它们的 class(例如按钮)和位置)在活动的前景屏幕上。我已经能够提供辅助功能服务,但我无法找到获取 UI 信息的方法。
我写了一些代码,效果很好,也许这就是你想要的。
首先,获取内容视图:
ViewGroup parent = (ViewGroup) findViewById(android.R.id.content);
然后用一个方法检查父视图的每个元素:
private void showViewInfo(View view){
if(view instanceof ViewGroup){
//do something when find view group:
System.out.println(view.getClass().toString()+"\tx:"+view.getX()+"\ty:"+view.getY());
for(int i=0;i<((ViewGroup) view).getChildCount();i++){
showViewInfo(((ViewGroup) view).getChildAt(i));
}
}else{
//do something when find children
System.out.println(view.getClass().toString()+"\tx:"+view.getX()+"\ty:"+view.getY());
}
}
最后,以父视图为参数调用方法:
showViewInfo(parent);
你可以得到这样的东西:
System.out: class android.support.v7.widget.ContentFrameLayout x:0.0 y:0.0
完整代码如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewGroup parent = (ViewGroup) findViewById(android.R.id.content);
showViewInfo(parent);
}
private void showViewInfo(View view){
if(view instanceof ViewGroup){
//do something when find view group:
System.out.println(view.getClass().toString()+"\tx:"+view.getX()+"\ty:"+view.getY());
//find the children
for(int i=0;i<((ViewGroup) view).getChildCount();i++){
showViewInfo(((ViewGroup) view).getChildAt(i));
}
}else{
//do something when find children
System.out.println(view.getClass().toString()+"\tx:"+view.getX()+"\ty:"+view.getY());
}
}
}
我找到了问题的答案。
Android 可访问性 API 提供此功能。我能够实现辅助功能服务,并且对于每个辅助功能事件,我能够使用 Accessibility Node Info 函数,它本质上是前台屏幕上所有 UI 元素的树形表示。例如一个线性布局由一个按钮和一个图像组成,那么按钮和图像将是 LL 的子级。
可以通过以下方式找到树的根:
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
然后我能够使用 getChild()
函数遍历树(广度优先搜索),该函数为我提供了活动屏幕上所有 UI 元素的列表。
希望它对其他人也有帮助!