UiAutomator UIAutomator2.0 - - - -UiDevice 简介

49875183 · 2015年11月16日 · 最后由 testly 回复于 2015年11月17日 · 3824 次阅读
本帖已被设为精华帖!

UiDevice 类的新特性:

1,UiObject2 findObject(BySelector selector)
通过查找获取 uiobject2 元素

2,List findObjects(BySelector selector)
通过查找获取 uiobject2 元素集合

3,R wait(SearchCondition condition, long timeout)
延时获取元素,如果元素不存在返回 null

4, R performActionAndWait(Runnable action, EventCondition condition, long timeout)
执行 action 并等待条件得到满足。

5, void setCompressedLayoutHeirarchy(boolean compressed)
设置是否启用布局压缩
启用或禁用布局层次压缩。如果启用了压缩,来源于 Acessibility 框架布局层次将只包含对 uiautomator 测试很重要的节点。任何使得浏览和搜索层次结构效率低下的不必要的周围布置节点都会被删除。

6, void dumpWindowHierarchy (File dest)
保存当前层次结构到文件,旧版本 dumpWindowHierarchy(String fileName) 方法,已不再推荐使用。

UiDevice 基本特性和方法:

1,Point getDisplaySizeDp()
设备独立像素

2,String getProductName()
获取设备名称 findObjects
findObjects

3,String getLastTraversedText()
获取最后一次遍历得到的文本

4,void clearLastTraversedText()
清除最后一次遍历得到的文本

5,模拟按键操作
boolean pressMenu()
boolean pressBack()
boolean pressHome()
boolean pressSearch()
boolean pressDPadCenter()
boolean pressDPadDown()
boolean pressDPadUp()
boolean pressDPadLeft()
boolean pressDPadRight()
boolean pressDelete()
boolean pressEnter()
全部调用的 pressKeyCode(int keyCode) 方法

6, boolean pressKeyCode(int keyCode)
通过 keycode 执行不一样的按键操作

7,boolean pressKeyCode(int keyCode, int metaState)
通过 keycode 执行不一样的按键操作,并设置一个标记

8,public boolean pressRecentApps()
打开正在运行的 app

9, boolean openNotification()
打开通知

10,boolean openQuickSettings()
打开快速设置

11,int getDisplayWidth()
获取显示的宽度,以像素为单位

12,int getDisplayHeight()
获取显示的高度,以像素为单位

13, boolean click(int x, int y)
通过坐标点击

14, boolean swipe(int startX, int startY, int endX, int endY, int steps)
二点之间滑动

15,boolean drag(int startX, int startY, int endX, int endY, int steps)
二点之间拖动

16,boolean swipe(Point[] segments, int segmentSteps)
多点之间进行滑动

17,void waitForIdle()
等待当前应用空闲,默认超时为 10*1000
private long mWaitForIdleTimeout = 10 * 1000;

18,void waitForIdle(long timeout)
等待当前应用空闲

19,String getCurrentPackageName()
检索可访问事件的最后一个包的名称。

20,void registerWatcher(String name, UiWatcher watcher)
注册监听器

21,void removeWatcher(String name)
删除监听器

22, void runWatchers()
启动所有监听

23,void resetWatcherTriggers()
重置所有监听,List mWatchersTriggers = new ArrayList,监听列表被清空:mWatchersTriggers.clear();

24,boolean hasWatcherTriggered(String watcherName)
查询监听列表中是否存在 watcherName 的监听

25,boolean hasAnyWatcherTriggered()
查询监听列表中是否有监听存在

26,boolean isNaturalOrientation()
监查设备是否自然竖屏方向

27,int getDisplayRotation()
返回当前的旋转

28,void freezeRotation()
禁用传感器,保留现在旋转状态

29,void unfreezeRotation()
启用传感器

30, void setOrientationLeft()
模拟左转,并冻结传感器

31,void setOrientationRight()
模拟右转,并冻结传感器

32,void setOrientationNatural()
设置旋转为正常竖屏,并冻结传感器

33,void wakeUp()
模拟按下电源按钮,唤醒屏幕

34,boolean isScreenOn()
检查屏幕是否被唤醒

35,void sleep()
模拟按下电源按钮,锁屏

36,void dumpWindowHierarchy(String fileName)
保存当前层次结构到文件

37,boolean waitForWindowUpdate(final String packageName, long timeout)
等待窗体包内容更新

38,boolean takeScreenshot(File storePath)
截图当前窗口并将其保存为 PNG,默认尺寸为 1.0f,压缩范围 90

39,boolean takeScreenshot(File storePath, float scale, int quality)
截图当前窗口并将其保存为 PNG,可以指图片尺寸,压缩范围

//屏幕截图 返回true 为截屏成功
 Boolean tmpa = device.takeScreenshot(new File("/data/local/tmp/test2.png"));
 System.out.println("截屏返回值:" + tmpa);
 //保存当前层次结构到文件 旧的dumpWindowHierarchy(String file )已过时
 device.dumpWindowHierarchy(new File("/data/local/tmp/test1.xml"));
 //打开正在运行的app
 device.pressRecentApps();
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 11 条回复 时间 点赞

getLastTraversedText() 能够来个 demo 解释下这个的用法吗?

2楼 已删除

#1 楼 @zsx10110 好像得在一个视图文本上进行遍历会产生TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY类型的事件,当产生这个类型的事件就会生成 LastTraversedText 文本
这个目前我没触发出来,明天我去咨询下 andorid 的开发 AccessibilityEvent 中的 131072 (0x00020000) 这个事件他们在什么情况下会用到,我去填坑~~
android 的 API 是这么说的。。

View text traversed at movement granularity - represents the event of traversing the text of a view at a given granularity. For example, moving to the next word.
Type: TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY

#1 楼 @zsx10110 Accessibility Service 为一类型的服务才会产出 131072 (0x00020000) 这个事件。

https://github.com/kesenhoo/android-training-course-in-chinese/blob/master/ui/accessibility/accessible-service.md

Accessibility Service 是 Android 系统框架提供给安装在设备上应用的一个可选的导航反馈特性。Accessibility Service 可以替代应用与用户交流反馈,比如将文本转化为语音提示,或是用户的手指悬停在屏幕上一个较重要的区域时的触摸反馈等。

DoctorQ 的这个:
http://blog.csdn.net/itfootball/article/details/21953763

#5 楼 @xushizhao 问题就是在于 我要怎么才能够产生 TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY 这个事件,官网说

You can write a test to perform directional arrow presses to focus on different elements inside a WebView

就可以了,貌似不太行。我去研究研究。

#6 楼 @zsx10110 这个需要应用开启并绑定一个 Accessibility Service 服务

Android 4.0 版本中增加了一个新特性,就是能够用 AccessibilityService 来遍历 View 层级,并从产生 Accessibility 事件的组件与它的父子组件中提取必要的信息。为了实现这个目的,你需要在 XML 文件中进行如下的配置:
android:canRetrieveWindowContent="true"
一旦完成,使用 getSource() 获取一个 AccessibilityNodeInfo 对象,如果触发事件的窗口是活动窗口,该调用只返回一个对象,如果不是,它将返回 null,做出相应的反响。下面的示例是一个代码片段,当它接收到一个事件时,执行以下步骤
1.立即获取到产生这个事件的 Parent
2,在这个 Parent 中寻找文本标签或勾选框
3.如果找到,创建一个文本内容来反馈给用户,提示内容和是否已勾选。
4.如果当遍历 View 的时候某处返回了 null 值,那么就直接结束这个方法。

#7 楼 @xushizhao 没太明白,开启 Accessibility Service 这个我懂,可是跟我一开始的问题实际在 uiautomator 中如何使用还是没有解决。另外我应该不用去创建一个 Accessibility service 之类的吧,因为默认 Uiautomator 已经有了,下面就是获取 LastTraversedText() 的源代码。

public QueryController(UiAutomatorBridge bridge) {
         mUiAutomatorBridge = bridge;
        bridge.addAccessibilityEventListener(new AccessibilityEventListener() {
            @Override
             public void onAccessibilityEvent(AccessibilityEvent event) {
                synchronized (mLock) {
                    mLastPackageName = event.getPackageName().toString();
                   // don't trust event.getText(), check for nulls
                     if (event.getText() != null && event.getText().size() > 0) {
                         if(event.getText().get(0) != null)
                             mLastActivityName = event.getText().get(0).toString();
                    }

                    switch(event.getEventType()) {
                     case AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
                         // don't trust event.getText(), check for nulls
                         if (event.getText() != null && event.getText().size() > 0)
                            if(event.getText().get(0) != null)
                                 mLastTraversedText = event.getText().get(0).toString();
                            if(DEBUG)
                            Log.i(LOG_TAG, "Last text selection reported: " + mLastTraversedText);
                               break;
                     }
                     mLock.notifyAll();
                 }
             }
         });
     }

#8 楼 @zsx10110 问题就是在于我也没有一个开启这种辅助功能的应用啊。。。从代码上分析,理论上只要有一个绑定 Accessibility Service 服务的应用,并提供了 view 遍历去查询 parent 中的文本的功能,模拟执行这个功能,就会生成这个参数。
你可以找你们开发了解下,看看你们应用有没有做这方面的~

#9 楼 @xushizhao 好像有点明白了 绑定一个 Accessibility Service 服务的应用 这个不难 我去试试看。

#10 楼 @zsx10110 我在我们这里找了,没有做这个东东。。。到时候也发我下~

多谢分享!

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册