0

Hierarchy Viewer 让您可以通过将手机连接到笔记本电脑来提取有关 UI 元素的信息。它通过 adb 轮询窗口管理器/视图管理器以获取信息。

我想知道是否可以在运行时使用后台服务提取手机上前台屏幕的 UI 信息?

我正在尝试构建一个可访问性服务(类似于 Talkback),并试图找到一种方法来收集有关活动前景屏幕上所有 UI 元素(它们的类(例如按钮)和位置)的信息。我已经能够提供无障碍服务,但我无法找到获取 UI 信息的方法。

4

2 回答 2

1

我写了一些代码并且工作正常,也许这就是你想要的。

首先,获取内容视图:

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());
    }
}

}

于 2017-02-25T08:46:56.837 回答
1

我能够找到我的问题的答案。

Android 可访问性 API 提供了此功能。我能够实现辅助功能服务,并且对于每个辅助功能事件,我都能够使用辅助功能节点信息功能,它本质上是前台屏幕上所有 UI 元素的树形表示。例如,一个线性布局由一个按钮和一个图像组成,那么按钮和图像将是 LL 的子级。

树的根可以通过以下方式找到:

AccessibilityNodeInfo rootNode = getRootInActiveWindow();

然后,我能够使用该getChild()功能遍历树(广度优先搜索),该功能为我提供了活动屏幕上所有 UI 元素的列表。

希望它对其他人也有帮助!

于 2017-02-25T22:49:48.170 回答