一、UiDevice类介绍
按键与keycode使用
获取坐标与坐标点击
拖拽与滑动
旋转屏幕
灭屏与唤起屏幕
截图与等待空闲
获取包名 开启通知栏 快速设置 获取布局文件
UIDevice代表设备状态
为单例模式
监听功能
Uidevice.getInstance().pressHome(); 按home键 推荐使用这个,下面的在调用的时候会报空指针异常
或者 getUiDevice().pressHome();
- 按键与keycode使用
手机常见的按键
Home
Menu
Back
Volume_up 音量加
Volume_down
RecentApps 最近使用的App
Power 电源键
Dpad 上下左右键
API
pressBack() 短按返回back键
presssDpadCenter() 按轨迹球中点按键
pressDpadDown() 按轨迹球向下按键
pressDpadLeft() 按轨迹球向左按键
pressDpadRight() 按轨迹球向下按键
pressDpadUp() 按轨迹球向上按键
pressDelete() 按删除delete按键
pressEnter() 短按回车键
pressHome() 短按Home键
pressKeyCode(int keyCode, int metaState) 短按键盘代码keycode
pressKeyCode(int keyCode) 短按键盘代码keycode
pressMenu() 短按menu键
pressRecentApps() 短按最近使用的程序
pressSearch() 短按搜索键
以上方法返回值都为boolean
UiDevice.getInstance().pressMenu();
Keycode 键盘影射码
KeyEvent 按键事件
META Key 辅助功能键
小写字母
UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_A);
UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_B);
大写字母 1为shift 为大写
UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_A,1);
- 获取坐标与坐标点击
手机屏幕,坐标 :从左上角开始到右下角
(0,0)
(479,799)
坐标相关API
boolean click(int x, int y) 使用坐标点击屏幕
int getDisplayHeight() 获取屏幕高度
Point getDisplaySizeDp() 获取显示尺寸返回显示大小
屏幕旋转返回的显示大小调整
int getDisplayWith() 获取屏幕宽度
bounds [294,279][516,555] 左上角 右下角坐标
点击屏幕中心
int h = UiDevice.getInstance().getDisplayHeight();
int w = UiDevice.getInstance().getDisplayWidth();
UiDevice.getInstance().click(w/2,h/2);
矩形中点
int centerx = r.centerX();
int centery = r.centerY();
- 拖拽与滑动
拖拽:将一个组件从一个坐标移动到另一个坐标
滑动:从一个坐标移动到另一个坐标点
步长:从一点滑动到另一点使用的时间
API
Boolean drag(int startX, int startY, int endX, int endY, int step)
拖动对象从一个坐标拖动到另一个坐标
swipe(Point [] segments, int SegmentSteps) 在点阵列中滑动,5ms一步
swipe(int startX, int startY, int endX, int endY, int step) 通过坐标滑动屏幕
将图标向左上方拖拽
public void testDragAndSwipe( ){
//[252, 1704][444, 1896] 相对于屏幕左上角(0,0)的坐标
int startX, startY, endX, endY, steps;
startX=(444-252) /2+252; //X向右拖动
startY=(1896-1704) /2+1704; //Y取值
endX=startX;
endY=startY-500; //向上移动500
steps=100; //5ms一步
UiDevice. getInstance() .drag(startX, startY, endX, endY, steps) ;
}
- 屏幕的旋转
旋转方向:4个方向,分别为0度,90 向左,180 水平, 270 向右
重力感应器
固定位置与物理位置旋转
API
返回值 方法名 描述
void setOrientationLeft() 通过禁用传感器。然后模拟设备向左转,并且固定位置
void setOrientationNatural() 通过禁用传感器。然后模拟设备转到其自然默认的方向,并且固定位置
void setOrientationRight() 通过禁用传感器。然后模拟设备右转,并且固定位置
void unfreezeRotation() 重新启动传感器和允许物理旋转
boolean isNaturalOrientation() 检测设置是否处于默认旋转状态
int getDisplayRotation() 返回当前的显示旋转 0度 90 180 270 值分别为 0 1 2 3
void freezeRotation() 禁用传感器和冻结装置物理旋转在其当前旋转状态
- 灭屏与唤醒屏幕
灭屏:按电源键将屏幕熄灭
唤醒屏幕:在灭屏的状态下按电源键点亮屏幕
返回值 API 说明
void wakeUp() 模拟短按电源键,将屏幕唤醒,如果屏幕是唤醒的状态没有任何作用
void sleep() 模拟短按电源键,如果屏幕是灭屏状态则没有任何作用
boolean isScreenOn() 检查屏幕是否亮屏
- 截图与等待空闲
图片缩放比例 100 100缩小为 50 50
图片质量 图片大小 质量高则图片比较大 低则小
File类 文件 文件夹
图片格式 PNG
空闲状态 窗口没有更新 没有动作 界面处于不动的状态
窗口更新事件 指的是打开应用的过程。打开完成,不动了则为窗口空闲状态
截图相关API 重载函数
boolean takeScreenshot(File storePath) 把当前窗口截图并将其存储为png 默认为1.0f的规模(原尺寸)和90%质量 参数为file类的文件路径
boolean takeScreenshot(File storePath ,float scale, int quality) 把当前窗口截图为png 可以定义缩放比例与图片质量
file类可以指定路径 存储路径 必须为png格式 缩放比例 1.0为原图 图片压缩质量 范围为0-100
等待空闲API
void waitForIdle(long timeout) 自定义超时等待当前应用处于空闲状态
void waitForIdle() 等待当前应用处于空闲状态 默认等待10s
boolean waitForWindowUpdate(String package,long timeout) 等待窗口内容更新事件的发生
- 获取包名、开启通知栏、快速设置、获取布局文件的方法
API
void getCurrentPackageName() 获取当前界面的包名
void dumpWindowHierarchy(String filename) 获取当前界面的布局文件,保存在/data/local/tmp下
Boolean openNotification() 打开通知栏
Boolean openQuickSettings() 打开快速设置
- UiSelector类介绍
- Android布局与组件及组件的属性
线性布局:LinerLayout
表格布局 TableLayout
相对布局 RelativeLayout
帧布局 FrameLayout
网格布局 GridLayout
绝对布局 AbsoluteLayout
- Android常用组件
文本框 TextView
编辑框 EditText
按钮 Button
单选按钮 RadioButton
复选框 CheckBox
状态开关按钮 ToggleButton
开关 Switch
拖动条 SeekBar
时钟 AnalogClock DigtalClock
计时器 Chronometer
列表视图 ListView
网格视图 GridView
进度条 ProgressBar
星级评分条 RatingBar
提示信息 Toast
滚动视图 ScrollView
四种匹配关系的介绍
节点关系
对象搜索-文本与描述
对象搜索-类名与包名
对象搜索-索引与实例
对象搜索-特殊属性与节点
对象搜索-资源ID
通过各种属性与节点关系定位组件
自动化操作步骤:找到对象-操作对象
Android属性介绍
属性值 值类型
index 同一级的组件编号 int 0
instance 实例,只针对class作用,指界面上第几个同类的class int 5
class 当前应用的包名 String android.widget.TextView
package 当前应用的包名 String com.like
content-desc 描述 String string
checkable 是否可以选中 单选 复选 boolean false
checked 单选 复选是否已选中 boolean false
clickable 是否可以点击 boolean true
enabled 是否可操作,false为灰选 boolean false
focusable 是否可以具有焦点 boolean false
focused 当前焦点是否在他身上 boolean false
Scrollable 是否可以滚动 boolean false
long-clickable 是否可以长按 boolean false
password 是否可以输入密码 boolean false
selected 是否具有被选择属性 boolean false
bounds 为矩形区域 Rect [366,999] [708,1967] 左上右下
- 四种匹配关系介绍
0123456789
全玩匹配 默认 0123456789
包含匹配 Contains 3456
正则匹配 Matches \d{10} 包含其他3种匹配
起始匹配 StartWith 01234
- 节点关系
XML文档节点关系
父 Parent 上一级
子 Children 下一级
同胞 Sibling 同级
先辈 Ancestor
后代 Descendant
- 对象搜索-文本与描述
文本属性定位对象
返回值 API 说明
UiSelector text(String text) 文本
UiSelector textContains(String text) 文本包含
UiSelector textMatches(String regex) 文本正则
UiSelector textStartsWith(String text) 文本起始匹配
文本属性定位对象
返回值 API 说明
UiSelector description(String desc) 描述
UiSelector descriptionContains(String desc) 描述包含
UiSelector descriptionMatches(String desc) 描述正则
UiSelector descriptionStartsWith(String desc) 描述起始匹配
- 对象搜索-类名与包名
返回值 API 说明
UiSelector className(String name) 类名
UiSelector classNameMatches(String regex) 正则类名
快速书写方式
- class.getName方式
- 完整类名方式 android.widget.LinerLayout
- 正则方式
- 常量方式
包名属性定位对象
返回值 API 说明
UiSelector packageName(String name) 包名
UiSelector packageName Matches(String regex) 包名正则
- 对象搜索-索引与实例
通过各种编号查找到对象
索引与实例说明
索引 index
实例 instance 只作用于类
- 对象搜索-特殊属性与节点
返回值 API 说明
UiSelector checked(boolean val) 选择属性,一般是开关
UiSelector clickable(boolean val) 可选点击性
UiSelector enabled ( boolean val) 是否可用
UiSelector focusable(boolean val) 焦点属性
UiSelector focused ( boolean val ) 当前焦点属性
UiSelector longClickable( boolean val) 长按属性
UiSelector scrollable (boolean val) 滚动属性
UiSelector selected ( boolean val) 背景选择属性
节点属性定位对象
返回值 API 说明
UiSelector childSelector(UiSelector selector) 当前类中往下递归找符合条件的子类组件
UiSelector fromParent (UiSelector selector) 当前父类中往下递归找符合条件的组件
- 搜索对象-资源ID
资源ID说明 每个组件都有个编号
资源ID对应的是Layout xml下面的Android:属性
返回值 API 说明
UiSelector resourceId(String id) 资源ID 完整的ID名称
UiSelector resourceIdMatches(String regex) 资源ID正则
- UiObject类介绍
- 点击与长按对象 click longclick
拖拽与滑动对象 drag swipe
输入文本与清除文本
获取对象的属性与属性的判断 获取属性 getXXX 属性判断 isXXX
手势的操作
判断对象是否存在 exist
获取子类 getChild getChildCount
UiObject功能
代表一个组件对象 对象有许多模拟实际操作手机的方法和属性
- 点击与长按
Rect 对象代表一个矩形区域 [left,top] [right,bottom]
返回值 API 说明
boolean click() 点击对象点击的是终点
boolean clickAndWaitForNewWindows(long timeout) 点击对象 等待新窗口出现 参数为等待超时时长 毫秒
boolean clickAndWaitForNewWindows() 点击对象 等待新窗口出现
boolean clickBottomRight() 点击对象的右下角
boolean clickTopLeft () 点击对象的左上角
boolean longClick() 长按对象 对对象执行长按操作
boolean longClickBottomRight() 长按对象右下角
boolean longClickTopLeft() 长按对象左上角
- 拖拽与滑动对象
可以将组件拖动到另一个组件上 或者一个点上Point
滑动一小段距离
返回值 API 说明
boolean dragTo(UiObject destObj,int steps) 拖拽对象到另一个对象的位置上 步长可以设置拖动的速度
boolean dragTo(int destX, int destY, int steps) 拖拽对象到屏幕某个坐标置上 步长可以设置拖动的速度
boolean swipeDown(int steps) 拖拽对象向下滑动
boolean swipeUp(int steps) 拖拽对象向上滑动
boolean swipeLeft(int steps) 拖拽对象向左滑动
boolean swipeRight(int steps) 拖拽对象向右滑动
- 输入文本与清除文本
返回值 API 说明
boolean setText(String text) 在对象中输入文本
void clearTextField( ) 清除编辑框中的文本
输入文本与清除文本实现步骤说明
输入文本:清除文本-输入文本
清除文本:长按-清除
- 获取对象的属性与属性的判断
返回值 API 说明
Rect getBounds( ) 获取对象矩形坐标,矩形左上角坐标与右下角坐标
int getChildCount( ) 获取下一级子类数量
string getClassName( ) 获取对象类名属性的类名文本
string getContentDescription ( ) 获取对象描述属性的描述文本
string getPackageName ( ) 获取对象包名属性的包名文本
string getText ( ) 获取对象的文本属性中的文本
Rect getVisibleBounds ( ) 返回可见视图的范围,如果视图的部分是可见的,只有可见部分报告的范围。在屏幕上能看到的区域,一个窗口,一半在屏幕内,一半在屏幕外。可见区域为在屏幕内可见的那一半
获取父类与子类节点
UiObject getChild (UiSelector selector ) 获取对象包子类对象,可以递归获取子孙当中某个对象
UiObject getFromParent ( UiSelector selector) 从父类获取子类,按照UiSelector获取兄弟类-递归
返回值 API 说明
boolean isCheckable() 检查对象的checkable属性是否为true 是否具有开关属性
boolean isChecked() 检查对象的checked属性是否为true
boolean isClickable()
boolean isEnabled ( boolean val)
boolean isFocusable(boolean val) 焦点属性
boolean isFocused ( boolean val ) 当前焦点属性
boolean isLongClickable( boolean val) 长按属性
boolean isScrollable (boolean val) 滚动属性
boolean isSelected ( boolean val) 背景选择属性
package com.youku.autoburypoint.studyui; import android.os.RemoteException; import android.support.test.uiautomator.UiAutomatorTestCase; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.UiObjectNotFoundException; import android.support.test.uiautomator.UiScrollable; import android.support.test.uiautomator.UiSelector; import android.view.KeyEvent; import junit.framework.TestResult; import java.io.File; import java.security.PublicKey; public class Demo extends UiAutomatorTestCase { public void testDevice(){ Demo2 d2 =new Demo2(); d2.press(); } /** * 截图与等待空闲 */ public void testScreen(){ UiDevice.getInstance().takeScreenshot(new File("/Users/lishan/Downloads")); } public void testIdle(){ UiDevice.getInstance().click(11,22); //20秒 20000毫秒 UiDevice.getInstance().waitForIdle(20000); } /** * 获取包名、开启通知栏、快速设置、获取布局文件的方法 */ public void testGetPackage(){ String packageName=UiDevice.getInstance().getCurrentPackageName(); System.out.println(packageName); UiDevice.getInstance().openNotification(); sleep(3000); UiDevice.getInstance().openQuickSettings(); UiDevice.getInstance().dumpWindowHierarchy("n.xml"); } /** * 灭屏 亮屏 解锁 单机浏览器 单机网址输入框 输入www.baidu.com 按回车键 旋转屏幕 截图 */ public void tesBrower() throws RemoteException { UiDevice.getInstance().sleep(); if(!UiDevice.getInstance().isScreenOn()){ UiDevice.getInstance().wakeUp(); } } /** * * UiSeletor text */ public void testMatches() throws UiObjectNotFoundException { //联系人 //完全匹配:联系人 //包含匹配:系人 //正则匹配:.*系 //起始匹配:联系 //找到对象 // UiSelector l=new UiSelector().text("联系人"); // UiSelector l =new UiSelector().textContains("联系人"); // UiSelector l =new UiSelector().textMatches(".*系.*"); UiSelector l =new UiSelector().textStartsWith("联系人"); //操作对象 UiObject object=new UiObject(l); object.click(); } /** * * UiSeletor description */ public void testDesc() throws UiObjectNotFoundException { //联系人 //完全匹配:应用 //包含匹配:用 //正则匹配:.*系 //起始匹配:联系 //找到对象 // UiSelector selector=new UiSelector().description("应用"); // UiSelector selector=new UiSelector().descriptionContains("用"); // UiSelector selector =new UiSelector().descriptionMatches("应.*"); UiSelector selector =new UiSelector().descriptionStartsWith("应"); //操作对象 UiObject object=new UiObject(selector); object.click(); } public void testClassAndPackage() throws UiObjectNotFoundException { //instance是实例 是界面上的第几个元素 只针对类class // UiSelector selector =new UiSelector().className("android.view.View").instance(5); //正则的时候是针对全部的view // UiSelector selector =new UiSelector().classNameMatches(".android*").instance(7); //记住包名 class.getName() 需要记住组件的名字 // UiSelector selector =new UiSelector().className(View.class.getName()); //包名 UiSelector selector=new UiSelector().packageName("com.android.deskclock"); //操作对象 UiObject object=new UiObject(selector); object.click(); } public void testIndex() throws UiObjectNotFoundException { UiSelector selector =new UiSelector().className("android.widget.ImageButton").index(0); UiObject object =new UiObject(selector); object.click(); sleep(3000); UiDevice.getInstance().pressBack(); UiSelector selectormore =new UiSelector().className("android.widget.ImageButton").instance(1); UiObject objectmore =new UiObject(selectormore); objectmore.click(); } /** * 特殊属性与节点 */ public void testProperty() throws UiObjectNotFoundException { //打开关闭开关 // UiObject switchObj =new UiObject(new UiSelector().checkable(true)); // switchObj.click(); UiObject switchObj =new UiObject(new UiSelector().checked(true)); switchObj.click(); //enable UiObject send =new UiObject(new UiSelector().enabled(false)); send.getText(); System.out.println("classname为"+send.getClassName()); //focused UiObject focusedObj=new UiObject(new UiSelector().focused(true)); //输入字符 focusedObj.setText("abcd"); //long-clickable 多个属性定位元素 UiObject longclick=new UiObject(new UiSelector().longClickable(true).index(4)); longclick.click(); //scrollable UiObject scrollable =new UiObject(new UiSelector().scrollable(true)); scrollable.click(); //UiScrollable是UiObject的子类 像后滚动2次 UiScrollable scrollable1 =new UiScrollable(new UiSelector().scrollable(true)); scrollable1.scrollBackward(); sleep(2000); scrollable1.scrollBackward(); sleep(2000); } /** * 节点 */ public void testNode() throws UiObjectNotFoundException { //查找子类 A a childselector UiScrollable scrollable1 =new UiScrollable(new UiSelector().scrollable(true). childSelector(new UiSelector().text("Android"))); scrollable1.click(); //查找兄弟类 a A formParent 根据resourceId定位元素,找到与其同级的元素 UiScrollable scrollable2 =new UiScrollable(new UiSelector().resourceId("XXX.XXX"). fromParent(new UiSelector().className("com.huawei.hidisk:id/layout_file_detail").index(1))); scrollable2.click(); } /** * 资源ID */ public void testID() throws UiObjectNotFoundException { UiObject file = new UiObject(new UiSelector().resourceId("com.huawei.hidisk:id/layout_file_detail")); file.click(); //列表元素的定位 ID都是一样的,根据索引index查找 UiObject list =new UiObject(new UiSelector().resourceId("com.huawei.hidisk:id/layout_file_detail").index(1)); list.click(); //正则匹配 UiObject list1 =new UiObject(new UiSelector().resourceIdMatches("*id/layout_file_detail").index(1)); list1.click(); } /** * UiObject 点击与长按 */ public void testClick() throws UiObjectNotFoundException { //点击终点 UiObject clock =new UiObject(new UiSelector().resourceId("com.huawei.hidisk:id/layout_file_detail")); clock.click(); //5000毫秒 打开新窗口 超时5秒 如果在5秒内打开则正常 clock.clickAndWaitForNewWindow(5000); clock.clickTopLeft(); sleep(3000); UiDevice.getInstance().pressBack(); clock.clickBottomRight(); sleep(3000); UiDevice.getInstance().pressBack(); //长按 clock.longClick(); //结合swipe自定义长按的时间 UiDevice.getInstance().swipe(111,222,133,233,500); } /** * 拖拽与滑动 */ public void testDrag() throws UiObjectNotFoundException { UiObject object= new UiObject(new UiSelector().text("联系人")); //拖动某个位置 object.dragTo(350,1740-500,10); //拖拽到某个组件 UiObject object2= new UiObject(new UiSelector().text("图库")); object.dragTo(object2,50); } /** * 输入文本与清除文本 * */ public void testSetText() throws UiObjectNotFoundException { UiObject edit = new UiObject(new UiSelector().resourceId("com.huawei.hidisk:id/layout_test_editor")); edit.setText("jjjjjjj"); // 创建接受者UI元素对象 UiObject w =new UiObject(new UiSelector().text("接受者")); // 将光标移动到行尾,使用backspace进行删除 UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_MOVE_END); // 删除一个字符 // UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_DEL); // 当接受者不存在的时候,一直单个字符删除,直到出现为止 while (!w.exists()){ UiDevice.getInstance().pressKeyCode(KeyEvent.KEYCODE_DEL); } sleep(1000); edit.clearTextField(); } /** * * 获取对象属性与属性的判断 */ public void testGet() throws UiObjectNotFoundException { UiObject r =new UiObject(new UiSelector().resourceId("com.huawei.hidisk:id/layout_test_editor")); // 取得输入框的文本 String rec = r.getText(); System.out.println("HINT" +rec); System.out.println("CLASS" + r.getClassName()); System.out.println("package" + r.getPackageName()); System.out.println("description" + r.getContentDescription()); System.out.println("bound" + r.getBounds().left); // 期望值 真实的值 assertEquals("接受者", rec); } // 查找子类 public void testNode1() throws UiObjectNotFoundException { UiObject down = new UiObject(new UiSelector().resourceId("com.huawei.hidisk:id/layout_test_editor").index(3)); // 子类 UiObject download = down.getChild(new UiSelector().resourceId("com.huawei.hidisk:id/layout_test_editor/zilei")); download.click(); } public void testIs() throws UiObjectNotFoundException{ UiObject wlan = new UiObject(new UiSelector().resourceId("com.huawei.hidisk:id/layout_test_editor").index(3)); // 检查之前是否开着的 if (!wlan.isChecked()){ wlan.click(); } } public static void main(String[] args){ String jarName,testClass,testName,androidId; jarName="Demo"; testClass="com.youku.autoburypoint.studyui.Demo"; testName ="testDevice"; androidId="1"; new UiAutomatorHelper(jarName, testClass, testName, androidId); } }