optimize: auto file size generated by touch record
docs: selector
This commit is contained in:
@@ -129,7 +129,7 @@
|
||||
<activity
|
||||
android:name=".external.open.EditIntentActivity"
|
||||
android:icon="@drawable/ic_edit_green_48dp"
|
||||
android:label="编辑脚本">
|
||||
android:label="@string/text_edit_script">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
@@ -168,7 +168,7 @@
|
||||
<activity
|
||||
android:name=".external.open.RunIntentActivity"
|
||||
android:icon="@drawable/ic_ali_run"
|
||||
android:label="运行脚本"
|
||||
android:label="@string/text_run_script"
|
||||
android:taskAffinity="com.stardust.scriptdroid.external.open.RunIntentActivity"
|
||||
android:theme="@android:style/Theme.NoDisplay">
|
||||
|
||||
@@ -186,6 +186,7 @@
|
||||
<data android:mimeType="application/plain"/>
|
||||
<data android:mimeType="application/x-javascript"/>
|
||||
<data android:mimeType="text/*"/>
|
||||
<data android:mimeType="*/*" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
@@ -209,8 +210,9 @@
|
||||
|
||||
<activity
|
||||
android:name=".external.open.ImportIntentActivity"
|
||||
android:theme="@style/AppTheme.Transparent"
|
||||
android:icon="@drawable/ic_import"
|
||||
android:label="导入脚本文件">
|
||||
android:label="@string/text_import_script">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
@@ -226,6 +228,8 @@
|
||||
<data android:mimeType="application/plain"/>
|
||||
<data android:mimeType="application/x-javascript"/>
|
||||
<data android:mimeType="text/*"/>
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:mimeType="application/*" android:host="*" android:pathPattern=".*.auto" android:scheme="content" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
**自动操作的函数都需要开启"自动操作服务"才能执行,否则执行到相应函数时脚本会停止运行。**
|
||||
**自动操作的函数都需要开启"无障碍服务"才能执行,否则执行到相应函数时脚本会停止运行。**
|
||||
### auto模式
|
||||
如果代码的第一行是
|
||||
```
|
||||
"auto";
|
||||
```
|
||||
那么脚本运行前会先确保自动操作服务已开启。
|
||||
那么脚本运行前会先确保无障碍操作服务已开启。如果服务没有开启,则尝试用root权限开启服务并继续运行脚本,或没有root权限时停止运行脚本并跳转到服务开启界面。
|
||||
|
||||
注意,由于这个语句在必须在第一行(包括注释),因此使用起来比较不方便,已经被auto()函数代替。
|
||||
|
||||
您可以在设置中开启"使用Root权限自动开启自动无障碍服务",从而在运行到相应语句时可以自动开启。
|
||||
|
||||
### auto(\[mode = "normal"\])
|
||||
* mode \<String\> 获取屏幕上控件时所使用的模式,包括:
|
||||
* normal 正常模式
|
||||
* fast 快速模式
|
||||
|
||||
确保无障碍服务开启,这个函数的行为与在代码第一行加上`"auto";`是一样的。同时可以指定参数mode。
|
||||
|
||||
fast模式对自动操作的脚本执行速度有一定提高,但可能造成脚本运行不稳定。
|
||||
|
||||
您也可以在设置中开启"使用Root权限自动开启自动操作服务",从而在运行到相应语句时可以自动开启。
|
||||
### click(text[, i])
|
||||
* text \<String\> 要点击的区域的文本
|
||||
* i \<Number\> 如果相同的文本在屏幕中出现多次,则i表示要点击第几个文本
|
||||
@@ -62,22 +74,22 @@ while(!click("扫一扫"));
|
||||
|
||||
|
||||
### back()
|
||||
模拟按下返回键
|
||||
模拟按下返回键。返回是否执行成功。
|
||||
|
||||
### home()
|
||||
模拟按下Home键
|
||||
模拟按下Home键。返回是否执行成功。
|
||||
|
||||
### powerDialog()
|
||||
弹出电源键菜单
|
||||
弹出电源键菜单。返回是否执行成功。
|
||||
|
||||
### notifications()
|
||||
弹出通知栏
|
||||
弹出通知栏。返回是否执行成功。
|
||||
|
||||
### quickSettings()
|
||||
显示快速设置(下拉通知栏到底)
|
||||
显示快速设置(下拉通知栏到底)。返回是否执行成功。
|
||||
|
||||
### recents()
|
||||
显示最近任务
|
||||
显示最近任务。返回是否执行成功。
|
||||
|
||||
### splitScreen()
|
||||
分屏
|
||||
分屏。返回是否执行成功。
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
|
||||
## 简介
|
||||
|
||||
选择器是书写稍微复杂的自动操作脚本所必须。使用选择器的一般步骤是:
|
||||
1. 用各种筛选条件找出想要的控件,如某个文本控件、列表控件、图片控件
|
||||
2. 对找出的控件执行想要的操作,如点击、滑动、设置文字、长按
|
||||
|
||||
问题的关键在于如何找出想要的控件。对于文本控件一般通过他的文字来定位他,图片控件则通过id或者图片描述(desc)。选择器所做的就是提供这些筛选条件并给出筛选结果。
|
||||
|
||||
选择器提供了更强大的定位界面控件与对其进行操作的功能,可以用他们完成更多的自动操作和提取界面信息。
|
||||
选择器通过附加筛选条件,筛选出符合条件的控件或控件集合,之后可以对这些控件这些操作。
|
||||
可供选择的筛选条件包括:
|
||||
@@ -42,10 +48,13 @@ emoj.click();
|
||||
id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
.className("ImageView").click();
|
||||
```
|
||||
|
||||
这段代码意思是,找出id为"name", 包名为"com.tentcent.mobileqq",类名为ImageView的所有可点击控件,对他们执行点击动作。
|
||||
|
||||
最后的click()函数相当于untilFind().click()。也就是如果只需要在找到控件以后立即进行操作,只需要调用相应的操作函数,而不需要先调用find等函数等到控件再操作。
|
||||
要获取屏幕上的控件的信息(例如id, text, desc, bounds等),可以开启悬浮窗,使用界面层次查看和界面范围查看。
|
||||
|
||||
因为选择器部分内容如果有安卓开发经验会更容易掌握,因而更适合UI测试。
|
||||
选择器部分内容如果有安卓开发经验会更容易掌握。
|
||||
|
||||
# 选择器
|
||||
|
||||
@@ -56,13 +65,15 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
|
||||
附加id严格匹配筛选条件。
|
||||
|
||||
控件的id属性通常是可以用来确定控件的唯一标识,如果一个控件有id,那么使用id来找到他是最好的方法。要查看屏幕上的控件的id,可以开启悬浮窗并使用界面工具,点击相应控件即可查看。若查看到的控件id为null, 表示该控件没有id。另外,在列表中会出现多个控件的id相同的情况。例如微信的联系人列表,每个头像的id都是一样的。此时不能用id来唯一确定控件。
|
||||
|
||||
在QQ界面经常会出现多个id为"name"的控件,在微信上则每个版本的id都会变化。对于这些软件而言比较难用id定位控件。
|
||||
|
||||
### idContains(str)
|
||||
* str \<Regex\> id要包含的字符串
|
||||
* str \<String\> id要包含的字符串
|
||||
|
||||
附加控件id包含字符串str的筛选条件。
|
||||
|
||||
> 控件的id属性通常是可以用来确定控件的唯一标识,如果一个控件有id,那么使用id来找到他是最好的方法。要查看屏幕上的控件的id,可以开启悬浮窗并使用界面工具,点击相应控件即可查看。若查看到的控件id为null, 表示该控件没有id。另外,在列表中会出现多个控件的id相同的情况。例如微信的联系人列表,每个头像的id都是一样的。此时不能用id来唯一确定控件。
|
||||
|
||||
### idStartsWith(prefix)
|
||||
* prefix \<String\> id前缀
|
||||
|
||||
@@ -73,17 +84,22 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
|
||||
附加id需要以suffix结束的筛选条件。
|
||||
|
||||
### idMatches(regex)
|
||||
* regex \<Regex\> id要满足的正则表达式
|
||||
### idMatches(String)
|
||||
* String \<String\> id要满足的正则表达式
|
||||
|
||||
附加id需要满足正则表达式。有关正则表达式,可以查看[菜鸟教程](http://www.runoob.com/regexp/regexp-example.html)。
|
||||
附加id需要满足正则表达式。有关正则表达式,可以查看[菜鸟教程](http://www.runoob.com/Stringp/Stringp-example.html)。
|
||||
|
||||
这里的正则表达式是Java的正则表达式,不能直接使用JavaScript的正则表达式。
|
||||
```
|
||||
idMatches("[a-zA-Z]+")
|
||||
```
|
||||
|
||||
### text(str)
|
||||
* str \<String\> 控件文本
|
||||
|
||||
附加控件文本等于字符串str的筛选条件。
|
||||
|
||||
> 控件的text(文本)属性是控件上的显示的文字,例如微信左上角的"微信"文本。对于图片或者其他控件通常text属性为null。
|
||||
控件的text(文本)属性是控件上的显示的文字,例如微信左上角的"微信"文本。对于图片或者其他控件通常text属性为null。
|
||||
|
||||
### textContains(str)
|
||||
|
||||
@@ -103,7 +119,7 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
附加控件文本需要以suffix结束的筛选条件。
|
||||
|
||||
### textMatches(str)
|
||||
* regex \<Regex\> 要满足的正则表达式
|
||||
* String \<String\> 要满足的正则表达式
|
||||
|
||||
附加控件文本需要满足正则表达式的条件。
|
||||
|
||||
@@ -112,7 +128,9 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
|
||||
附加控件描述等于字符串str的筛选条件。
|
||||
|
||||
> 控件的desc(描述,全称为Content-Description)属性是对一个控件的描述,例如网易云音乐右上角的放大镜图标的描述为搜索。要查看一个控件的描述,同样地可以借助悬浮窗查看。
|
||||
控件的desc(描述,全称为Content-Description)属性是对一个控件的描述,例如网易云音乐右上角的放大镜图标的描述为搜索。要查看一个控件的描述,同样地可以借助悬浮窗查看。
|
||||
|
||||
desc属性同样是定位控件的利器。
|
||||
|
||||
### descContains(str)
|
||||
|
||||
@@ -132,7 +150,7 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
附加控件描述需要以suffix结束的筛选条件。
|
||||
|
||||
### descMatches(str)
|
||||
* regex \<Regex\> 要满足的正则表达式
|
||||
* String \<String\> 要满足的正则表达式
|
||||
|
||||
附加控件描述需要满足正则表达式的条件。
|
||||
|
||||
@@ -141,7 +159,7 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
|
||||
附加控件类名等于字符串str的筛选条件。
|
||||
|
||||
> 控件的className属性是一个控件的具体类型,例如图片控件通常为ImageView,文本控件通常为TextView, 输入框通常为EditText。(若一个控件是在android.widget包里的,那么android.widget可以省略。但除此之外的其他控件必须是类的全名,例如"com.stardust.theme.ThemeColorImageView")。
|
||||
控件的className属性是一个控件的具体类型,例如图片控件通常为ImageView,文本控件通常为TextView, 输入框通常为EditText。(若一个控件是在android.widget包里的,那么android.widget可以省略。但除此之外的其他控件必须是类的全名,例如"com.stardust.theme.ThemeColorImageView")。
|
||||
|
||||
### classNameContains(str)
|
||||
|
||||
@@ -161,7 +179,7 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
附加控件类名需要以suffix结束的筛选条件。
|
||||
|
||||
### classNameMatches(str)
|
||||
* regex \<Regex\> 要满足的正则表达式
|
||||
* String \<String\> 要满足的正则表达式
|
||||
|
||||
附加控件类名需要满足正则表达式的条件。
|
||||
|
||||
@@ -170,7 +188,7 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
|
||||
附加包名等于字符串str的筛选条件。
|
||||
|
||||
> packageName属性也即控件所属的应用的包名(参见《shell命令:应用包名》),通常用来保证当前运行的应用是想要的应用。
|
||||
packageName属性也即控件所属的应用的包名(参见《shell命令:应用包名》),通常用来保证当前运行的应用是想要的应用。
|
||||
|
||||
### packageNameContains(str)
|
||||
|
||||
@@ -190,7 +208,7 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
附加包名需要以suffix结束的筛选条件。
|
||||
|
||||
### packageNameMatches(str)
|
||||
* regex \<Regex\> 要满足的正则表达式
|
||||
* String \<String\> 要满足的正则表达式
|
||||
|
||||
附加包名需要满足正则表达式的条件。
|
||||
|
||||
@@ -205,52 +223,52 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
### drawingOrder(order)
|
||||
* order \<Number\> 控件在父视图中的绘制顺序,在一些
|
||||
|
||||
### checkable(b = true)
|
||||
### checkable(\[b = true\])
|
||||
* b \<Boolean\> 表示控件是否可勾选, 默认为true
|
||||
|
||||
附加控件是否可勾选的条件。可勾选指的是,例如QQ和微信发送图片时图片的勾选。
|
||||
|
||||
### selected(b = true)
|
||||
### selected(\[b = true\])
|
||||
* b \<Boolean\> 表示控件是否被选中,默认为true
|
||||
|
||||
附加控件是否被选中的条件。被选中指的是,例如QQ聊天界面点击下方的表情按钮时,会出现自己收藏的表情,这时表情按钮便处于选中状态。
|
||||
|
||||
### clickable(b = true)
|
||||
### clickable(\[b = true\])
|
||||
* b \<Boolean\> 表示控件是否可点击, 默认为true
|
||||
|
||||
附加控件是否可点击的条件。但并非所有clickable为false的控件都真的不能点击,这取决于控件的实现。因而要确定一个控件的clickable属性,可以开启悬浮窗工具。
|
||||
|
||||
### longClickable(b = true)
|
||||
### longClickable(\[b = true\])
|
||||
* b \<Boolean\> 表示控件是否可长按, 默认为true
|
||||
|
||||
附加控件是否可长按的条件。
|
||||
|
||||
### enabled(b = true)
|
||||
### enabled(\[b = true\])
|
||||
* b \<Boolean\> 表示控件是否已启用, 默认为true
|
||||
|
||||
附加控件是否已启用的条件。大多数控件都是启用的状态,处于“禁用”状态通常是灰色并且不可点击。
|
||||
|
||||
### scrollable(b = true)
|
||||
### scrollable(\[b = true\])
|
||||
* b \<Boolean\> 表示控件是否可滑动, 默认为true
|
||||
|
||||
附加控件是否可滑动的条件。
|
||||
|
||||
### editable(b = true)
|
||||
### editable(\[b = true\])
|
||||
* b \<Boolean\> 表示控件是否可编辑, 默认为true
|
||||
|
||||
附加控件是否可编辑的条件。一般来说可编辑的控件为输入框(EditText)。
|
||||
|
||||
### contentInvalid(b = true)
|
||||
### contentInvalid(\[b = true\])
|
||||
* b \<Boolean\> 表示控件是否是contentInvalid, 默认为true
|
||||
|
||||
我也不知道是什么,下次再补充吧。
|
||||
|
||||
### contextClickable(b = true)
|
||||
### contextClickable(\[b = true\])
|
||||
* b \<Boolean\> 表示控件是否是contextClickable, 默认为true
|
||||
|
||||
我也不知道是什么,下次再补充吧。
|
||||
|
||||
### multiLine(b = true)
|
||||
### multiLine(\[b = true\])
|
||||
* b \<Boolean\> 表示文本或输入框控件是否是多行显示的, 默认为true
|
||||
|
||||
附加控件是否文本或输入框控件是否是多行显示的条件。
|
||||
@@ -263,59 +281,85 @@ id("name").packageName("com.tencent.mobileqq").clickable()
|
||||
### find()
|
||||
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,找到所有满足条件的控件集合并返回。这个搜索只进行一次,并不保证一直会找到,因而会出现返回的控件集合为空的情况。参见[控件集合](#控件集合)。
|
||||
|
||||
可以通过empty()或nonEmpty()函数判断找到的是否为空。例如:
|
||||
```
|
||||
var c = className("AbsListView").find();
|
||||
if(c.empty()){
|
||||
toast("找到啦");
|
||||
}else{
|
||||
toast("没找到╭(╯^╰)╮");
|
||||
}
|
||||
```
|
||||
|
||||
### untilFind()
|
||||
根据当前的选择器所确定的筛选条件,对屏幕上的控件进行搜索,直到找到至少一个满足条件的控件为止,并返回所有满足条件的控件集合。参见[控件集合](#控件集合)。
|
||||
|
||||
### exists()
|
||||
判断屏幕上是否存在控件符合选择器所确定的条件。例如要判断某个文本出现就执行某个动作,可以用:
|
||||
```
|
||||
if(text("嘿嘿嘿").exists()){
|
||||
//嘿嘿嘿
|
||||
}
|
||||
```
|
||||
|
||||
### waitFor()
|
||||
等待屏幕上出现符合条件的控件。
|
||||
```
|
||||
text("嘿嘿嘿").waitFor();
|
||||
```
|
||||
|
||||
|
||||
## 操作
|
||||
|
||||
### click()
|
||||
找到所有符合条件的控件并点击。相当于untilFind().click()。参见[click](#UiCollection.click)。
|
||||
找到所有符合条件的控件并点击。相当于untilFind().click()。参见[click](#UiCollection.click())。
|
||||
|
||||
### longClick()
|
||||
找到所有符合条件的控件并长按。相当于untilFind().longClick()。参见[longClick](#UiCollection.longClick)。
|
||||
找到所有符合条件的控件并长按。相当于untilFind().longClick()。参见[longClick](#UiCollection.longClick())。
|
||||
|
||||
### copy()
|
||||
找到所有符合条件的控件并复制其内容,只对文本框或输入框控件有文字选中时有效。相当于untilFind().copy()。参见[copy](#UiCollection.copy)。
|
||||
找到所有符合条件的控件并复制其内容,只对文本框或输入框控件有文字选中时有效。相当于untilFind().copy()。参见[copy](#UiCollection.copy())。
|
||||
|
||||
### paste()
|
||||
找到所有符合条件的控件并粘贴,只对输入框控件有效。相当于untilFind().paste()。参见[paste](#UiCollection.paste)。
|
||||
找到所有符合条件的控件并粘贴,只对输入框控件有效。相当于untilFind().paste()。参见[paste](#UiCollection.paste())。
|
||||
|
||||
### select()
|
||||
找到所有符合条件的控件并选中。相当于untilFind().select()。参见[select](#UiCollection.select)。
|
||||
找到所有符合条件的控件并选中。相当于untilFind().select()。参见[select](#UiCollection.select())。
|
||||
|
||||
### cut()
|
||||
找到所有符合条件的控件并剪切其内容,只对文本框或输入框控件有文字选中时有效。相当于untilFind().cut()。参见[cut](#UiCollection.cut)。
|
||||
找到所有符合条件的控件并剪切其内容,只对文本框或输入框控件有文字选中时有效。相当于untilFind().cut()。参见[cut](#UiCollection.cut())。
|
||||
|
||||
### collapse()
|
||||
找到所有符合条件的控件并折叠。相当于untilFind().collapse()。参见[collapse](#UiCollection.collapse)。
|
||||
找到所有符合条件的控件并折叠。相当于untilFind().collapse()。参见[collapse](#UiCollection.collapse())。
|
||||
|
||||
### expand()
|
||||
找到所有符合条件的控件并展开。相当于untilFind().expand()。参见[expand](#UiCollection.expand)。
|
||||
找到所有符合条件的控件并展开。相当于untilFind().expand()。参见[expand](#UiCollection.expand())。
|
||||
|
||||
### show()
|
||||
找到所有符合条件的控件并使其出现在屏幕上。相当于untilFind().show()。参见[show](#UiCollection.show)。
|
||||
找到所有符合条件的控件并使其出现在屏幕上。相当于untilFind().show()。参见[show](#UiCollection.show())。
|
||||
|
||||
### scrollForward()
|
||||
找到所有符合条件的控件并向前滑。相当于untilFind().scrollForward()。参见[scrollForward](#UiCollection.scrollForward)。
|
||||
找到所有符合条件的控件并向前滑。相当于untilFind().scrollForward()。参见[scrollForward](#UiCollection.scrollForward())。
|
||||
向前滑指的是,对于左右滑动的控件向右滑,上下滑动的控件向下滑。
|
||||
|
||||
### scrollBackward()
|
||||
找到所有符合条件的控件并向后滑。相当于untilFind().scrollBackward()。参见[scrollBackward](#UiCollection.scrollBackward)。
|
||||
找到所有符合条件的控件并向后滑。相当于untilFind().scrollBackward()。参见[scrollBackward](#UiCollection.scrollBackward())。
|
||||
向后滑指的是,对于左右滑动的控件向左滑,上下滑动的控件向上滑。
|
||||
|
||||
### scrollUp()
|
||||
找到所有符合条件的控件并向上滑。相当于untilFind().scrollUp()。参见[scrollUp](#UiCollection.scrollUp)。
|
||||
找到所有符合条件的控件并向上滑。相当于untilFind().scrollUp()。参见[scrollUp](#UiCollection.scrollUp())。
|
||||
|
||||
### scrollDown()
|
||||
找到所有符合条件的控件并向下滑。相当于untilFind().scrollDown()。参见[scrollDown](#UiCollection.scrollDown)。
|
||||
找到所有符合条件的控件并向下滑。相当于untilFind().scrollDown()。参见[scrollDown](#UiCollection.scrollDown())。
|
||||
|
||||
### scrollLeft()
|
||||
找到所有符合条件的控件并向左滑。相当于untilFind().scrollLeft()。参见[scrollLeft](#UiCollection.scrollLeft)。
|
||||
找到所有符合条件的控件并向左滑。相当于untilFind().scrollLeft()。参见[scrollLeft](#UiCollection.scrollLeft())。
|
||||
|
||||
### scrollRight()
|
||||
找到所有符合条件的控件并向右滑。相当于untilFind().scrollRight()。参见[scrollRight](#UiCollection.scrollRight)。
|
||||
找到所有符合条件的控件并向右滑。相当于untilFind().scrollRight()。参见[scrollRight](#UiCollection.scrollRight())。
|
||||
|
||||
### contextClick()
|
||||
\\\\文档缺失
|
||||
|
||||
### setSelection(start, end)
|
||||
* start \<Number\> 文字选中开始位置
|
||||
@@ -349,10 +393,30 @@ c.each(function(o){
|
||||
});
|
||||
```
|
||||
|
||||
### empty()
|
||||
返回控件集合是否为空。
|
||||
|
||||
### nonEmpty()
|
||||
返回控件集合是否非空。
|
||||
|
||||
### filter(filter)
|
||||
* filter \<Function\> 过滤函数。参数为UiObject,返回值为Boolean。
|
||||
|
||||
过滤出控件集合中符合条件的子控件。例如要过滤出所有子控件数目为1的控件为:
|
||||
```
|
||||
var newCollection = collection.filter(function(obj){
|
||||
return obj.childCount() == 1;
|
||||
});
|
||||
```
|
||||
|
||||
### find(selector)
|
||||
* selector \<UiSelector\> 选择器
|
||||
|
||||
根据selector所确定的条件在该控件集合中找到所有符合条件的控件并返回控件集合。例如:
|
||||
根据selector所确定的条件在该控件集合的控件和**子控件**找到所有符合条件的控件并返回控件集合。
|
||||
|
||||
注意这会递归地遍历控件集合里所有的控件以及他们的子控件。和filter函数不同。
|
||||
|
||||
例如:
|
||||
```
|
||||
var names = id("name");
|
||||
var clickableNames = names.find(clickable());
|
||||
@@ -433,4 +497,77 @@ UiObject, 选择器的findOne方法返回的对象。和UiCollection有相似的
|
||||
返回父控件(UiObject)。
|
||||
|
||||
### children()
|
||||
返回该控件的所有子控件组成的控件集合。
|
||||
返回该控件的所有子控件组成的控件集合。
|
||||
|
||||
### childCount()
|
||||
返回子控件数目。
|
||||
|
||||
### bounds()
|
||||
返回控件在屏幕上的范围,其值是一个\[Rect\]对象。
|
||||
|
||||
### boundsInParent()
|
||||
返回控件在父控件中的范围,其值是一个\[Rect\]对象。
|
||||
|
||||
### drawingOrder()
|
||||
返回控件的绘制次序。
|
||||
|
||||
### id()
|
||||
返回控件的id,可能为null。
|
||||
|
||||
### text()
|
||||
返回控件的文本,如果控件没有文本,返回""。
|
||||
|
||||
### findByText(text)
|
||||
* text \<String\> 文本
|
||||
|
||||
根据文本text在子控件中递归地寻找并返回文本或描述(desc)**包含**这段文本text的控件,返回它们组成的集合。。
|
||||
|
||||
### find(selector)
|
||||
* selector \<UiSelector\> 选择器
|
||||
|
||||
根据选择器selector在子控件中递归地寻找符合条件的控件,返回它们组成的集合。
|
||||
|
||||
### findOne
|
||||
|
||||
### find(selector)
|
||||
* selector \<UiSelector\> 选择器
|
||||
|
||||
根据选择器selector在子控件中递归地寻找一个符合条件的控件。找不到则返回null。
|
||||
|
||||
# Rect
|
||||
|
||||
UiObject.bounds(), UiObject.boundsInParent()返回的对象。表示一个长方形。
|
||||
|
||||
### Rect.left
|
||||
长方形左边界的x坐标、
|
||||
|
||||
### Rect.right
|
||||
长方形左边界的x坐标、
|
||||
|
||||
### Rect.top
|
||||
长方形上边界的y坐标、
|
||||
|
||||
### Rect.bottom
|
||||
长方形下边界的y坐标、
|
||||
|
||||
### Rect.centerX()
|
||||
长方形中点x坐标。
|
||||
|
||||
### Rect.centerY()
|
||||
长方形中点y坐标。
|
||||
|
||||
### Rect.width()
|
||||
长方形宽度。通常可以作为控件宽度。
|
||||
|
||||
### Rect.height()
|
||||
长方形高度。通常可以作为控件高度。
|
||||
|
||||
### Rect.contains(r)
|
||||
* r \<Rect\>
|
||||
|
||||
返回是否包含另一个长方形r。
|
||||
|
||||
### Rect.intersect(r)
|
||||
* r \<Rect\>
|
||||
|
||||
返回是否和另一个长方形相交。
|
||||
|
||||
@@ -1,12 +1,41 @@
|
||||
以下函数均需要root权限,可以实现任意位置的点击、滑动、长按、模拟物理按键等。
|
||||
|
||||
这些函数通常首字母大写以表示其特殊的权限。
|
||||
函数是返回值均是一个布尔值。true表示成功,false表示失败。一般而言,只有没有root权限时才会运行失败。
|
||||
这些函数均不返回任何值。
|
||||
并且,这些函数的执行是异步的、非实时的,在不同机型上所用的时间不同。脚本不会等待动作执行完成才继续执行。因此最好在每个函数之后加上适当的sleep来达到期望的效果。
|
||||
|
||||
例如:
|
||||
```
|
||||
Tap(100, 100);
|
||||
sleep(500);
|
||||
```
|
||||
|
||||
注意,动作的执行可能无法被停止,例如:
|
||||
```
|
||||
for(var i = 0; i < 100; i++){
|
||||
Tap(100, 100);
|
||||
}
|
||||
```
|
||||
这段代码执行后可能会出现在任务管理中停止脚本后点击仍然继续的情况。
|
||||
因此,强烈建议在每个动作后加上延时:
|
||||
```
|
||||
for(var i = 0; i < 100; i++){
|
||||
Tap(100, 100);
|
||||
sleep(500);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Tap(x, y)
|
||||
* x, y \<Number\> 要点击的坐标。
|
||||
|
||||
点击位置(x, y), 您可以通过"开发者选项"开启指针位置来确定点击坐标。
|
||||
|
||||
### Swipe(x1, y1, x2, y2, \[delay\])
|
||||
### Swipe(x1, y1, x2, y2, \[duration\])
|
||||
* x1, y1 \<Number\> 滑动起点的坐标
|
||||
* x2, y2 \<Number\> 滑动终点的坐标
|
||||
* duration \<Number\> 滑动动作所用的时间
|
||||
|
||||
滑动。从(x1, y1)位置滑动到(x2, y2)位置。
|
||||
|
||||
### Home()
|
||||
|
||||
14
app/src/main/assets/sample/图片与图色处理/实时显示触摸点颜色.js
Normal file
14
app/src/main/assets/sample/图片与图色处理/实时显示触摸点颜色.js
Normal file
@@ -0,0 +1,14 @@
|
||||
requestScreenCapture();
|
||||
console.show();
|
||||
events.observeTouch();
|
||||
events.setTouchEventTimeout(30);
|
||||
events.on("touch", function(point){
|
||||
var img = captureScreen();
|
||||
if(img == null){
|
||||
var c = null;
|
||||
}else{
|
||||
var c = colors.toString(images.pixel(captureScreen(), point.x, point.y);
|
||||
}
|
||||
log("(" + point.x + ", " + point.y + "): " + c);
|
||||
log("");
|
||||
});
|
||||
@@ -5,13 +5,19 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.main.MainActivity;
|
||||
import com.stardust.scriptdroid.R;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.functions.Consumer;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/2.
|
||||
@@ -22,20 +28,14 @@ public class ImportIntentActivity extends BaseActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
try {
|
||||
handleIntent(getIntent());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, R.string.edit_and_run_handle_intent_error, Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
}
|
||||
onNewIntent(getIntent());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
try {
|
||||
handleIntent(intent);
|
||||
} catch (FileNotFoundException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, R.string.edit_and_run_handle_intent_error, Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
@@ -45,14 +45,28 @@ public class ImportIntentActivity extends BaseActivity {
|
||||
private void handleIntent(Intent intent) throws FileNotFoundException {
|
||||
Uri uri = intent.getData();
|
||||
if (uri != null && "content".equals(uri.getScheme())) {
|
||||
MainActivity.importScriptFileByInputStream(this, getContentResolver().openInputStream(uri));
|
||||
InputStream stream = getContentResolver().openInputStream(uri);
|
||||
new ScriptOperations(this, null)
|
||||
.importFile("", stream)
|
||||
.subscribe(new Consumer<String>() {
|
||||
@Override
|
||||
public void accept(@NonNull String s) throws Exception {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
final String path = intent.getData().getPath();
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
MainActivity.importScriptFile(this, path);
|
||||
new ScriptOperations(this, null)
|
||||
.importFile(path)
|
||||
.subscribe(new Consumer<String>() {
|
||||
@Override
|
||||
public void accept(@NonNull String s) throws Exception {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -110,6 +110,7 @@ public class HelpCatalogueActivity extends BaseActivity {
|
||||
mLoadingIndicatorView.hide();
|
||||
handleIntent();
|
||||
}
|
||||
setToolbarAsBack(mTitle);
|
||||
}
|
||||
|
||||
private void readCatalogues() {
|
||||
@@ -141,7 +142,6 @@ public class HelpCatalogueActivity extends BaseActivity {
|
||||
|
||||
private void setUpUI() {
|
||||
setContentView(R.layout.activity_help);
|
||||
setToolbarAsBack(mTitle);
|
||||
setUpRecyclerView();
|
||||
setUpLoadingView();
|
||||
}
|
||||
|
||||
@@ -94,13 +94,12 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
private OnActivityResultDelegate.Mediator mActivityResultMediator = new OnActivityResultDelegate.Mediator();
|
||||
private DrawableSaver mDrawerHeaderBackgroundSaver, mAppbarBackgroundSaver;
|
||||
private VersionGuard mVersionGuard;
|
||||
private Intent mIntentToHandle;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
checkPermissions();
|
||||
mIntentToHandle = getIntent();
|
||||
EventBus.getDefault().register(this);
|
||||
mVersionGuard = new VersionGuard(this);
|
||||
showAnnunciationIfNeeded();
|
||||
@@ -200,15 +199,6 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
.build();
|
||||
mViewPager.setAdapter(mPagerAdapter);
|
||||
tabLayout.setupWithViewPager(mViewPager);
|
||||
mPagerAdapter.setOnFragmentInstantiateListener(new FragmentPagerAdapterBuilder.OnFragmentInstantiateListener() {
|
||||
@Override
|
||||
public void OnInstantiate(Fragment fragment) {
|
||||
if (fragment instanceof MyScriptListFragment && mIntentToHandle != null) {
|
||||
handleIntent(mIntentToHandle);
|
||||
mIntentToHandle = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Click(R.id.add)
|
||||
@@ -239,7 +229,8 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
dialog.dismiss();
|
||||
provider.clearCacheExceptInitialDirectory();
|
||||
new ScriptOperations(MainActivity.this, mDrawerLayout)
|
||||
.importFile(file.getPath());
|
||||
.importFile(file.getPath())
|
||||
.subscribe();
|
||||
}
|
||||
})
|
||||
.title(R.string.text_please_choose_file_to_import)
|
||||
@@ -289,59 +280,6 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
mVersionGuard.checkDeprecateAndUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
handleIntent(intent);
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent) {
|
||||
String action = intent.getStringExtra(EXTRA_ACTION);
|
||||
if (action == null)
|
||||
return;
|
||||
switch (action) {
|
||||
|
||||
case ACTION_IMPORT_SCRIPT:
|
||||
handleImportScriptFile(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleImportScriptFile(Intent intent) {
|
||||
String path = intent.getStringExtra(ARGUMENT_PATH);
|
||||
if (path != null) {
|
||||
new ScriptOperations(MainActivity.this, mDrawerLayout)
|
||||
.importFile(intent.getStringExtra(ARGUMENT_PATH))
|
||||
.subscribe();
|
||||
return;
|
||||
}
|
||||
InputStream inputStream = IntentExtras.fromIntent(intent).getAndClear(ARGUMENT_INPUT_STREAM);
|
||||
new ScriptOperations(MainActivity.this, mDrawerLayout)
|
||||
.importFile("", inputStream)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void importScriptFile(Context context, String path) {
|
||||
context.startActivity(new Intent(context, MainActivity_.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
.putExtra(EXTRA_ACTION, ACTION_IMPORT_SCRIPT)
|
||||
.putExtra(ARGUMENT_PATH, path));
|
||||
}
|
||||
|
||||
public static void importScriptFileByInputStream(Context context, InputStream inputStream) {
|
||||
Intent intent = new Intent(context, MainActivity_.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
.putExtra(EXTRA_ACTION, ACTION_IMPORT_SCRIPT);
|
||||
IntentExtras.newExtras()
|
||||
.put(ARGUMENT_INPUT_STREAM, inputStream)
|
||||
.putInIntent(intent);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
|
||||
@Click(R.id.toolbar)
|
||||
public void OnToolbarClick() {
|
||||
mAppbarBackgroundSaver.select(this, mActivityResultMediator);
|
||||
|
||||
@@ -213,6 +213,9 @@
|
||||
<string name="text_on_progress">处理中</string>
|
||||
<string name="text_delete_failed">删除失败</string>
|
||||
<string name="text_enable_accessibility_service_by_root_ing">正在使用root权限启用无障碍服务</string>
|
||||
<string name="text_edit_script">编辑脚本</string>
|
||||
<string name="text_run_script">运行脚本</string>
|
||||
<string name="text_import_script">导入脚本文件</string>
|
||||
|
||||
|
||||
<string-array name="record_control_keys">
|
||||
|
||||
@@ -20,6 +20,16 @@
|
||||
<item name="windowActionBar">false</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.Transparent" parent="AppTheme">
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:backgroundDimEnabled">false</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="MainToolbarTheme" parent="AppTheme">
|
||||
<item name="android:textColorSecondary">#c4c4c4</item>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user